blob: 7349908d837846b777596d2328da981b590c2a53 [file] [log] [blame]
Leo Repp58b9f112021-11-22 11:57:47 +01001(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global = global || self, global.csstree = factory());
5}(this, function () { 'use strict';
6
7 //
8 // list
9 // ┌──────┐
10 // ┌──────────────┼─head │
11 // │ │ tail─┼──────────────┐
12 // │ └──────┘ │
13 // ▼ ▼
14 // item item item item
15 // ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
16 // null ◀──┼─prev │◀───┼─prev │◀───┼─prev │◀───┼─prev │
17 // │ next─┼───▶│ next─┼───▶│ next─┼───▶│ next─┼──▶ null
18 // ├──────┤ ├──────┤ ├──────┤ ├──────┤
19 // │ data │ │ data │ │ data │ │ data │
20 // └──────┘ └──────┘ └──────┘ └──────┘
21 //
22
23 function createItem(data) {
24 return {
25 prev: null,
26 next: null,
27 data: data
28 };
29 }
30
31 function allocateCursor(node, prev, next) {
32 var cursor;
33
34 if (cursors !== null) {
35 cursor = cursors;
36 cursors = cursors.cursor;
37 cursor.prev = prev;
38 cursor.next = next;
39 cursor.cursor = node.cursor;
40 } else {
41 cursor = {
42 prev: prev,
43 next: next,
44 cursor: node.cursor
45 };
46 }
47
48 node.cursor = cursor;
49
50 return cursor;
51 }
52
53 function releaseCursor(node) {
54 var cursor = node.cursor;
55
56 node.cursor = cursor.cursor;
57 cursor.prev = null;
58 cursor.next = null;
59 cursor.cursor = cursors;
60 cursors = cursor;
61 }
62
63 var cursors = null;
64 var List = function() {
65 this.cursor = null;
66 this.head = null;
67 this.tail = null;
68 };
69
70 List.createItem = createItem;
71 List.prototype.createItem = createItem;
72
73 List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
74 var cursor = this.cursor;
75
76 while (cursor !== null) {
77 if (cursor.prev === prevOld) {
78 cursor.prev = prevNew;
79 }
80
81 if (cursor.next === nextOld) {
82 cursor.next = nextNew;
83 }
84
85 cursor = cursor.cursor;
86 }
87 };
88
89 List.prototype.getSize = function() {
90 var size = 0;
91 var cursor = this.head;
92
93 while (cursor) {
94 size++;
95 cursor = cursor.next;
96 }
97
98 return size;
99 };
100
101 List.prototype.fromArray = function(array) {
102 var cursor = null;
103
104 this.head = null;
105
106 for (var i = 0; i < array.length; i++) {
107 var item = createItem(array[i]);
108
109 if (cursor !== null) {
110 cursor.next = item;
111 } else {
112 this.head = item;
113 }
114
115 item.prev = cursor;
116 cursor = item;
117 }
118
119 this.tail = cursor;
120
121 return this;
122 };
123
124 List.prototype.toArray = function() {
125 var cursor = this.head;
126 var result = [];
127
128 while (cursor) {
129 result.push(cursor.data);
130 cursor = cursor.next;
131 }
132
133 return result;
134 };
135
136 List.prototype.toJSON = List.prototype.toArray;
137
138 List.prototype.isEmpty = function() {
139 return this.head === null;
140 };
141
142 List.prototype.first = function() {
143 return this.head && this.head.data;
144 };
145
146 List.prototype.last = function() {
147 return this.tail && this.tail.data;
148 };
149
150 List.prototype.each = function(fn, context) {
151 var item;
152
153 if (context === undefined) {
154 context = this;
155 }
156
157 // push cursor
158 var cursor = allocateCursor(this, null, this.head);
159
160 while (cursor.next !== null) {
161 item = cursor.next;
162 cursor.next = item.next;
163
164 fn.call(context, item.data, item, this);
165 }
166
167 // pop cursor
168 releaseCursor(this);
169 };
170
171 List.prototype.forEach = List.prototype.each;
172
173 List.prototype.eachRight = function(fn, context) {
174 var item;
175
176 if (context === undefined) {
177 context = this;
178 }
179
180 // push cursor
181 var cursor = allocateCursor(this, this.tail, null);
182
183 while (cursor.prev !== null) {
184 item = cursor.prev;
185 cursor.prev = item.prev;
186
187 fn.call(context, item.data, item, this);
188 }
189
190 // pop cursor
191 releaseCursor(this);
192 };
193
194 List.prototype.forEachRight = List.prototype.eachRight;
195
196 List.prototype.nextUntil = function(start, fn, context) {
197 if (start === null) {
198 return;
199 }
200
201 var item;
202
203 if (context === undefined) {
204 context = this;
205 }
206
207 // push cursor
208 var cursor = allocateCursor(this, null, start);
209
210 while (cursor.next !== null) {
211 item = cursor.next;
212 cursor.next = item.next;
213
214 if (fn.call(context, item.data, item, this)) {
215 break;
216 }
217 }
218
219 // pop cursor
220 releaseCursor(this);
221 };
222
223 List.prototype.prevUntil = function(start, fn, context) {
224 if (start === null) {
225 return;
226 }
227
228 var item;
229
230 if (context === undefined) {
231 context = this;
232 }
233
234 // push cursor
235 var cursor = allocateCursor(this, start, null);
236
237 while (cursor.prev !== null) {
238 item = cursor.prev;
239 cursor.prev = item.prev;
240
241 if (fn.call(context, item.data, item, this)) {
242 break;
243 }
244 }
245
246 // pop cursor
247 releaseCursor(this);
248 };
249
250 List.prototype.some = function(fn, context) {
251 var cursor = this.head;
252
253 if (context === undefined) {
254 context = this;
255 }
256
257 while (cursor !== null) {
258 if (fn.call(context, cursor.data, cursor, this)) {
259 return true;
260 }
261
262 cursor = cursor.next;
263 }
264
265 return false;
266 };
267
268 List.prototype.map = function(fn, context) {
269 var result = new List();
270 var cursor = this.head;
271
272 if (context === undefined) {
273 context = this;
274 }
275
276 while (cursor !== null) {
277 result.appendData(fn.call(context, cursor.data, cursor, this));
278 cursor = cursor.next;
279 }
280
281 return result;
282 };
283
284 List.prototype.filter = function(fn, context) {
285 var result = new List();
286 var cursor = this.head;
287
288 if (context === undefined) {
289 context = this;
290 }
291
292 while (cursor !== null) {
293 if (fn.call(context, cursor.data, cursor, this)) {
294 result.appendData(cursor.data);
295 }
296 cursor = cursor.next;
297 }
298
299 return result;
300 };
301
302 List.prototype.clear = function() {
303 this.head = null;
304 this.tail = null;
305 };
306
307 List.prototype.copy = function() {
308 var result = new List();
309 var cursor = this.head;
310
311 while (cursor !== null) {
312 result.insert(createItem(cursor.data));
313 cursor = cursor.next;
314 }
315
316 return result;
317 };
318
319 List.prototype.prepend = function(item) {
320 // head
321 // ^
322 // item
323 this.updateCursors(null, item, this.head, item);
324
325 // insert to the beginning of the list
326 if (this.head !== null) {
327 // new item <- first item
328 this.head.prev = item;
329
330 // new item -> first item
331 item.next = this.head;
332 } else {
333 // if list has no head, then it also has no tail
334 // in this case tail points to the new item
335 this.tail = item;
336 }
337
338 // head always points to new item
339 this.head = item;
340
341 return this;
342 };
343
344 List.prototype.prependData = function(data) {
345 return this.prepend(createItem(data));
346 };
347
348 List.prototype.append = function(item) {
349 return this.insert(item);
350 };
351
352 List.prototype.appendData = function(data) {
353 return this.insert(createItem(data));
354 };
355
356 List.prototype.insert = function(item, before) {
357 if (before !== undefined && before !== null) {
358 // prev before
359 // ^
360 // item
361 this.updateCursors(before.prev, item, before, item);
362
363 if (before.prev === null) {
364 // insert to the beginning of list
365 if (this.head !== before) {
366 throw new Error('before doesn\'t belong to list');
367 }
368
369 // since head points to before therefore list doesn't empty
370 // no need to check tail
371 this.head = item;
372 before.prev = item;
373 item.next = before;
374
375 this.updateCursors(null, item);
376 } else {
377
378 // insert between two items
379 before.prev.next = item;
380 item.prev = before.prev;
381
382 before.prev = item;
383 item.next = before;
384 }
385 } else {
386 // tail
387 // ^
388 // item
389 this.updateCursors(this.tail, item, null, item);
390
391 // insert to the ending of the list
392 if (this.tail !== null) {
393 // last item -> new item
394 this.tail.next = item;
395
396 // last item <- new item
397 item.prev = this.tail;
398 } else {
399 // if list has no tail, then it also has no head
400 // in this case head points to new item
401 this.head = item;
402 }
403
404 // tail always points to new item
405 this.tail = item;
406 }
407
408 return this;
409 };
410
411 List.prototype.insertData = function(data, before) {
412 return this.insert(createItem(data), before);
413 };
414
415 List.prototype.remove = function(item) {
416 // item
417 // ^
418 // prev next
419 this.updateCursors(item, item.prev, item, item.next);
420
421 if (item.prev !== null) {
422 item.prev.next = item.next;
423 } else {
424 if (this.head !== item) {
425 throw new Error('item doesn\'t belong to list');
426 }
427
428 this.head = item.next;
429 }
430
431 if (item.next !== null) {
432 item.next.prev = item.prev;
433 } else {
434 if (this.tail !== item) {
435 throw new Error('item doesn\'t belong to list');
436 }
437
438 this.tail = item.prev;
439 }
440
441 item.prev = null;
442 item.next = null;
443
444 return item;
445 };
446
447 List.prototype.push = function(data) {
448 this.insert(createItem(data));
449 };
450
451 List.prototype.pop = function() {
452 if (this.tail !== null) {
453 return this.remove(this.tail);
454 }
455 };
456
457 List.prototype.unshift = function(data) {
458 this.prepend(createItem(data));
459 };
460
461 List.prototype.shift = function() {
462 if (this.head !== null) {
463 return this.remove(this.head);
464 }
465 };
466
467 List.prototype.prependList = function(list) {
468 return this.insertList(list, this.head);
469 };
470
471 List.prototype.appendList = function(list) {
472 return this.insertList(list);
473 };
474
475 List.prototype.insertList = function(list, before) {
476 // ignore empty lists
477 if (list.head === null) {
478 return this;
479 }
480
481 if (before !== undefined && before !== null) {
482 this.updateCursors(before.prev, list.tail, before, list.head);
483
484 // insert in the middle of dist list
485 if (before.prev !== null) {
486 // before.prev <-> list.head
487 before.prev.next = list.head;
488 list.head.prev = before.prev;
489 } else {
490 this.head = list.head;
491 }
492
493 before.prev = list.tail;
494 list.tail.next = before;
495 } else {
496 this.updateCursors(this.tail, list.tail, null, list.head);
497
498 // insert to end of the list
499 if (this.tail !== null) {
500 // if destination list has a tail, then it also has a head,
501 // but head doesn't change
502
503 // dest tail -> source head
504 this.tail.next = list.head;
505
506 // dest tail <- source head
507 list.head.prev = this.tail;
508 } else {
509 // if list has no a tail, then it also has no a head
510 // in this case points head to new item
511 this.head = list.head;
512 }
513
514 // tail always start point to new item
515 this.tail = list.tail;
516 }
517
518 list.head = null;
519 list.tail = null;
520
521 return this;
522 };
523
524 List.prototype.replace = function(oldItem, newItemOrList) {
525 if ('head' in newItemOrList) {
526 this.insertList(newItemOrList, oldItem);
527 } else {
528 this.insert(newItemOrList, oldItem);
529 }
530
531 this.remove(oldItem);
532 };
533
534 var List_1 = List;
535
536 var createCustomError = function createCustomError(name, message) {
537 // use Object.create(), because some VMs prevent setting line/column otherwise
538 // (iOS Safari 10 even throws an exception)
539 var error = Object.create(SyntaxError.prototype);
540 var errorStack = new Error();
541
542 error.name = name;
543 error.message = message;
544
545 Object.defineProperty(error, 'stack', {
546 get: function() {
547 return (errorStack.stack || '').replace(/^(.+\n){1,3}/, name + ': ' + message + '\n');
548 }
549 });
550
551 return error;
552 };
553
554 var MAX_LINE_LENGTH = 100;
555 var OFFSET_CORRECTION = 60;
556 var TAB_REPLACEMENT = ' ';
557
558 function sourceFragment(error, extraLines) {
559 function processLines(start, end) {
560 return lines.slice(start, end).map(function(line, idx) {
561 var num = String(start + idx + 1);
562
563 while (num.length < maxNumLength) {
564 num = ' ' + num;
565 }
566
567 return num + ' |' + line;
568 }).join('\n');
569 }
570
571 var lines = error.source.split(/\r\n?|\n|\f/);
572 var line = error.line;
573 var column = error.column;
574 var startLine = Math.max(1, line - extraLines) - 1;
575 var endLine = Math.min(line + extraLines, lines.length + 1);
576 var maxNumLength = Math.max(4, String(endLine).length) + 1;
577 var cutLeft = 0;
578
579 // column correction according to replaced tab before column
580 column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
581
582 if (column > MAX_LINE_LENGTH) {
583 cutLeft = column - OFFSET_CORRECTION + 3;
584 column = OFFSET_CORRECTION - 2;
585 }
586
587 for (var i = startLine; i <= endLine; i++) {
588 if (i >= 0 && i < lines.length) {
589 lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
590 lines[i] =
591 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
592 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
593 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
594 }
595 }
596
597 return [
598 processLines(startLine, line),
599 new Array(column + maxNumLength + 2).join('-') + '^',
600 processLines(line, endLine)
601 ].filter(Boolean).join('\n');
602 }
603
604 var SyntaxError$1 = function(message, source, offset, line, column) {
605 var error = createCustomError('SyntaxError', message);
606
607 error.source = source;
608 error.offset = offset;
609 error.line = line;
610 error.column = column;
611
612 error.sourceFragment = function(extraLines) {
613 return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
614 };
615 Object.defineProperty(error, 'formattedMessage', {
616 get: function() {
617 return (
618 'Parse error: ' + error.message + '\n' +
619 sourceFragment(error, 2)
620 );
621 }
622 });
623
624 // for backward capability
625 error.parseError = {
626 offset: offset,
627 line: line,
628 column: column
629 };
630
631 return error;
632 };
633
634 var _SyntaxError = SyntaxError$1;
635
636 // CSS Syntax Module Level 3
637 // https://www.w3.org/TR/css-syntax-3/
638 var TYPE = {
639 EOF: 0, // <EOF-token>
640 Ident: 1, // <ident-token>
641 Function: 2, // <function-token>
642 AtKeyword: 3, // <at-keyword-token>
643 Hash: 4, // <hash-token>
644 String: 5, // <string-token>
645 BadString: 6, // <bad-string-token>
646 Url: 7, // <url-token>
647 BadUrl: 8, // <bad-url-token>
648 Delim: 9, // <delim-token>
649 Number: 10, // <number-token>
650 Percentage: 11, // <percentage-token>
651 Dimension: 12, // <dimension-token>
652 WhiteSpace: 13, // <whitespace-token>
653 CDO: 14, // <CDO-token>
654 CDC: 15, // <CDC-token>
655 Colon: 16, // <colon-token> :
656 Semicolon: 17, // <semicolon-token> ;
657 Comma: 18, // <comma-token> ,
658 LeftSquareBracket: 19, // <[-token>
659 RightSquareBracket: 20, // <]-token>
660 LeftParenthesis: 21, // <(-token>
661 RightParenthesis: 22, // <)-token>
662 LeftCurlyBracket: 23, // <{-token>
663 RightCurlyBracket: 24, // <}-token>
664 Comment: 25
665 };
666
667 var NAME = Object.keys(TYPE).reduce(function(result, key) {
668 result[TYPE[key]] = key;
669 return result;
670 }, {});
671
672 var _const = {
673 TYPE: TYPE,
674 NAME: NAME
675 };
676
677 var EOF = 0;
678
679 // https://drafts.csswg.org/css-syntax-3/
680 // § 4.2. Definitions
681
682 // digit
683 // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9).
684 function isDigit(code) {
685 return code >= 0x0030 && code <= 0x0039;
686 }
687
688 // hex digit
689 // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F),
690 // or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f).
691 function isHexDigit(code) {
692 return (
693 isDigit(code) || // 0 .. 9
694 (code >= 0x0041 && code <= 0x0046) || // A .. F
695 (code >= 0x0061 && code <= 0x0066) // a .. f
696 );
697 }
698
699 // uppercase letter
700 // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z).
701 function isUppercaseLetter(code) {
702 return code >= 0x0041 && code <= 0x005A;
703 }
704
705 // lowercase letter
706 // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z).
707 function isLowercaseLetter(code) {
708 return code >= 0x0061 && code <= 0x007A;
709 }
710
711 // letter
712 // An uppercase letter or a lowercase letter.
713 function isLetter(code) {
714 return isUppercaseLetter(code) || isLowercaseLetter(code);
715 }
716
717 // non-ASCII code point
718 // A code point with a value equal to or greater than U+0080 <control>.
719 function isNonAscii(code) {
720 return code >= 0x0080;
721 }
722
723 // name-start code point
724 // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
725 function isNameStart(code) {
726 return isLetter(code) || isNonAscii(code) || code === 0x005F;
727 }
728
729 // name code point
730 // A name-start code point, a digit, or U+002D HYPHEN-MINUS (-).
731 function isName(code) {
732 return isNameStart(code) || isDigit(code) || code === 0x002D;
733 }
734
735 // non-printable code point
736 // A code point between U+0000 NULL and U+0008 BACKSPACE, or U+000B LINE TABULATION,
737 // or a code point between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE, or U+007F DELETE.
738 function isNonPrintable(code) {
739 return (
740 (code >= 0x0000 && code <= 0x0008) ||
741 (code === 0x000B) ||
742 (code >= 0x000E && code <= 0x001F) ||
743 (code === 0x007F)
744 );
745 }
746
747 // newline
748 // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition,
749 // as they are converted to U+000A LINE FEED during preprocessing.
750 // TODO: we doesn't do a preprocessing, so check a code point for U+000D CARRIAGE RETURN and U+000C FORM FEED
751 function isNewline(code) {
752 return code === 0x000A || code === 0x000D || code === 0x000C;
753 }
754
755 // whitespace
756 // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
757 function isWhiteSpace(code) {
758 return isNewline(code) || code === 0x0020 || code === 0x0009;
759 }
760
761 // § 4.3.8. Check if two code points are a valid escape
762 function isValidEscape(first, second) {
763 // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
764 if (first !== 0x005C) {
765 return false;
766 }
767
768 // Otherwise, if the second code point is a newline or EOF, return false.
769 if (isNewline(second) || second === EOF) {
770 return false;
771 }
772
773 // Otherwise, return true.
774 return true;
775 }
776
777 // § 4.3.9. Check if three code points would start an identifier
778 function isIdentifierStart(first, second, third) {
779 // Look at the first code point:
780
781 // U+002D HYPHEN-MINUS
782 if (first === 0x002D) {
783 // If the second code point is a name-start code point or a U+002D HYPHEN-MINUS,
784 // or the second and third code points are a valid escape, return true. Otherwise, return false.
785 return (
786 isNameStart(second) ||
787 second === 0x002D ||
788 isValidEscape(second, third)
789 );
790 }
791
792 // name-start code point
793 if (isNameStart(first)) {
794 // Return true.
795 return true;
796 }
797
798 // U+005C REVERSE SOLIDUS (\)
799 if (first === 0x005C) {
800 // If the first and second code points are a valid escape, return true. Otherwise, return false.
801 return isValidEscape(first, second);
802 }
803
804 // anything else
805 // Return false.
806 return false;
807 }
808
809 // § 4.3.10. Check if three code points would start a number
810 function isNumberStart(first, second, third) {
811 // Look at the first code point:
812
813 // U+002B PLUS SIGN (+)
814 // U+002D HYPHEN-MINUS (-)
815 if (first === 0x002B || first === 0x002D) {
816 // If the second code point is a digit, return true.
817 if (isDigit(second)) {
818 return 2;
819 }
820
821 // Otherwise, if the second code point is a U+002E FULL STOP (.)
822 // and the third code point is a digit, return true.
823 // Otherwise, return false.
824 return second === 0x002E && isDigit(third) ? 3 : 0;
825 }
826
827 // U+002E FULL STOP (.)
828 if (first === 0x002E) {
829 // If the second code point is a digit, return true. Otherwise, return false.
830 return isDigit(second) ? 2 : 0;
831 }
832
833 // digit
834 if (isDigit(first)) {
835 // Return true.
836 return 1;
837 }
838
839 // anything else
840 // Return false.
841 return 0;
842 }
843
844 //
845 // Misc
846 //
847
848 // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
849 function isBOM(code) {
850 // UTF-16BE
851 if (code === 0xFEFF) {
852 return 1;
853 }
854
855 // UTF-16LE
856 if (code === 0xFFFE) {
857 return 1;
858 }
859
860 return 0;
861 }
862
863 // Fast code category
864 //
865 // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
866 // > non-ASCII code point
867 // > A code point with a value equal to or greater than U+0080 <control>
868 // > name-start code point
869 // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
870 // > name code point
871 // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
872 // That means only ASCII code points has a special meaning and we define a maps for 0..127 codes only
873 var CATEGORY = new Array(0x80);
874 charCodeCategory.Eof = 0x80;
875 charCodeCategory.WhiteSpace = 0x82;
876 charCodeCategory.Digit = 0x83;
877 charCodeCategory.NameStart = 0x84;
878 charCodeCategory.NonPrintable = 0x85;
879
880 for (var i = 0; i < CATEGORY.length; i++) {
881 switch (true) {
882 case isWhiteSpace(i):
883 CATEGORY[i] = charCodeCategory.WhiteSpace;
884 break;
885
886 case isDigit(i):
887 CATEGORY[i] = charCodeCategory.Digit;
888 break;
889
890 case isNameStart(i):
891 CATEGORY[i] = charCodeCategory.NameStart;
892 break;
893
894 case isNonPrintable(i):
895 CATEGORY[i] = charCodeCategory.NonPrintable;
896 break;
897
898 default:
899 CATEGORY[i] = i || charCodeCategory.Eof;
900 }
901 }
902
903 function charCodeCategory(code) {
904 return code < 0x80 ? CATEGORY[code] : charCodeCategory.NameStart;
905 }
906 var charCodeDefinitions = {
907 isDigit: isDigit,
908 isHexDigit: isHexDigit,
909 isUppercaseLetter: isUppercaseLetter,
910 isLowercaseLetter: isLowercaseLetter,
911 isLetter: isLetter,
912 isNonAscii: isNonAscii,
913 isNameStart: isNameStart,
914 isName: isName,
915 isNonPrintable: isNonPrintable,
916 isNewline: isNewline,
917 isWhiteSpace: isWhiteSpace,
918 isValidEscape: isValidEscape,
919 isIdentifierStart: isIdentifierStart,
920 isNumberStart: isNumberStart,
921
922 isBOM: isBOM,
923 charCodeCategory: charCodeCategory
924 };
925
926 var isDigit$1 = charCodeDefinitions.isDigit;
927 var isHexDigit$1 = charCodeDefinitions.isHexDigit;
928 var isUppercaseLetter$1 = charCodeDefinitions.isUppercaseLetter;
929 var isName$1 = charCodeDefinitions.isName;
930 var isWhiteSpace$1 = charCodeDefinitions.isWhiteSpace;
931 var isValidEscape$1 = charCodeDefinitions.isValidEscape;
932
933 function getCharCode(source, offset) {
934 return offset < source.length ? source.charCodeAt(offset) : 0;
935 }
936
937 function getNewlineLength(source, offset, code) {
938 if (code === 13 /* \r */ && getCharCode(source, offset + 1) === 10 /* \n */) {
939 return 2;
940 }
941
942 return 1;
943 }
944
945 function cmpChar(testStr, offset, referenceCode) {
946 var code = testStr.charCodeAt(offset);
947
948 // code.toLowerCase() for A..Z
949 if (isUppercaseLetter$1(code)) {
950 code = code | 32;
951 }
952
953 return code === referenceCode;
954 }
955
956 function cmpStr(testStr, start, end, referenceStr) {
957 if (end - start !== referenceStr.length) {
958 return false;
959 }
960
961 if (start < 0 || end > testStr.length) {
962 return false;
963 }
964
965 for (var i = start; i < end; i++) {
966 var testCode = testStr.charCodeAt(i);
967 var referenceCode = referenceStr.charCodeAt(i - start);
968
969 // testCode.toLowerCase() for A..Z
970 if (isUppercaseLetter$1(testCode)) {
971 testCode = testCode | 32;
972 }
973
974 if (testCode !== referenceCode) {
975 return false;
976 }
977 }
978
979 return true;
980 }
981
982 function findWhiteSpaceStart(source, offset) {
983 for (; offset >= 0; offset--) {
984 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
985 break;
986 }
987 }
988
989 return offset + 1;
990 }
991
992 function findWhiteSpaceEnd(source, offset) {
993 for (; offset < source.length; offset++) {
994 if (!isWhiteSpace$1(source.charCodeAt(offset))) {
995 break;
996 }
997 }
998
999 return offset;
1000 }
1001
1002 function findDecimalNumberEnd(source, offset) {
1003 for (; offset < source.length; offset++) {
1004 if (!isDigit$1(source.charCodeAt(offset))) {
1005 break;
1006 }
1007 }
1008
1009 return offset;
1010 }
1011
1012 // § 4.3.7. Consume an escaped code point
1013 function consumeEscaped(source, offset) {
1014 // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and
1015 // that the next input code point has already been verified to be part of a valid escape.
1016 offset += 2;
1017
1018 // hex digit
1019 if (isHexDigit$1(getCharCode(source, offset - 1))) {
1020 // Consume as many hex digits as possible, but no more than 5.
1021 // Note that this means 1-6 hex digits have been consumed in total.
1022 for (var maxOffset = Math.min(source.length, offset + 5); offset < maxOffset; offset++) {
1023 if (!isHexDigit$1(getCharCode(source, offset))) {
1024 break;
1025 }
1026 }
1027
1028 // If the next input code point is whitespace, consume it as well.
1029 var code = getCharCode(source, offset);
1030 if (isWhiteSpace$1(code)) {
1031 offset += getNewlineLength(source, offset, code);
1032 }
1033 }
1034
1035 return offset;
1036 }
1037
1038 // §4.3.11. Consume a name
1039 // Note: This algorithm does not do the verification of the first few code points that are necessary
1040 // to ensure the returned code points would constitute an <ident-token>. If that is the intended use,
1041 // ensure that the stream starts with an identifier before calling this algorithm.
1042 function consumeName(source, offset) {
1043 // Let result initially be an empty string.
1044 // Repeatedly consume the next input code point from the stream:
1045 for (; offset < source.length; offset++) {
1046 var code = source.charCodeAt(offset);
1047
1048 // name code point
1049 if (isName$1(code)) {
1050 // Append the code point to result.
1051 continue;
1052 }
1053
1054 // the stream starts with a valid escape
1055 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
1056 // Consume an escaped code point. Append the returned code point to result.
1057 offset = consumeEscaped(source, offset) - 1;
1058 continue;
1059 }
1060
1061 // anything else
1062 // Reconsume the current input code point. Return result.
1063 break;
1064 }
1065
1066 return offset;
1067 }
1068
1069 // §4.3.12. Consume a number
1070 function consumeNumber(source, offset) {
1071 var code = source.charCodeAt(offset);
1072
1073 // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-),
1074 // consume it and append it to repr.
1075 if (code === 0x002B || code === 0x002D) {
1076 code = source.charCodeAt(offset += 1);
1077 }
1078
1079 // 3. While the next input code point is a digit, consume it and append it to repr.
1080 if (isDigit$1(code)) {
1081 offset = findDecimalNumberEnd(source, offset + 1);
1082 code = source.charCodeAt(offset);
1083 }
1084
1085 // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
1086 if (code === 0x002E && isDigit$1(source.charCodeAt(offset + 1))) {
1087 // 4.1 Consume them.
1088 // 4.2 Append them to repr.
1089 code = source.charCodeAt(offset += 2);
1090
1091 // 4.3 Set type to "number".
1092 // TODO
1093
1094 // 4.4 While the next input code point is a digit, consume it and append it to repr.
1095
1096 offset = findDecimalNumberEnd(source, offset);
1097 }
1098
1099 // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E)
1100 // or U+0065 LATIN SMALL LETTER E (e), ... , followed by a digit, then:
1101 if (cmpChar(source, offset, 101 /* e */)) {
1102 var sign = 0;
1103 code = source.charCodeAt(offset + 1);
1104
1105 // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+) ...
1106 if (code === 0x002D || code === 0x002B) {
1107 sign = 1;
1108 code = source.charCodeAt(offset + 2);
1109 }
1110
1111 // ... followed by a digit
1112 if (isDigit$1(code)) {
1113 // 5.1 Consume them.
1114 // 5.2 Append them to repr.
1115
1116 // 5.3 Set type to "number".
1117 // TODO
1118
1119 // 5.4 While the next input code point is a digit, consume it and append it to repr.
1120 offset = findDecimalNumberEnd(source, offset + 1 + sign + 1);
1121 }
1122 }
1123
1124 return offset;
1125 }
1126
1127 // § 4.3.14. Consume the remnants of a bad url
1128 // ... its sole use is to consume enough of the input stream to reach a recovery point
1129 // where normal tokenizing can resume.
1130 function consumeBadUrlRemnants(source, offset) {
1131 // Repeatedly consume the next input code point from the stream:
1132 for (; offset < source.length; offset++) {
1133 var code = source.charCodeAt(offset);
1134
1135 // U+0029 RIGHT PARENTHESIS ())
1136 // EOF
1137 if (code === 0x0029) {
1138 // Return.
1139 offset++;
1140 break;
1141 }
1142
1143 if (isValidEscape$1(code, getCharCode(source, offset + 1))) {
1144 // Consume an escaped code point.
1145 // Note: This allows an escaped right parenthesis ("\)") to be encountered
1146 // without ending the <bad-url-token>. This is otherwise identical to
1147 // the "anything else" clause.
1148 offset = consumeEscaped(source, offset);
1149 }
1150 }
1151
1152 return offset;
1153 }
1154
1155 var utils = {
1156 consumeEscaped: consumeEscaped,
1157 consumeName: consumeName,
1158 consumeNumber: consumeNumber,
1159 consumeBadUrlRemnants: consumeBadUrlRemnants,
1160
1161 cmpChar: cmpChar,
1162 cmpStr: cmpStr,
1163
1164 getNewlineLength: getNewlineLength,
1165 findWhiteSpaceStart: findWhiteSpaceStart,
1166 findWhiteSpaceEnd: findWhiteSpaceEnd
1167 };
1168
1169 var TYPE$1 = _const.TYPE;
1170 var NAME$1 = _const.NAME;
1171
1172
1173 var cmpStr$1 = utils.cmpStr;
1174
1175 var EOF$1 = TYPE$1.EOF;
1176 var WHITESPACE = TYPE$1.WhiteSpace;
1177 var COMMENT = TYPE$1.Comment;
1178
1179 var OFFSET_MASK = 0x00FFFFFF;
1180 var TYPE_SHIFT = 24;
1181
1182 var TokenStream = function() {
1183 this.offsetAndType = null;
1184 this.balance = null;
1185
1186 this.reset();
1187 };
1188
1189 TokenStream.prototype = {
1190 reset: function() {
1191 this.eof = false;
1192 this.tokenIndex = -1;
1193 this.tokenType = 0;
1194 this.tokenStart = this.firstCharOffset;
1195 this.tokenEnd = this.firstCharOffset;
1196 },
1197
1198 lookupType: function(offset) {
1199 offset += this.tokenIndex;
1200
1201 if (offset < this.tokenCount) {
1202 return this.offsetAndType[offset] >> TYPE_SHIFT;
1203 }
1204
1205 return EOF$1;
1206 },
1207 lookupOffset: function(offset) {
1208 offset += this.tokenIndex;
1209
1210 if (offset < this.tokenCount) {
1211 return this.offsetAndType[offset - 1] & OFFSET_MASK;
1212 }
1213
1214 return this.source.length;
1215 },
1216 lookupValue: function(offset, referenceStr) {
1217 offset += this.tokenIndex;
1218
1219 if (offset < this.tokenCount) {
1220 return cmpStr$1(
1221 this.source,
1222 this.offsetAndType[offset - 1] & OFFSET_MASK,
1223 this.offsetAndType[offset] & OFFSET_MASK,
1224 referenceStr
1225 );
1226 }
1227
1228 return false;
1229 },
1230 getTokenStart: function(tokenIndex) {
1231 if (tokenIndex === this.tokenIndex) {
1232 return this.tokenStart;
1233 }
1234
1235 if (tokenIndex > 0) {
1236 return tokenIndex < this.tokenCount
1237 ? this.offsetAndType[tokenIndex - 1] & OFFSET_MASK
1238 : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
1239 }
1240
1241 return this.firstCharOffset;
1242 },
1243
1244 // TODO: -> skipUntilBalanced
1245 getRawLength: function(startToken, mode) {
1246 var cursor = startToken;
1247 var balanceEnd;
1248 var offset = this.offsetAndType[Math.max(cursor - 1, 0)] & OFFSET_MASK;
1249 var type;
1250
1251 loop:
1252 for (; cursor < this.tokenCount; cursor++) {
1253 balanceEnd = this.balance[cursor];
1254
1255 // stop scanning on balance edge that points to offset before start token
1256 if (balanceEnd < startToken) {
1257 break loop;
1258 }
1259
1260 type = this.offsetAndType[cursor] >> TYPE_SHIFT;
1261
1262 // check token is stop type
1263 switch (mode(type, this.source, offset)) {
1264 case 1:
1265 break loop;
1266
1267 case 2:
1268 cursor++;
1269 break loop;
1270
1271 default:
1272 offset = this.offsetAndType[cursor] & OFFSET_MASK;
1273
1274 // fast forward to the end of balanced block
1275 if (this.balance[balanceEnd] === cursor) {
1276 cursor = balanceEnd;
1277 }
1278 }
1279 }
1280
1281 return cursor - this.tokenIndex;
1282 },
1283 isBalanceEdge: function(pos) {
1284 return this.balance[this.tokenIndex] < pos;
1285 },
1286 isDelim: function(code, offset) {
1287 if (offset) {
1288 return (
1289 this.lookupType(offset) === TYPE$1.Delim &&
1290 this.source.charCodeAt(this.lookupOffset(offset)) === code
1291 );
1292 }
1293
1294 return (
1295 this.tokenType === TYPE$1.Delim &&
1296 this.source.charCodeAt(this.tokenStart) === code
1297 );
1298 },
1299
1300 getTokenValue: function() {
1301 return this.source.substring(this.tokenStart, this.tokenEnd);
1302 },
1303 getTokenLength: function() {
1304 return this.tokenEnd - this.tokenStart;
1305 },
1306 substrToCursor: function(start) {
1307 return this.source.substring(start, this.tokenStart);
1308 },
1309
1310 skipWS: function() {
1311 for (var i = this.tokenIndex, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
1312 if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE) {
1313 break;
1314 }
1315 }
1316
1317 if (skipTokenCount > 0) {
1318 this.skip(skipTokenCount);
1319 }
1320 },
1321 skipSC: function() {
1322 while (this.tokenType === WHITESPACE || this.tokenType === COMMENT) {
1323 this.next();
1324 }
1325 },
1326 skip: function(tokenCount) {
1327 var next = this.tokenIndex + tokenCount;
1328
1329 if (next < this.tokenCount) {
1330 this.tokenIndex = next;
1331 this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
1332 next = this.offsetAndType[next];
1333 this.tokenType = next >> TYPE_SHIFT;
1334 this.tokenEnd = next & OFFSET_MASK;
1335 } else {
1336 this.tokenIndex = this.tokenCount;
1337 this.next();
1338 }
1339 },
1340 next: function() {
1341 var next = this.tokenIndex + 1;
1342
1343 if (next < this.tokenCount) {
1344 this.tokenIndex = next;
1345 this.tokenStart = this.tokenEnd;
1346 next = this.offsetAndType[next];
1347 this.tokenType = next >> TYPE_SHIFT;
1348 this.tokenEnd = next & OFFSET_MASK;
1349 } else {
1350 this.tokenIndex = this.tokenCount;
1351 this.eof = true;
1352 this.tokenType = EOF$1;
1353 this.tokenStart = this.tokenEnd = this.source.length;
1354 }
1355 },
1356
1357 dump: function() {
1358 var offset = this.firstCharOffset;
1359
1360 return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
1361 var start = offset;
1362 var end = item & OFFSET_MASK;
1363
1364 offset = end;
1365
1366 return {
1367 idx: idx,
1368 type: NAME$1[item >> TYPE_SHIFT],
1369 chunk: this.source.substring(start, end),
1370 balance: this.balance[idx]
1371 };
1372 }, this);
1373 }
1374 };
1375
1376 var TokenStream_1 = TokenStream;
1377
1378 function noop(value) {
1379 return value;
1380 }
1381
1382 function generateMultiplier(multiplier) {
1383 if (multiplier.min === 0 && multiplier.max === 0) {
1384 return '*';
1385 }
1386
1387 if (multiplier.min === 0 && multiplier.max === 1) {
1388 return '?';
1389 }
1390
1391 if (multiplier.min === 1 && multiplier.max === 0) {
1392 return multiplier.comma ? '#' : '+';
1393 }
1394
1395 if (multiplier.min === 1 && multiplier.max === 1) {
1396 return '';
1397 }
1398
1399 return (
1400 (multiplier.comma ? '#' : '') +
1401 (multiplier.min === multiplier.max
1402 ? '{' + multiplier.min + '}'
1403 : '{' + multiplier.min + ',' + (multiplier.max !== 0 ? multiplier.max : '') + '}'
1404 )
1405 );
1406 }
1407
1408 function generateTypeOpts(node) {
1409 switch (node.type) {
1410 case 'Range':
1411 return (
1412 ' [' +
1413 (node.min === null ? '-∞' : node.min) +
1414 ',' +
1415 (node.max === null ? '∞' : node.max) +
1416 ']'
1417 );
1418
1419 default:
1420 throw new Error('Unknown node type `' + node.type + '`');
1421 }
1422 }
1423
1424 function generateSequence(node, decorate, forceBraces, compact) {
1425 var combinator = node.combinator === ' ' || compact ? node.combinator : ' ' + node.combinator + ' ';
1426 var result = node.terms.map(function(term) {
1427 return generate(term, decorate, forceBraces, compact);
1428 }).join(combinator);
1429
1430 if (node.explicit || forceBraces) {
1431 result = (compact || result[0] === ',' ? '[' : '[ ') + result + (compact ? ']' : ' ]');
1432 }
1433
1434 return result;
1435 }
1436
1437 function generate(node, decorate, forceBraces, compact) {
1438 var result;
1439
1440 switch (node.type) {
1441 case 'Group':
1442 result =
1443 generateSequence(node, decorate, forceBraces, compact) +
1444 (node.disallowEmpty ? '!' : '');
1445 break;
1446
1447 case 'Multiplier':
1448 // return since node is a composition
1449 return (
1450 generate(node.term, decorate, forceBraces, compact) +
1451 decorate(generateMultiplier(node), node)
1452 );
1453
1454 case 'Type':
1455 result = '<' + node.name + (node.opts ? decorate(generateTypeOpts(node.opts), node.opts) : '') + '>';
1456 break;
1457
1458 case 'Property':
1459 result = '<\'' + node.name + '\'>';
1460 break;
1461
1462 case 'Keyword':
1463 result = node.name;
1464 break;
1465
1466 case 'AtKeyword':
1467 result = '@' + node.name;
1468 break;
1469
1470 case 'Function':
1471 result = node.name + '(';
1472 break;
1473
1474 case 'String':
1475 case 'Token':
1476 result = node.value;
1477 break;
1478
1479 case 'Comma':
1480 result = ',';
1481 break;
1482
1483 default:
1484 throw new Error('Unknown node type `' + node.type + '`');
1485 }
1486
1487 return decorate(result, node);
1488 }
1489
1490 var generate_1 = function(node, options) {
1491 var decorate = noop;
1492 var forceBraces = false;
1493 var compact = false;
1494
1495 if (typeof options === 'function') {
1496 decorate = options;
1497 } else if (options) {
1498 forceBraces = Boolean(options.forceBraces);
1499 compact = Boolean(options.compact);
1500 if (typeof options.decorate === 'function') {
1501 decorate = options.decorate;
1502 }
1503 }
1504
1505 return generate(node, decorate, forceBraces, compact);
1506 };
1507
1508 function fromMatchResult(matchResult) {
1509 var tokens = matchResult.tokens;
1510 var longestMatch = matchResult.longestMatch;
1511 var node = longestMatch < tokens.length ? tokens[longestMatch].node : null;
1512 var mismatchOffset = -1;
1513 var entries = 0;
1514 var css = '';
1515
1516 for (var i = 0; i < tokens.length; i++) {
1517 if (i === longestMatch) {
1518 mismatchOffset = css.length;
1519 }
1520
1521 if (node !== null && tokens[i].node === node) {
1522 if (i <= longestMatch) {
1523 entries++;
1524 } else {
1525 entries = 0;
1526 }
1527 }
1528
1529 css += tokens[i].value;
1530 }
1531
1532 return {
1533 node: node,
1534 css: css,
1535 mismatchOffset: mismatchOffset === -1 ? css.length : mismatchOffset,
1536 last: node === null || entries > 1
1537 };
1538 }
1539
1540 function getLocation(node, point) {
1541 var loc = node && node.loc && node.loc[point];
1542
1543 if (loc) {
1544 return {
1545 offset: loc.offset,
1546 line: loc.line,
1547 column: loc.column
1548 };
1549 }
1550
1551 return null;
1552 }
1553
1554 var SyntaxReferenceError = function(type, referenceName) {
1555 var error = createCustomError(
1556 'SyntaxReferenceError',
1557 type + (referenceName ? ' `' + referenceName + '`' : '')
1558 );
1559
1560 error.reference = referenceName;
1561
1562 return error;
1563 };
1564
1565 var MatchError = function(message, syntax, node, matchResult) {
1566 var error = createCustomError('SyntaxMatchError', message);
1567 var details = fromMatchResult(matchResult);
1568 var mismatchOffset = details.mismatchOffset || 0;
1569 var badNode = details.node || node;
1570 var end = getLocation(badNode, 'end');
1571 var start = details.last ? end : getLocation(badNode, 'start');
1572 var css = details.css;
1573
1574 error.rawMessage = message;
1575 error.syntax = syntax ? generate_1(syntax) : '<generic>';
1576 error.css = css;
1577 error.mismatchOffset = mismatchOffset;
1578 error.loc = {
1579 source: (badNode && badNode.loc && badNode.loc.source) || '<unknown>',
1580 start: start,
1581 end: end
1582 };
1583 error.line = start ? start.line : undefined;
1584 error.column = start ? start.column : undefined;
1585 error.offset = start ? start.offset : undefined;
1586 error.message = message + '\n' +
1587 ' syntax: ' + error.syntax + '\n' +
1588 ' value: ' + (error.css || '<empty string>') + '\n' +
1589 ' --------' + new Array(error.mismatchOffset + 1).join('-') + '^';
1590
1591 return error;
1592 };
1593
1594 var error = {
1595 SyntaxReferenceError: SyntaxReferenceError,
1596 MatchError: MatchError
1597 };
1598
1599 var hasOwnProperty = Object.prototype.hasOwnProperty;
1600 var keywords = Object.create(null);
1601 var properties = Object.create(null);
1602 var HYPHENMINUS = 45; // '-'.charCodeAt()
1603
1604 function isCustomProperty(str, offset) {
1605 offset = offset || 0;
1606
1607 return str.length - offset >= 2 &&
1608 str.charCodeAt(offset) === HYPHENMINUS &&
1609 str.charCodeAt(offset + 1) === HYPHENMINUS;
1610 }
1611
1612 function getVendorPrefix(str, offset) {
1613 offset = offset || 0;
1614
1615 // verdor prefix should be at least 3 chars length
1616 if (str.length - offset >= 3) {
1617 // vendor prefix starts with hyper minus following non-hyper minus
1618 if (str.charCodeAt(offset) === HYPHENMINUS &&
1619 str.charCodeAt(offset + 1) !== HYPHENMINUS) {
1620 // vendor prefix should contain a hyper minus at the ending
1621 var secondDashIndex = str.indexOf('-', offset + 2);
1622
1623 if (secondDashIndex !== -1) {
1624 return str.substring(offset, secondDashIndex + 1);
1625 }
1626 }
1627 }
1628
1629 return '';
1630 }
1631
1632 function getKeywordDescriptor(keyword) {
1633 if (hasOwnProperty.call(keywords, keyword)) {
1634 return keywords[keyword];
1635 }
1636
1637 var name = keyword.toLowerCase();
1638
1639 if (hasOwnProperty.call(keywords, name)) {
1640 return keywords[keyword] = keywords[name];
1641 }
1642
1643 var custom = isCustomProperty(name, 0);
1644 var vendor = !custom ? getVendorPrefix(name, 0) : '';
1645
1646 return keywords[keyword] = Object.freeze({
1647 basename: name.substr(vendor.length),
1648 name: name,
1649 vendor: vendor,
1650 prefix: vendor,
1651 custom: custom
1652 });
1653 }
1654
1655 function getPropertyDescriptor(property) {
1656 if (hasOwnProperty.call(properties, property)) {
1657 return properties[property];
1658 }
1659
1660 var name = property;
1661 var hack = property[0];
1662
1663 if (hack === '/') {
1664 hack = property[1] === '/' ? '//' : '/';
1665 } else if (hack !== '_' &&
1666 hack !== '*' &&
1667 hack !== '$' &&
1668 hack !== '#' &&
1669 hack !== '+' &&
1670 hack !== '&') {
1671 hack = '';
1672 }
1673
1674 var custom = isCustomProperty(name, hack.length);
1675
1676 // re-use result when possible (the same as for lower case)
1677 if (!custom) {
1678 name = name.toLowerCase();
1679 if (hasOwnProperty.call(properties, name)) {
1680 return properties[property] = properties[name];
1681 }
1682 }
1683
1684 var vendor = !custom ? getVendorPrefix(name, hack.length) : '';
1685 var prefix = name.substr(0, hack.length + vendor.length);
1686
1687 return properties[property] = Object.freeze({
1688 basename: name.substr(prefix.length),
1689 name: name.substr(hack.length),
1690 hack: hack,
1691 vendor: vendor,
1692 prefix: prefix,
1693 custom: custom
1694 });
1695 }
1696
1697 var names = {
1698 keyword: getKeywordDescriptor,
1699 property: getPropertyDescriptor,
1700 isCustomProperty: isCustomProperty,
1701 vendorPrefix: getVendorPrefix
1702 };
1703
1704 var MIN_SIZE = 16 * 1024;
1705 var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
1706
1707 var adoptBuffer = function adoptBuffer(buffer, size) {
1708 if (buffer === null || buffer.length < size) {
1709 return new SafeUint32Array(Math.max(size + 1024, MIN_SIZE));
1710 }
1711
1712 return buffer;
1713 };
1714
1715 var TYPE$2 = _const.TYPE;
1716
1717
1718 var isNewline$1 = charCodeDefinitions.isNewline;
1719 var isName$2 = charCodeDefinitions.isName;
1720 var isValidEscape$2 = charCodeDefinitions.isValidEscape;
1721 var isNumberStart$1 = charCodeDefinitions.isNumberStart;
1722 var isIdentifierStart$1 = charCodeDefinitions.isIdentifierStart;
1723 var charCodeCategory$1 = charCodeDefinitions.charCodeCategory;
1724 var isBOM$1 = charCodeDefinitions.isBOM;
1725
1726
1727 var cmpStr$2 = utils.cmpStr;
1728 var getNewlineLength$1 = utils.getNewlineLength;
1729 var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
1730 var consumeEscaped$1 = utils.consumeEscaped;
1731 var consumeName$1 = utils.consumeName;
1732 var consumeNumber$1 = utils.consumeNumber;
1733 var consumeBadUrlRemnants$1 = utils.consumeBadUrlRemnants;
1734
1735 var OFFSET_MASK$1 = 0x00FFFFFF;
1736 var TYPE_SHIFT$1 = 24;
1737
1738 function tokenize(source, stream) {
1739 function getCharCode(offset) {
1740 return offset < sourceLength ? source.charCodeAt(offset) : 0;
1741 }
1742
1743 // § 4.3.3. Consume a numeric token
1744 function consumeNumericToken() {
1745 // Consume a number and let number be the result.
1746 offset = consumeNumber$1(source, offset);
1747
1748 // If the next 3 input code points would start an identifier, then:
1749 if (isIdentifierStart$1(getCharCode(offset), getCharCode(offset + 1), getCharCode(offset + 2))) {
1750 // Create a <dimension-token> with the same value and type flag as number, and a unit set initially to the empty string.
1751 // Consume a name. Set the <dimension-token>’s unit to the returned value.
1752 // Return the <dimension-token>.
1753 type = TYPE$2.Dimension;
1754 offset = consumeName$1(source, offset);
1755 return;
1756 }
1757
1758 // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it.
1759 if (getCharCode(offset) === 0x0025) {
1760 // Create a <percentage-token> with the same value as number, and return it.
1761 type = TYPE$2.Percentage;
1762 offset++;
1763 return;
1764 }
1765
1766 // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
1767 type = TYPE$2.Number;
1768 }
1769
1770 // § 4.3.4. Consume an ident-like token
1771 function consumeIdentLikeToken() {
1772 const nameStartOffset = offset;
1773
1774 // Consume a name, and let string be the result.
1775 offset = consumeName$1(source, offset);
1776
1777 // If string’s value is an ASCII case-insensitive match for "url",
1778 // and the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
1779 if (cmpStr$2(source, nameStartOffset, offset, 'url') && getCharCode(offset) === 0x0028) {
1780 // While the next two input code points are whitespace, consume the next input code point.
1781 offset = findWhiteSpaceEnd$1(source, offset + 1);
1782
1783 // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('),
1784 // or whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('),
1785 // then create a <function-token> with its value set to string and return it.
1786 if (getCharCode(offset) === 0x0022 ||
1787 getCharCode(offset) === 0x0027) {
1788 type = TYPE$2.Function;
1789 offset = nameStartOffset + 4;
1790 return;
1791 }
1792
1793 // Otherwise, consume a url token, and return it.
1794 consumeUrlToken();
1795 return;
1796 }
1797
1798 // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it.
1799 // Create a <function-token> with its value set to string and return it.
1800 if (getCharCode(offset) === 0x0028) {
1801 type = TYPE$2.Function;
1802 offset++;
1803 return;
1804 }
1805
1806 // Otherwise, create an <ident-token> with its value set to string and return it.
1807 type = TYPE$2.Ident;
1808 }
1809
1810 // § 4.3.5. Consume a string token
1811 function consumeStringToken(endingCodePoint) {
1812 // This algorithm may be called with an ending code point, which denotes the code point
1813 // that ends the string. If an ending code point is not specified,
1814 // the current input code point is used.
1815 if (!endingCodePoint) {
1816 endingCodePoint = getCharCode(offset++);
1817 }
1818
1819 // Initially create a <string-token> with its value set to the empty string.
1820 type = TYPE$2.String;
1821
1822 // Repeatedly consume the next input code point from the stream:
1823 for (; offset < source.length; offset++) {
1824 var code = source.charCodeAt(offset);
1825
1826 switch (charCodeCategory$1(code)) {
1827 // ending code point
1828 case endingCodePoint:
1829 // Return the <string-token>.
1830 offset++;
1831 return;
1832
1833 // EOF
1834 case charCodeCategory$1.Eof:
1835 // This is a parse error. Return the <string-token>.
1836 return;
1837
1838 // newline
1839 case charCodeCategory$1.WhiteSpace:
1840 if (isNewline$1(code)) {
1841 // This is a parse error. Reconsume the current input code point,
1842 // create a <bad-string-token>, and return it.
1843 offset += getNewlineLength$1(source, offset, code);
1844 type = TYPE$2.BadString;
1845 return;
1846 }
1847 break;
1848
1849 // U+005C REVERSE SOLIDUS (\)
1850 case 0x005C:
1851 // If the next input code point is EOF, do nothing.
1852 if (offset === source.length - 1) {
1853 break;
1854 }
1855
1856 var nextCode = getCharCode(offset + 1);
1857
1858 // Otherwise, if the next input code point is a newline, consume it.
1859 if (isNewline$1(nextCode)) {
1860 offset += getNewlineLength$1(source, offset + 1, nextCode);
1861 } else if (isValidEscape$2(code, nextCode)) {
1862 // Otherwise, (the stream starts with a valid escape) consume
1863 // an escaped code point and append the returned code point to
1864 // the <string-token>’s value.
1865 offset = consumeEscaped$1(source, offset) - 1;
1866 }
1867 break;
1868
1869 // anything else
1870 // Append the current input code point to the <string-token>’s value.
1871 }
1872 }
1873 }
1874
1875 // § 4.3.6. Consume a url token
1876 // Note: This algorithm assumes that the initial "url(" has already been consumed.
1877 // This algorithm also assumes that it’s being called to consume an "unquoted" value, like url(foo).
1878 // A quoted value, like url("foo"), is parsed as a <function-token>. Consume an ident-like token
1879 // automatically handles this distinction; this algorithm shouldn’t be called directly otherwise.
1880 function consumeUrlToken() {
1881 // Initially create a <url-token> with its value set to the empty string.
1882 type = TYPE$2.Url;
1883
1884 // Consume as much whitespace as possible.
1885 offset = findWhiteSpaceEnd$1(source, offset);
1886
1887 // Repeatedly consume the next input code point from the stream:
1888 for (; offset < source.length; offset++) {
1889 var code = source.charCodeAt(offset);
1890
1891 switch (charCodeCategory$1(code)) {
1892 // U+0029 RIGHT PARENTHESIS ())
1893 case 0x0029:
1894 // Return the <url-token>.
1895 offset++;
1896 return;
1897
1898 // EOF
1899 case charCodeCategory$1.Eof:
1900 // This is a parse error. Return the <url-token>.
1901 return;
1902
1903 // whitespace
1904 case charCodeCategory$1.WhiteSpace:
1905 // Consume as much whitespace as possible.
1906 offset = findWhiteSpaceEnd$1(source, offset);
1907
1908 // If the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF,
1909 // consume it and return the <url-token>
1910 // (if EOF was encountered, this is a parse error);
1911 if (getCharCode(offset) === 0x0029 || offset >= source.length) {
1912 if (offset < source.length) {
1913 offset++;
1914 }
1915 return;
1916 }
1917
1918 // otherwise, consume the remnants of a bad url, create a <bad-url-token>,
1919 // and return it.
1920 offset = consumeBadUrlRemnants$1(source, offset);
1921 type = TYPE$2.BadUrl;
1922 return;
1923
1924 // U+0022 QUOTATION MARK (")
1925 // U+0027 APOSTROPHE (')
1926 // U+0028 LEFT PARENTHESIS (()
1927 // non-printable code point
1928 case 0x0022:
1929 case 0x0027:
1930 case 0x0028:
1931 case charCodeCategory$1.NonPrintable:
1932 // This is a parse error. Consume the remnants of a bad url,
1933 // create a <bad-url-token>, and return it.
1934 offset = consumeBadUrlRemnants$1(source, offset);
1935 type = TYPE$2.BadUrl;
1936 return;
1937
1938 // U+005C REVERSE SOLIDUS (\)
1939 case 0x005C:
1940 // If the stream starts with a valid escape, consume an escaped code point and
1941 // append the returned code point to the <url-token>’s value.
1942 if (isValidEscape$2(code, getCharCode(offset + 1))) {
1943 offset = consumeEscaped$1(source, offset) - 1;
1944 break;
1945 }
1946
1947 // Otherwise, this is a parse error. Consume the remnants of a bad url,
1948 // create a <bad-url-token>, and return it.
1949 offset = consumeBadUrlRemnants$1(source, offset);
1950 type = TYPE$2.BadUrl;
1951 return;
1952
1953 // anything else
1954 // Append the current input code point to the <url-token>’s value.
1955 }
1956 }
1957 }
1958
1959 if (!stream) {
1960 stream = new TokenStream_1();
1961 }
1962
1963 // ensure source is a string
1964 source = String(source || '');
1965
1966 var sourceLength = source.length;
1967 var offsetAndType = adoptBuffer(stream.offsetAndType, sourceLength + 1); // +1 because of eof-token
1968 var balance = adoptBuffer(stream.balance, sourceLength + 1);
1969 var tokenCount = 0;
1970 var start = isBOM$1(getCharCode(0));
1971 var offset = start;
1972 var balanceCloseType = 0;
1973 var balanceStart = 0;
1974 var balancePrev = 0;
1975
1976 // https://drafts.csswg.org/css-syntax-3/#consume-token
1977 // § 4.3.1. Consume a token
1978 while (offset < sourceLength) {
1979 var code = source.charCodeAt(offset);
1980 var type = 0;
1981
1982 balance[tokenCount] = sourceLength;
1983
1984 switch (charCodeCategory$1(code)) {
1985 // whitespace
1986 case charCodeCategory$1.WhiteSpace:
1987 // Consume as much whitespace as possible. Return a <whitespace-token>.
1988 type = TYPE$2.WhiteSpace;
1989 offset = findWhiteSpaceEnd$1(source, offset + 1);
1990 break;
1991
1992 // U+0022 QUOTATION MARK (")
1993 case 0x0022:
1994 // Consume a string token and return it.
1995 consumeStringToken();
1996 break;
1997
1998 // U+0023 NUMBER SIGN (#)
1999 case 0x0023:
2000 // If the next input code point is a name code point or the next two input code points are a valid escape, then:
2001 if (isName$2(getCharCode(offset + 1)) || isValidEscape$2(getCharCode(offset + 1), getCharCode(offset + 2))) {
2002 // Create a <hash-token>.
2003 type = TYPE$2.Hash;
2004
2005 // If the next 3 input code points would start an identifier, set the <hash-token>’s type flag to "id".
2006 // if (isIdentifierStart(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
2007 // // TODO: set id flag
2008 // }
2009
2010 // Consume a name, and set the <hash-token>’s value to the returned string.
2011 offset = consumeName$1(source, offset + 1);
2012
2013 // Return the <hash-token>.
2014 } else {
2015 // Otherwise, return a <delim-token> with its value set to the current input code point.
2016 type = TYPE$2.Delim;
2017 offset++;
2018 }
2019
2020 break;
2021
2022 // U+0027 APOSTROPHE (')
2023 case 0x0027:
2024 // Consume a string token and return it.
2025 consumeStringToken();
2026 break;
2027
2028 // U+0028 LEFT PARENTHESIS (()
2029 case 0x0028:
2030 // Return a <(-token>.
2031 type = TYPE$2.LeftParenthesis;
2032 offset++;
2033 break;
2034
2035 // U+0029 RIGHT PARENTHESIS ())
2036 case 0x0029:
2037 // Return a <)-token>.
2038 type = TYPE$2.RightParenthesis;
2039 offset++;
2040 break;
2041
2042 // U+002B PLUS SIGN (+)
2043 case 0x002B:
2044 // If the input stream starts with a number, ...
2045 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
2046 // ... reconsume the current input code point, consume a numeric token, and return it.
2047 consumeNumericToken();
2048 } else {
2049 // Otherwise, return a <delim-token> with its value set to the current input code point.
2050 type = TYPE$2.Delim;
2051 offset++;
2052 }
2053 break;
2054
2055 // U+002C COMMA (,)
2056 case 0x002C:
2057 // Return a <comma-token>.
2058 type = TYPE$2.Comma;
2059 offset++;
2060 break;
2061
2062 // U+002D HYPHEN-MINUS (-)
2063 case 0x002D:
2064 // If the input stream starts with a number, reconsume the current input code point, consume a numeric token, and return it.
2065 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
2066 consumeNumericToken();
2067 } else {
2068 // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN (->), consume them and return a <CDC-token>.
2069 if (getCharCode(offset + 1) === 0x002D &&
2070 getCharCode(offset + 2) === 0x003E) {
2071 type = TYPE$2.CDC;
2072 offset = offset + 3;
2073 } else {
2074 // Otherwise, if the input stream starts with an identifier, ...
2075 if (isIdentifierStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
2076 // ... reconsume the current input code point, consume an ident-like token, and return it.
2077 consumeIdentLikeToken();
2078 } else {
2079 // Otherwise, return a <delim-token> with its value set to the current input code point.
2080 type = TYPE$2.Delim;
2081 offset++;
2082 }
2083 }
2084 }
2085 break;
2086
2087 // U+002E FULL STOP (.)
2088 case 0x002E:
2089 // If the input stream starts with a number, ...
2090 if (isNumberStart$1(code, getCharCode(offset + 1), getCharCode(offset + 2))) {
2091 // ... reconsume the current input code point, consume a numeric token, and return it.
2092 consumeNumericToken();
2093 } else {
2094 // Otherwise, return a <delim-token> with its value set to the current input code point.
2095 type = TYPE$2.Delim;
2096 offset++;
2097 }
2098
2099 break;
2100
2101 // U+002F SOLIDUS (/)
2102 case 0x002F:
2103 // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
2104 if (getCharCode(offset + 1) === 0x002A) {
2105 // ... consume them and all following code points up to and including the first U+002A ASTERISK (*)
2106 // followed by a U+002F SOLIDUS (/), or up to an EOF code point.
2107 type = TYPE$2.Comment;
2108 offset = source.indexOf('*/', offset + 2) + 2;
2109 if (offset === 1) {
2110 offset = source.length;
2111 }
2112 } else {
2113 type = TYPE$2.Delim;
2114 offset++;
2115 }
2116 break;
2117
2118 // U+003A COLON (:)
2119 case 0x003A:
2120 // Return a <colon-token>.
2121 type = TYPE$2.Colon;
2122 offset++;
2123 break;
2124
2125 // U+003B SEMICOLON (;)
2126 case 0x003B:
2127 // Return a <semicolon-token>.
2128 type = TYPE$2.Semicolon;
2129 offset++;
2130 break;
2131
2132 // U+003C LESS-THAN SIGN (<)
2133 case 0x003C:
2134 // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D HYPHEN-MINUS (!--), ...
2135 if (getCharCode(offset + 1) === 0x0021 &&
2136 getCharCode(offset + 2) === 0x002D &&
2137 getCharCode(offset + 3) === 0x002D) {
2138 // ... consume them and return a <CDO-token>.
2139 type = TYPE$2.CDO;
2140 offset = offset + 4;
2141 } else {
2142 // Otherwise, return a <delim-token> with its value set to the current input code point.
2143 type = TYPE$2.Delim;
2144 offset++;
2145 }
2146
2147 break;
2148
2149 // U+0040 COMMERCIAL AT (@)
2150 case 0x0040:
2151 // If the next 3 input code points would start an identifier, ...
2152 if (isIdentifierStart$1(getCharCode(offset + 1), getCharCode(offset + 2), getCharCode(offset + 3))) {
2153 // ... consume a name, create an <at-keyword-token> with its value set to the returned value, and return it.
2154 type = TYPE$2.AtKeyword;
2155 offset = consumeName$1(source, offset + 1);
2156 } else {
2157 // Otherwise, return a <delim-token> with its value set to the current input code point.
2158 type = TYPE$2.Delim;
2159 offset++;
2160 }
2161
2162 break;
2163
2164 // U+005B LEFT SQUARE BRACKET ([)
2165 case 0x005B:
2166 // Return a <[-token>.
2167 type = TYPE$2.LeftSquareBracket;
2168 offset++;
2169 break;
2170
2171 // U+005C REVERSE SOLIDUS (\)
2172 case 0x005C:
2173 // If the input stream starts with a valid escape, ...
2174 if (isValidEscape$2(code, getCharCode(offset + 1))) {
2175 // ... reconsume the current input code point, consume an ident-like token, and return it.
2176 consumeIdentLikeToken();
2177 } else {
2178 // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current input code point.
2179 type = TYPE$2.Delim;
2180 offset++;
2181 }
2182 break;
2183
2184 // U+005D RIGHT SQUARE BRACKET (])
2185 case 0x005D:
2186 // Return a <]-token>.
2187 type = TYPE$2.RightSquareBracket;
2188 offset++;
2189 break;
2190
2191 // U+007B LEFT CURLY BRACKET ({)
2192 case 0x007B:
2193 // Return a <{-token>.
2194 type = TYPE$2.LeftCurlyBracket;
2195 offset++;
2196 break;
2197
2198 // U+007D RIGHT CURLY BRACKET (})
2199 case 0x007D:
2200 // Return a <}-token>.
2201 type = TYPE$2.RightCurlyBracket;
2202 offset++;
2203 break;
2204
2205 // digit
2206 case charCodeCategory$1.Digit:
2207 // Reconsume the current input code point, consume a numeric token, and return it.
2208 consumeNumericToken();
2209 break;
2210
2211 // name-start code point
2212 case charCodeCategory$1.NameStart:
2213 // Reconsume the current input code point, consume an ident-like token, and return it.
2214 consumeIdentLikeToken();
2215 break;
2216
2217 // EOF
2218 case charCodeCategory$1.Eof:
2219 // Return an <EOF-token>.
2220 break;
2221
2222 // anything else
2223 default:
2224 // Return a <delim-token> with its value set to the current input code point.
2225 type = TYPE$2.Delim;
2226 offset++;
2227 }
2228
2229 switch (type) {
2230 case balanceCloseType:
2231 balancePrev = balanceStart & OFFSET_MASK$1;
2232 balanceStart = balance[balancePrev];
2233 balanceCloseType = balanceStart >> TYPE_SHIFT$1;
2234 balance[tokenCount] = balancePrev;
2235 balance[balancePrev++] = tokenCount;
2236 for (; balancePrev < tokenCount; balancePrev++) {
2237 if (balance[balancePrev] === sourceLength) {
2238 balance[balancePrev] = tokenCount;
2239 }
2240 }
2241 break;
2242
2243 case TYPE$2.LeftParenthesis:
2244 case TYPE$2.Function:
2245 balance[tokenCount] = balanceStart;
2246 balanceCloseType = TYPE$2.RightParenthesis;
2247 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
2248 break;
2249
2250 case TYPE$2.LeftSquareBracket:
2251 balance[tokenCount] = balanceStart;
2252 balanceCloseType = TYPE$2.RightSquareBracket;
2253 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
2254 break;
2255
2256 case TYPE$2.LeftCurlyBracket:
2257 balance[tokenCount] = balanceStart;
2258 balanceCloseType = TYPE$2.RightCurlyBracket;
2259 balanceStart = (balanceCloseType << TYPE_SHIFT$1) | tokenCount;
2260 break;
2261 }
2262
2263 offsetAndType[tokenCount++] = (type << TYPE_SHIFT$1) | offset;
2264 }
2265
2266 // finalize buffers
2267 offsetAndType[tokenCount] = (TYPE$2.EOF << TYPE_SHIFT$1) | offset; // <EOF-token>
2268 balance[tokenCount] = sourceLength;
2269 balance[sourceLength] = sourceLength; // prevents false positive balance match with any token
2270 while (balanceStart !== 0) {
2271 balancePrev = balanceStart & OFFSET_MASK$1;
2272 balanceStart = balance[balancePrev];
2273 balance[balancePrev] = sourceLength;
2274 }
2275
2276 // update stream
2277 stream.source = source;
2278 stream.firstCharOffset = start;
2279 stream.offsetAndType = offsetAndType;
2280 stream.tokenCount = tokenCount;
2281 stream.balance = balance;
2282 stream.reset();
2283 stream.next();
2284
2285 return stream;
2286 }
2287
2288 // extend tokenizer with constants
2289 Object.keys(_const).forEach(function(key) {
2290 tokenize[key] = _const[key];
2291 });
2292
2293 // extend tokenizer with static methods from utils
2294 Object.keys(charCodeDefinitions).forEach(function(key) {
2295 tokenize[key] = charCodeDefinitions[key];
2296 });
2297 Object.keys(utils).forEach(function(key) {
2298 tokenize[key] = utils[key];
2299 });
2300
2301 var tokenizer = tokenize;
2302
2303 var isDigit$2 = tokenizer.isDigit;
2304 var cmpChar$1 = tokenizer.cmpChar;
2305 var TYPE$3 = tokenizer.TYPE;
2306
2307 var DELIM = TYPE$3.Delim;
2308 var WHITESPACE$1 = TYPE$3.WhiteSpace;
2309 var COMMENT$1 = TYPE$3.Comment;
2310 var IDENT = TYPE$3.Ident;
2311 var NUMBER = TYPE$3.Number;
2312 var DIMENSION = TYPE$3.Dimension;
2313 var PLUSSIGN = 0x002B; // U+002B PLUS SIGN (+)
2314 var HYPHENMINUS$1 = 0x002D; // U+002D HYPHEN-MINUS (-)
2315 var N = 0x006E; // U+006E LATIN SMALL LETTER N (n)
2316 var DISALLOW_SIGN = true;
2317 var ALLOW_SIGN = false;
2318
2319 function isDelim(token, code) {
2320 return token !== null && token.type === DELIM && token.value.charCodeAt(0) === code;
2321 }
2322
2323 function skipSC(token, offset, getNextToken) {
2324 while (token !== null && (token.type === WHITESPACE$1 || token.type === COMMENT$1)) {
2325 token = getNextToken(++offset);
2326 }
2327
2328 return offset;
2329 }
2330
2331 function checkInteger(token, valueOffset, disallowSign, offset) {
2332 if (!token) {
2333 return 0;
2334 }
2335
2336 var code = token.value.charCodeAt(valueOffset);
2337
2338 if (code === PLUSSIGN || code === HYPHENMINUS$1) {
2339 if (disallowSign) {
2340 // Number sign is not allowed
2341 return 0;
2342 }
2343 valueOffset++;
2344 }
2345
2346 for (; valueOffset < token.value.length; valueOffset++) {
2347 if (!isDigit$2(token.value.charCodeAt(valueOffset))) {
2348 // Integer is expected
2349 return 0;
2350 }
2351 }
2352
2353 return offset + 1;
2354 }
2355
2356 // ... <signed-integer>
2357 // ... ['+' | '-'] <signless-integer>
2358 function consumeB(token, offset_, getNextToken) {
2359 var sign = false;
2360 var offset = skipSC(token, offset_, getNextToken);
2361
2362 token = getNextToken(offset);
2363
2364 if (token === null) {
2365 return offset_;
2366 }
2367
2368 if (token.type !== NUMBER) {
2369 if (isDelim(token, PLUSSIGN) || isDelim(token, HYPHENMINUS$1)) {
2370 sign = true;
2371 offset = skipSC(getNextToken(++offset), offset, getNextToken);
2372 token = getNextToken(offset);
2373
2374 if (token === null && token.type !== NUMBER) {
2375 return 0;
2376 }
2377 } else {
2378 return offset_;
2379 }
2380 }
2381
2382 if (!sign) {
2383 var code = token.value.charCodeAt(0);
2384 if (code !== PLUSSIGN && code !== HYPHENMINUS$1) {
2385 // Number sign is expected
2386 return 0;
2387 }
2388 }
2389
2390 return checkInteger(token, sign ? 0 : 1, sign, offset);
2391 }
2392
2393 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
2394 var genericAnPlusB = function anPlusB(token, getNextToken) {
2395 /* eslint-disable brace-style*/
2396 var offset = 0;
2397
2398 if (!token) {
2399 return 0;
2400 }
2401
2402 // <integer>
2403 if (token.type === NUMBER) {
2404 return checkInteger(token, 0, ALLOW_SIGN, offset); // b
2405 }
2406
2407 // -n
2408 // -n <signed-integer>
2409 // -n ['+' | '-'] <signless-integer>
2410 // -n- <signless-integer>
2411 // <dashndashdigit-ident>
2412 else if (token.type === IDENT && token.value.charCodeAt(0) === HYPHENMINUS$1) {
2413 // expect 1st char is N
2414 if (!cmpChar$1(token.value, 1, N)) {
2415 return 0;
2416 }
2417
2418 switch (token.value.length) {
2419 // -n
2420 // -n <signed-integer>
2421 // -n ['+' | '-'] <signless-integer>
2422 case 2:
2423 return consumeB(getNextToken(++offset), offset, getNextToken);
2424
2425 // -n- <signless-integer>
2426 case 3:
2427 if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
2428 return 0;
2429 }
2430
2431 offset = skipSC(getNextToken(++offset), offset, getNextToken);
2432 token = getNextToken(offset);
2433
2434 return checkInteger(token, 0, DISALLOW_SIGN, offset);
2435
2436 // <dashndashdigit-ident>
2437 default:
2438 if (token.value.charCodeAt(2) !== HYPHENMINUS$1) {
2439 return 0;
2440 }
2441
2442 return checkInteger(token, 3, DISALLOW_SIGN, offset);
2443 }
2444 }
2445
2446 // '+'? n
2447 // '+'? n <signed-integer>
2448 // '+'? n ['+' | '-'] <signless-integer>
2449 // '+'? n- <signless-integer>
2450 // '+'? <ndashdigit-ident>
2451 else if (token.type === IDENT || (isDelim(token, PLUSSIGN) && getNextToken(offset + 1).type === IDENT)) {
2452 // just ignore a plus
2453 if (token.type !== IDENT) {
2454 token = getNextToken(++offset);
2455 }
2456
2457 if (token === null || !cmpChar$1(token.value, 0, N)) {
2458 return 0;
2459 }
2460
2461 switch (token.value.length) {
2462 // '+'? n
2463 // '+'? n <signed-integer>
2464 // '+'? n ['+' | '-'] <signless-integer>
2465 case 1:
2466 return consumeB(getNextToken(++offset), offset, getNextToken);
2467
2468 // '+'? n- <signless-integer>
2469 case 2:
2470 if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
2471 return 0;
2472 }
2473
2474 offset = skipSC(getNextToken(++offset), offset, getNextToken);
2475 token = getNextToken(offset);
2476
2477 return checkInteger(token, 0, DISALLOW_SIGN, offset);
2478
2479 // '+'? <ndashdigit-ident>
2480 default:
2481 if (token.value.charCodeAt(1) !== HYPHENMINUS$1) {
2482 return 0;
2483 }
2484
2485 return checkInteger(token, 2, DISALLOW_SIGN, offset);
2486 }
2487 }
2488
2489 // <ndashdigit-dimension>
2490 // <ndash-dimension> <signless-integer>
2491 // <n-dimension>
2492 // <n-dimension> <signed-integer>
2493 // <n-dimension> ['+' | '-'] <signless-integer>
2494 else if (token.type === DIMENSION) {
2495 var code = token.value.charCodeAt(0);
2496 var sign = code === PLUSSIGN || code === HYPHENMINUS$1 ? 1 : 0;
2497
2498 for (var i = sign; i < token.value.length; i++) {
2499 if (!isDigit$2(token.value.charCodeAt(i))) {
2500 break;
2501 }
2502 }
2503
2504 if (i === sign) {
2505 // Integer is expected
2506 return 0;
2507 }
2508
2509 if (!cmpChar$1(token.value, i, N)) {
2510 return 0;
2511 }
2512
2513 // <n-dimension>
2514 // <n-dimension> <signed-integer>
2515 // <n-dimension> ['+' | '-'] <signless-integer>
2516 if (i + 1 === token.value.length) {
2517 return consumeB(getNextToken(++offset), offset, getNextToken);
2518 } else {
2519 if (token.value.charCodeAt(i + 1) !== HYPHENMINUS$1) {
2520 return 0;
2521 }
2522
2523 // <ndash-dimension> <signless-integer>
2524 if (i + 2 === token.value.length) {
2525 offset = skipSC(getNextToken(++offset), offset, getNextToken);
2526 token = getNextToken(offset);
2527
2528 return checkInteger(token, 0, DISALLOW_SIGN, offset);
2529 }
2530 // <ndashdigit-dimension>
2531 else {
2532 return checkInteger(token, i + 2, DISALLOW_SIGN, offset);
2533 }
2534 }
2535 }
2536
2537 return 0;
2538 };
2539
2540 var isHexDigit$2 = tokenizer.isHexDigit;
2541 var cmpChar$2 = tokenizer.cmpChar;
2542 var TYPE$4 = tokenizer.TYPE;
2543
2544 var IDENT$1 = TYPE$4.Ident;
2545 var DELIM$1 = TYPE$4.Delim;
2546 var NUMBER$1 = TYPE$4.Number;
2547 var DIMENSION$1 = TYPE$4.Dimension;
2548 var PLUSSIGN$1 = 0x002B; // U+002B PLUS SIGN (+)
2549 var HYPHENMINUS$2 = 0x002D; // U+002D HYPHEN-MINUS (-)
2550 var QUESTIONMARK = 0x003F; // U+003F QUESTION MARK (?)
2551 var U = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
2552
2553 function isDelim$1(token, code) {
2554 return token !== null && token.type === DELIM$1 && token.value.charCodeAt(0) === code;
2555 }
2556
2557 function startsWith(token, code) {
2558 return token.value.charCodeAt(0) === code;
2559 }
2560
2561 function hexSequence(token, offset, allowDash) {
2562 for (var pos = offset, hexlen = 0; pos < token.value.length; pos++) {
2563 var code = token.value.charCodeAt(pos);
2564
2565 if (code === HYPHENMINUS$2 && allowDash && hexlen !== 0) {
2566 if (hexSequence(token, offset + hexlen + 1, false) > 0) {
2567 return 6; // dissallow following question marks
2568 }
2569
2570 return 0; // dash at the ending of a hex sequence is not allowed
2571 }
2572
2573 if (!isHexDigit$2(code)) {
2574 return 0; // not a hex digit
2575 }
2576
2577 if (++hexlen > 6) {
2578 return 0; // too many hex digits
2579 } }
2580
2581 return hexlen;
2582 }
2583
2584 function withQuestionMarkSequence(consumed, length, getNextToken) {
2585 if (!consumed) {
2586 return 0; // nothing consumed
2587 }
2588
2589 while (isDelim$1(getNextToken(length), QUESTIONMARK)) {
2590 if (++consumed > 6) {
2591 return 0; // too many question marks
2592 }
2593
2594 length++;
2595 }
2596
2597 return length;
2598 }
2599
2600 // https://drafts.csswg.org/css-syntax/#urange
2601 // Informally, the <urange> production has three forms:
2602 // U+0001
2603 // Defines a range consisting of a single code point, in this case the code point "1".
2604 // U+0001-00ff
2605 // Defines a range of codepoints between the first and the second value, in this case
2606 // the range between "1" and "ff" (255 in decimal) inclusive.
2607 // U+00??
2608 // Defines a range of codepoints where the "?" characters range over all hex digits,
2609 // in this case defining the same as the value U+0000-00ff.
2610 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
2611 //
2612 // <urange> =
2613 // u '+' <ident-token> '?'* |
2614 // u <dimension-token> '?'* |
2615 // u <number-token> '?'* |
2616 // u <number-token> <dimension-token> |
2617 // u <number-token> <number-token> |
2618 // u '+' '?'+
2619 var genericUrange = function urange(token, getNextToken) {
2620 var length = 0;
2621
2622 // should start with `u` or `U`
2623 if (token === null || token.type !== IDENT$1 || !cmpChar$2(token.value, 0, U)) {
2624 return 0;
2625 }
2626
2627 token = getNextToken(++length);
2628 if (token === null) {
2629 return 0;
2630 }
2631
2632 // u '+' <ident-token> '?'*
2633 // u '+' '?'+
2634 if (isDelim$1(token, PLUSSIGN$1)) {
2635 token = getNextToken(++length);
2636 if (token === null) {
2637 return 0;
2638 }
2639
2640 if (token.type === IDENT$1) {
2641 // u '+' <ident-token> '?'*
2642 return withQuestionMarkSequence(hexSequence(token, 0, true), ++length, getNextToken);
2643 }
2644
2645 if (isDelim$1(token, QUESTIONMARK)) {
2646 // u '+' '?'+
2647 return withQuestionMarkSequence(1, ++length, getNextToken);
2648 }
2649
2650 // Hex digit or question mark is expected
2651 return 0;
2652 }
2653
2654 // u <number-token> '?'*
2655 // u <number-token> <dimension-token>
2656 // u <number-token> <number-token>
2657 if (token.type === NUMBER$1) {
2658 if (!startsWith(token, PLUSSIGN$1)) {
2659 return 0;
2660 }
2661
2662 var consumedHexLength = hexSequence(token, 1, true);
2663 if (consumedHexLength === 0) {
2664 return 0;
2665 }
2666
2667 token = getNextToken(++length);
2668 if (token === null) {
2669 // u <number-token> <eof>
2670 return length;
2671 }
2672
2673 if (token.type === DIMENSION$1 || token.type === NUMBER$1) {
2674 // u <number-token> <dimension-token>
2675 // u <number-token> <number-token>
2676 if (!startsWith(token, HYPHENMINUS$2) || !hexSequence(token, 1, false)) {
2677 return 0;
2678 }
2679
2680 return length + 1;
2681 }
2682
2683 // u <number-token> '?'*
2684 return withQuestionMarkSequence(consumedHexLength, length, getNextToken);
2685 }
2686
2687 // u <dimension-token> '?'*
2688 if (token.type === DIMENSION$1) {
2689 if (!startsWith(token, PLUSSIGN$1)) {
2690 return 0;
2691 }
2692
2693 return withQuestionMarkSequence(hexSequence(token, 1, true), ++length, getNextToken);
2694 }
2695
2696 return 0;
2697 };
2698
2699 var isIdentifierStart$2 = tokenizer.isIdentifierStart;
2700 var isHexDigit$3 = tokenizer.isHexDigit;
2701 var isDigit$3 = tokenizer.isDigit;
2702 var cmpStr$3 = tokenizer.cmpStr;
2703 var consumeNumber$2 = tokenizer.consumeNumber;
2704 var TYPE$5 = tokenizer.TYPE;
2705
2706
2707
2708 var cssWideKeywords = ['unset', 'initial', 'inherit'];
2709 var calcFunctionNames = ['calc(', '-moz-calc(', '-webkit-calc('];
2710
2711 // https://www.w3.org/TR/css-values-3/#lengths
2712 var LENGTH = {
2713 // absolute length units
2714 'px': true,
2715 'mm': true,
2716 'cm': true,
2717 'in': true,
2718 'pt': true,
2719 'pc': true,
2720 'q': true,
2721
2722 // relative length units
2723 'em': true,
2724 'ex': true,
2725 'ch': true,
2726 'rem': true,
2727
2728 // viewport-percentage lengths
2729 'vh': true,
2730 'vw': true,
2731 'vmin': true,
2732 'vmax': true,
2733 'vm': true
2734 };
2735
2736 var ANGLE = {
2737 'deg': true,
2738 'grad': true,
2739 'rad': true,
2740 'turn': true
2741 };
2742
2743 var TIME = {
2744 's': true,
2745 'ms': true
2746 };
2747
2748 var FREQUENCY = {
2749 'hz': true,
2750 'khz': true
2751 };
2752
2753 // https://www.w3.org/TR/css-values-3/#resolution (https://drafts.csswg.org/css-values/#resolution)
2754 var RESOLUTION = {
2755 'dpi': true,
2756 'dpcm': true,
2757 'dppx': true,
2758 'x': true // https://github.com/w3c/csswg-drafts/issues/461
2759 };
2760
2761 // https://drafts.csswg.org/css-grid/#fr-unit
2762 var FLEX = {
2763 'fr': true
2764 };
2765
2766 // https://www.w3.org/TR/css3-speech/#mixing-props-voice-volume
2767 var DECIBEL = {
2768 'db': true
2769 };
2770
2771 // https://www.w3.org/TR/css3-speech/#voice-props-voice-pitch
2772 var SEMITONES = {
2773 'st': true
2774 };
2775
2776 // safe char code getter
2777 function charCode(str, index) {
2778 return index < str.length ? str.charCodeAt(index) : 0;
2779 }
2780
2781 function eqStr(actual, expected) {
2782 return cmpStr$3(actual, 0, actual.length, expected);
2783 }
2784
2785 function eqStrAny(actual, expected) {
2786 for (var i = 0; i < expected.length; i++) {
2787 if (eqStr(actual, expected[i])) {
2788 return true;
2789 }
2790 }
2791
2792 return false;
2793 }
2794
2795 // IE postfix hack, i.e. 123\0 or 123px\9
2796 function isPostfixIeHack(str, offset) {
2797 if (offset !== str.length - 2) {
2798 return false;
2799 }
2800
2801 return (
2802 str.charCodeAt(offset) === 0x005C && // U+005C REVERSE SOLIDUS (\)
2803 isDigit$3(str.charCodeAt(offset + 1))
2804 );
2805 }
2806
2807 function outOfRange(opts, value, numEnd) {
2808 if (opts && opts.type === 'Range') {
2809 var num = Number(
2810 numEnd !== undefined && numEnd !== value.length
2811 ? value.substr(0, numEnd)
2812 : value
2813 );
2814
2815 if (isNaN(num)) {
2816 return true;
2817 }
2818
2819 if (opts.min !== null && num < opts.min) {
2820 return true;
2821 }
2822
2823 if (opts.max !== null && num > opts.max) {
2824 return true;
2825 }
2826 }
2827
2828 return false;
2829 }
2830
2831 function consumeFunction(token, getNextToken) {
2832 var startIdx = token.index;
2833 var length = 0;
2834
2835 // balanced token consuming
2836 do {
2837 length++;
2838
2839 if (token.balance <= startIdx) {
2840 break;
2841 }
2842 } while (token = getNextToken(length));
2843
2844 return length;
2845 }
2846
2847 // TODO: implement
2848 // can be used wherever <length>, <frequency>, <angle>, <time>, <percentage>, <number>, or <integer> values are allowed
2849 // https://drafts.csswg.org/css-values/#calc-notation
2850 function calc(next) {
2851 return function(token, getNextToken, opts) {
2852 if (token === null) {
2853 return 0;
2854 }
2855
2856 if (token.type === TYPE$5.Function && eqStrAny(token.value, calcFunctionNames)) {
2857 return consumeFunction(token, getNextToken);
2858 }
2859
2860 return next(token, getNextToken, opts);
2861 };
2862 }
2863
2864 function tokenType(expectedTokenType) {
2865 return function(token) {
2866 if (token === null || token.type !== expectedTokenType) {
2867 return 0;
2868 }
2869
2870 return 1;
2871 };
2872 }
2873
2874 function func(name) {
2875 name = name + '(';
2876
2877 return function(token, getNextToken) {
2878 if (token !== null && eqStr(token.value, name)) {
2879 return consumeFunction(token, getNextToken);
2880 }
2881
2882 return 0;
2883 };
2884 }
2885
2886 // =========================
2887 // Complex types
2888 //
2889
2890 // https://drafts.csswg.org/css-values-4/#custom-idents
2891 // 4.2. Author-defined Identifiers: the <custom-ident> type
2892 // Some properties accept arbitrary author-defined identifiers as a component value.
2893 // This generic data type is denoted by <custom-ident>, and represents any valid CSS identifier
2894 // that would not be misinterpreted as a pre-defined keyword in that property’s value definition.
2895 //
2896 // See also: https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident
2897 function customIdent(token) {
2898 if (token === null || token.type !== TYPE$5.Ident) {
2899 return 0;
2900 }
2901
2902 var name = token.value.toLowerCase();
2903
2904 // The CSS-wide keywords are not valid <custom-ident>s
2905 if (eqStrAny(name, cssWideKeywords)) {
2906 return 0;
2907 }
2908
2909 // The default keyword is reserved and is also not a valid <custom-ident>
2910 if (eqStr(name, 'default')) {
2911 return 0;
2912 }
2913
2914 // TODO: ignore property specific keywords (as described https://developer.mozilla.org/en-US/docs/Web/CSS/custom-ident)
2915 // Specifications using <custom-ident> must specify clearly what other keywords
2916 // are excluded from <custom-ident>, if any—for example by saying that any pre-defined keywords
2917 // in that property’s value definition are excluded. Excluded keywords are excluded
2918 // in all ASCII case permutations.
2919
2920 return 1;
2921 }
2922
2923 // https://drafts.csswg.org/css-variables/#typedef-custom-property-name
2924 // A custom property is any property whose name starts with two dashes (U+002D HYPHEN-MINUS), like --foo.
2925 // The <custom-property-name> production corresponds to this: it’s defined as any valid identifier
2926 // that starts with two dashes, except -- itself, which is reserved for future use by CSS.
2927 // NOTE: Current implementation treat `--` as a valid name since most (all?) major browsers treat it as valid.
2928 function customPropertyName(token) {
2929 // ... defined as any valid identifier
2930 if (token === null || token.type !== TYPE$5.Ident) {
2931 return 0;
2932 }
2933
2934 // ... that starts with two dashes (U+002D HYPHEN-MINUS)
2935 if (charCode(token.value, 0) !== 0x002D || charCode(token.value, 1) !== 0x002D) {
2936 return 0;
2937 }
2938
2939 return 1;
2940 }
2941
2942 // https://drafts.csswg.org/css-color-4/#hex-notation
2943 // The syntax of a <hex-color> is a <hash-token> token whose value consists of 3, 4, 6, or 8 hexadecimal digits.
2944 // In other words, a hex color is written as a hash character, "#", followed by some number of digits 0-9 or
2945 // letters a-f (the case of the letters doesn’t matter - #00ff00 is identical to #00FF00).
2946 function hexColor(token) {
2947 if (token === null || token.type !== TYPE$5.Hash) {
2948 return 0;
2949 }
2950
2951 var length = token.value.length;
2952
2953 // valid values (length): #rgb (4), #rgba (5), #rrggbb (7), #rrggbbaa (9)
2954 if (length !== 4 && length !== 5 && length !== 7 && length !== 9) {
2955 return 0;
2956 }
2957
2958 for (var i = 1; i < length; i++) {
2959 if (!isHexDigit$3(token.value.charCodeAt(i))) {
2960 return 0;
2961 }
2962 }
2963
2964 return 1;
2965 }
2966
2967 function idSelector(token) {
2968 if (token === null || token.type !== TYPE$5.Hash) {
2969 return 0;
2970 }
2971
2972 if (!isIdentifierStart$2(charCode(token.value, 1), charCode(token.value, 2), charCode(token.value, 3))) {
2973 return 0;
2974 }
2975
2976 return 1;
2977 }
2978
2979 // https://drafts.csswg.org/css-syntax/#any-value
2980 // It represents the entirety of what a valid declaration can have as its value.
2981 function declarationValue(token, getNextToken) {
2982 if (!token) {
2983 return 0;
2984 }
2985
2986 var length = 0;
2987 var level = 0;
2988 var startIdx = token.index;
2989
2990 // The <declaration-value> production matches any sequence of one or more tokens,
2991 // so long as the sequence ...
2992 scan:
2993 do {
2994 switch (token.type) {
2995 // ... does not contain <bad-string-token>, <bad-url-token>,
2996 case TYPE$5.BadString:
2997 case TYPE$5.BadUrl:
2998 break scan;
2999
3000 // ... unmatched <)-token>, <]-token>, or <}-token>,
3001 case TYPE$5.RightCurlyBracket:
3002 case TYPE$5.RightParenthesis:
3003 case TYPE$5.RightSquareBracket:
3004 if (token.balance > token.index || token.balance < startIdx) {
3005 break scan;
3006 }
3007
3008 level--;
3009 break;
3010
3011 // ... or top-level <semicolon-token> tokens
3012 case TYPE$5.Semicolon:
3013 if (level === 0) {
3014 break scan;
3015 }
3016
3017 break;
3018
3019 // ... or <delim-token> tokens with a value of "!"
3020 case TYPE$5.Delim:
3021 if (token.value === '!' && level === 0) {
3022 break scan;
3023 }
3024
3025 break;
3026
3027 case TYPE$5.Function:
3028 case TYPE$5.LeftParenthesis:
3029 case TYPE$5.LeftSquareBracket:
3030 case TYPE$5.LeftCurlyBracket:
3031 level++;
3032 break;
3033 }
3034
3035 length++;
3036
3037 // until balance closing
3038 if (token.balance <= startIdx) {
3039 break;
3040 }
3041 } while (token = getNextToken(length));
3042
3043 return length;
3044 }
3045
3046 // https://drafts.csswg.org/css-syntax/#any-value
3047 // The <any-value> production is identical to <declaration-value>, but also
3048 // allows top-level <semicolon-token> tokens and <delim-token> tokens
3049 // with a value of "!". It represents the entirety of what valid CSS can be in any context.
3050 function anyValue(token, getNextToken) {
3051 if (!token) {
3052 return 0;
3053 }
3054
3055 var startIdx = token.index;
3056 var length = 0;
3057
3058 // The <any-value> production matches any sequence of one or more tokens,
3059 // so long as the sequence ...
3060 scan:
3061 do {
3062 switch (token.type) {
3063 // ... does not contain <bad-string-token>, <bad-url-token>,
3064 case TYPE$5.BadString:
3065 case TYPE$5.BadUrl:
3066 break scan;
3067
3068 // ... unmatched <)-token>, <]-token>, or <}-token>,
3069 case TYPE$5.RightCurlyBracket:
3070 case TYPE$5.RightParenthesis:
3071 case TYPE$5.RightSquareBracket:
3072 if (token.balance > token.index || token.balance < startIdx) {
3073 break scan;
3074 }
3075
3076 break;
3077 }
3078
3079 length++;
3080
3081 // until balance closing
3082 if (token.balance <= startIdx) {
3083 break;
3084 }
3085 } while (token = getNextToken(length));
3086
3087 return length;
3088 }
3089
3090 // =========================
3091 // Dimensions
3092 //
3093
3094 function dimension(type) {
3095 return function(token, getNextToken, opts) {
3096 if (token === null || token.type !== TYPE$5.Dimension) {
3097 return 0;
3098 }
3099
3100 var numberEnd = consumeNumber$2(token.value, 0);
3101
3102 // check unit
3103 if (type !== null) {
3104 // check for IE postfix hack, i.e. 123px\0 or 123px\9
3105 var reverseSolidusOffset = token.value.indexOf('\\', numberEnd);
3106 var unit = reverseSolidusOffset === -1 || !isPostfixIeHack(token.value, reverseSolidusOffset)
3107 ? token.value.substr(numberEnd)
3108 : token.value.substring(numberEnd, reverseSolidusOffset);
3109
3110 if (type.hasOwnProperty(unit.toLowerCase()) === false) {
3111 return 0;
3112 }
3113 }
3114
3115 // check range if specified
3116 if (outOfRange(opts, token.value, numberEnd)) {
3117 return 0;
3118 }
3119
3120 return 1;
3121 };
3122 }
3123
3124 // =========================
3125 // Percentage
3126 //
3127
3128 // §5.5. Percentages: the <percentage> type
3129 // https://drafts.csswg.org/css-values-4/#percentages
3130 function percentage(token, getNextToken, opts) {
3131 // ... corresponds to the <percentage-token> production
3132 if (token === null || token.type !== TYPE$5.Percentage) {
3133 return 0;
3134 }
3135
3136 // check range if specified
3137 if (outOfRange(opts, token.value, token.value.length - 1)) {
3138 return 0;
3139 }
3140
3141 return 1;
3142 }
3143
3144 // =========================
3145 // Numeric
3146 //
3147
3148 // https://drafts.csswg.org/css-values-4/#numbers
3149 // The value <zero> represents a literal number with the value 0. Expressions that merely
3150 // evaluate to a <number> with the value 0 (for example, calc(0)) do not match <zero>;
3151 // only literal <number-token>s do.
3152 function zero(next) {
3153 if (typeof next !== 'function') {
3154 next = function() {
3155 return 0;
3156 };
3157 }
3158
3159 return function(token, getNextToken, opts) {
3160 if (token !== null && token.type === TYPE$5.Number) {
3161 if (Number(token.value) === 0) {
3162 return 1;
3163 }
3164 }
3165
3166 return next(token, getNextToken, opts);
3167 };
3168 }
3169
3170 // § 5.3. Real Numbers: the <number> type
3171 // https://drafts.csswg.org/css-values-4/#numbers
3172 // Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.
3173 // ... It corresponds to the <number-token> production
3174 function number(token, getNextToken, opts) {
3175 if (token === null) {
3176 return 0;
3177 }
3178
3179 var numberEnd = consumeNumber$2(token.value, 0);
3180 var isNumber = numberEnd === token.value.length;
3181 if (!isNumber && !isPostfixIeHack(token.value, numberEnd)) {
3182 return 0;
3183 }
3184
3185 // check range if specified
3186 if (outOfRange(opts, token.value, numberEnd)) {
3187 return 0;
3188 }
3189
3190 return 1;
3191 }
3192
3193 // §5.2. Integers: the <integer> type
3194 // https://drafts.csswg.org/css-values-4/#integers
3195 function integer(token, getNextToken, opts) {
3196 // ... corresponds to a subset of the <number-token> production
3197 if (token === null || token.type !== TYPE$5.Number) {
3198 return 0;
3199 }
3200
3201 // The first digit of an integer may be immediately preceded by `-` or `+` to indicate the integer’s sign.
3202 var i = token.value.charCodeAt(0) === 0x002B || // U+002B PLUS SIGN (+)
3203 token.value.charCodeAt(0) === 0x002D ? 1 : 0; // U+002D HYPHEN-MINUS (-)
3204
3205 // When written literally, an integer is one or more decimal digits 0 through 9 ...
3206 for (; i < token.value.length; i++) {
3207 if (!isDigit$3(token.value.charCodeAt(i))) {
3208 return 0;
3209 }
3210 }
3211
3212 // check range if specified
3213 if (outOfRange(opts, token.value, i)) {
3214 return 0;
3215 }
3216
3217 return 1;
3218 }
3219
3220 var generic = {
3221 // token types
3222 'ident-token': tokenType(TYPE$5.Ident),
3223 'function-token': tokenType(TYPE$5.Function),
3224 'at-keyword-token': tokenType(TYPE$5.AtKeyword),
3225 'hash-token': tokenType(TYPE$5.Hash),
3226 'string-token': tokenType(TYPE$5.String),
3227 'bad-string-token': tokenType(TYPE$5.BadString),
3228 'url-token': tokenType(TYPE$5.Url),
3229 'bad-url-token': tokenType(TYPE$5.BadUrl),
3230 'delim-token': tokenType(TYPE$5.Delim),
3231 'number-token': tokenType(TYPE$5.Number),
3232 'percentage-token': tokenType(TYPE$5.Percentage),
3233 'dimension-token': tokenType(TYPE$5.Dimension),
3234 'whitespace-token': tokenType(TYPE$5.WhiteSpace),
3235 'CDO-token': tokenType(TYPE$5.CDO),
3236 'CDC-token': tokenType(TYPE$5.CDC),
3237 'colon-token': tokenType(TYPE$5.Colon),
3238 'semicolon-token': tokenType(TYPE$5.Semicolon),
3239 'comma-token': tokenType(TYPE$5.Comma),
3240 '[-token': tokenType(TYPE$5.LeftSquareBracket),
3241 ']-token': tokenType(TYPE$5.RightSquareBracket),
3242 '(-token': tokenType(TYPE$5.LeftParenthesis),
3243 ')-token': tokenType(TYPE$5.RightParenthesis),
3244 '{-token': tokenType(TYPE$5.LeftCurlyBracket),
3245 '}-token': tokenType(TYPE$5.RightCurlyBracket),
3246
3247 // token type aliases
3248 'string': tokenType(TYPE$5.String),
3249 'ident': tokenType(TYPE$5.Ident),
3250
3251 // complex types
3252 'custom-ident': customIdent,
3253 'custom-property-name': customPropertyName,
3254 'hex-color': hexColor,
3255 'id-selector': idSelector, // element( <id-selector> )
3256 'an-plus-b': genericAnPlusB,
3257 'urange': genericUrange,
3258 'declaration-value': declarationValue,
3259 'any-value': anyValue,
3260
3261 // dimensions
3262 'dimension': calc(dimension(null)),
3263 'angle': calc(dimension(ANGLE)),
3264 'decibel': calc(dimension(DECIBEL)),
3265 'frequency': calc(dimension(FREQUENCY)),
3266 'flex': calc(dimension(FLEX)),
3267 'length': calc(zero(dimension(LENGTH))),
3268 'resolution': calc(dimension(RESOLUTION)),
3269 'semitones': calc(dimension(SEMITONES)),
3270 'time': calc(dimension(TIME)),
3271
3272 // percentage
3273 'percentage': calc(percentage),
3274
3275 // numeric
3276 'zero': zero(),
3277 'number': calc(number),
3278 'integer': calc(integer),
3279
3280 // old IE stuff
3281 '-ms-legacy-expression': func('expression')
3282 };
3283
3284 var _SyntaxError$1 = function SyntaxError(message, input, offset) {
3285 var error = createCustomError('SyntaxError', message);
3286
3287 error.input = input;
3288 error.offset = offset;
3289 error.rawMessage = message;
3290 error.message = error.rawMessage + '\n' +
3291 ' ' + error.input + '\n' +
3292 '--' + new Array((error.offset || error.input.length) + 1).join('-') + '^';
3293
3294 return error;
3295 };
3296
3297 var TAB = 9;
3298 var N$1 = 10;
3299 var F = 12;
3300 var R = 13;
3301 var SPACE = 32;
3302
3303 var Tokenizer = function(str) {
3304 this.str = str;
3305 this.pos = 0;
3306 };
3307
3308 Tokenizer.prototype = {
3309 charCodeAt: function(pos) {
3310 return pos < this.str.length ? this.str.charCodeAt(pos) : 0;
3311 },
3312 charCode: function() {
3313 return this.charCodeAt(this.pos);
3314 },
3315 nextCharCode: function() {
3316 return this.charCodeAt(this.pos + 1);
3317 },
3318 nextNonWsCode: function(pos) {
3319 return this.charCodeAt(this.findWsEnd(pos));
3320 },
3321 findWsEnd: function(pos) {
3322 for (; pos < this.str.length; pos++) {
3323 var code = this.str.charCodeAt(pos);
3324 if (code !== R && code !== N$1 && code !== F && code !== SPACE && code !== TAB) {
3325 break;
3326 }
3327 }
3328
3329 return pos;
3330 },
3331 substringToPos: function(end) {
3332 return this.str.substring(this.pos, this.pos = end);
3333 },
3334 eat: function(code) {
3335 if (this.charCode() !== code) {
3336 this.error('Expect `' + String.fromCharCode(code) + '`');
3337 }
3338
3339 this.pos++;
3340 },
3341 peek: function() {
3342 return this.pos < this.str.length ? this.str.charAt(this.pos++) : '';
3343 },
3344 error: function(message) {
3345 throw new _SyntaxError$1(message, this.str, this.pos);
3346 }
3347 };
3348
3349 var tokenizer$1 = Tokenizer;
3350
3351 var TAB$1 = 9;
3352 var N$2 = 10;
3353 var F$1 = 12;
3354 var R$1 = 13;
3355 var SPACE$1 = 32;
3356 var EXCLAMATIONMARK = 33; // !
3357 var NUMBERSIGN = 35; // #
3358 var AMPERSAND = 38; // &
3359 var APOSTROPHE = 39; // '
3360 var LEFTPARENTHESIS = 40; // (
3361 var RIGHTPARENTHESIS = 41; // )
3362 var ASTERISK = 42; // *
3363 var PLUSSIGN$2 = 43; // +
3364 var COMMA = 44; // ,
3365 var HYPERMINUS = 45; // -
3366 var LESSTHANSIGN = 60; // <
3367 var GREATERTHANSIGN = 62; // >
3368 var QUESTIONMARK$1 = 63; // ?
3369 var COMMERCIALAT = 64; // @
3370 var LEFTSQUAREBRACKET = 91; // [
3371 var RIGHTSQUAREBRACKET = 93; // ]
3372 var LEFTCURLYBRACKET = 123; // {
3373 var VERTICALLINE = 124; // |
3374 var RIGHTCURLYBRACKET = 125; // }
3375 var INFINITY = 8734; // ∞
3376 var NAME_CHAR = createCharMap(function(ch) {
3377 return /[a-zA-Z0-9\-]/.test(ch);
3378 });
3379 var COMBINATOR_PRECEDENCE = {
3380 ' ': 1,
3381 '&&': 2,
3382 '||': 3,
3383 '|': 4
3384 };
3385
3386 function createCharMap(fn) {
3387 var array = typeof Uint32Array === 'function' ? new Uint32Array(128) : new Array(128);
3388 for (var i = 0; i < 128; i++) {
3389 array[i] = fn(String.fromCharCode(i)) ? 1 : 0;
3390 }
3391 return array;
3392 }
3393
3394 function scanSpaces(tokenizer) {
3395 return tokenizer.substringToPos(
3396 tokenizer.findWsEnd(tokenizer.pos)
3397 );
3398 }
3399
3400 function scanWord(tokenizer) {
3401 var end = tokenizer.pos;
3402
3403 for (; end < tokenizer.str.length; end++) {
3404 var code = tokenizer.str.charCodeAt(end);
3405 if (code >= 128 || NAME_CHAR[code] === 0) {
3406 break;
3407 }
3408 }
3409
3410 if (tokenizer.pos === end) {
3411 tokenizer.error('Expect a keyword');
3412 }
3413
3414 return tokenizer.substringToPos(end);
3415 }
3416
3417 function scanNumber(tokenizer) {
3418 var end = tokenizer.pos;
3419
3420 for (; end < tokenizer.str.length; end++) {
3421 var code = tokenizer.str.charCodeAt(end);
3422 if (code < 48 || code > 57) {
3423 break;
3424 }
3425 }
3426
3427 if (tokenizer.pos === end) {
3428 tokenizer.error('Expect a number');
3429 }
3430
3431 return tokenizer.substringToPos(end);
3432 }
3433
3434 function scanString(tokenizer) {
3435 var end = tokenizer.str.indexOf('\'', tokenizer.pos + 1);
3436
3437 if (end === -1) {
3438 tokenizer.pos = tokenizer.str.length;
3439 tokenizer.error('Expect an apostrophe');
3440 }
3441
3442 return tokenizer.substringToPos(end + 1);
3443 }
3444
3445 function readMultiplierRange(tokenizer) {
3446 var min = null;
3447 var max = null;
3448
3449 tokenizer.eat(LEFTCURLYBRACKET);
3450
3451 min = scanNumber(tokenizer);
3452
3453 if (tokenizer.charCode() === COMMA) {
3454 tokenizer.pos++;
3455 if (tokenizer.charCode() !== RIGHTCURLYBRACKET) {
3456 max = scanNumber(tokenizer);
3457 }
3458 } else {
3459 max = min;
3460 }
3461
3462 tokenizer.eat(RIGHTCURLYBRACKET);
3463
3464 return {
3465 min: Number(min),
3466 max: max ? Number(max) : 0
3467 };
3468 }
3469
3470 function readMultiplier(tokenizer) {
3471 var range = null;
3472 var comma = false;
3473
3474 switch (tokenizer.charCode()) {
3475 case ASTERISK:
3476 tokenizer.pos++;
3477
3478 range = {
3479 min: 0,
3480 max: 0
3481 };
3482
3483 break;
3484
3485 case PLUSSIGN$2:
3486 tokenizer.pos++;
3487
3488 range = {
3489 min: 1,
3490 max: 0
3491 };
3492
3493 break;
3494
3495 case QUESTIONMARK$1:
3496 tokenizer.pos++;
3497
3498 range = {
3499 min: 0,
3500 max: 1
3501 };
3502
3503 break;
3504
3505 case NUMBERSIGN:
3506 tokenizer.pos++;
3507
3508 comma = true;
3509
3510 if (tokenizer.charCode() === LEFTCURLYBRACKET) {
3511 range = readMultiplierRange(tokenizer);
3512 } else {
3513 range = {
3514 min: 1,
3515 max: 0
3516 };
3517 }
3518
3519 break;
3520
3521 case LEFTCURLYBRACKET:
3522 range = readMultiplierRange(tokenizer);
3523 break;
3524
3525 default:
3526 return null;
3527 }
3528
3529 return {
3530 type: 'Multiplier',
3531 comma: comma,
3532 min: range.min,
3533 max: range.max,
3534 term: null
3535 };
3536 }
3537
3538 function maybeMultiplied(tokenizer, node) {
3539 var multiplier = readMultiplier(tokenizer);
3540
3541 if (multiplier !== null) {
3542 multiplier.term = node;
3543 return multiplier;
3544 }
3545
3546 return node;
3547 }
3548
3549 function maybeToken(tokenizer) {
3550 var ch = tokenizer.peek();
3551
3552 if (ch === '') {
3553 return null;
3554 }
3555
3556 return {
3557 type: 'Token',
3558 value: ch
3559 };
3560 }
3561
3562 function readProperty(tokenizer) {
3563 var name;
3564
3565 tokenizer.eat(LESSTHANSIGN);
3566 tokenizer.eat(APOSTROPHE);
3567
3568 name = scanWord(tokenizer);
3569
3570 tokenizer.eat(APOSTROPHE);
3571 tokenizer.eat(GREATERTHANSIGN);
3572
3573 return maybeMultiplied(tokenizer, {
3574 type: 'Property',
3575 name: name
3576 });
3577 }
3578
3579 // https://drafts.csswg.org/css-values-3/#numeric-ranges
3580 // 4.1. Range Restrictions and Range Definition Notation
3581 //
3582 // Range restrictions can be annotated in the numeric type notation using CSS bracketed
3583 // range notation—[min,max]—within the angle brackets, after the identifying keyword,
3584 // indicating a closed range between (and including) min and max.
3585 // For example, <integer [0, 10]> indicates an integer between 0 and 10, inclusive.
3586 function readTypeRange(tokenizer) {
3587 // use null for Infinity to make AST format JSON serializable/deserializable
3588 var min = null; // -Infinity
3589 var max = null; // Infinity
3590 var sign = 1;
3591
3592 tokenizer.eat(LEFTSQUAREBRACKET);
3593
3594 if (tokenizer.charCode() === HYPERMINUS) {
3595 tokenizer.peek();
3596 sign = -1;
3597 }
3598
3599 if (sign == -1 && tokenizer.charCode() === INFINITY) {
3600 tokenizer.peek();
3601 } else {
3602 min = sign * Number(scanNumber(tokenizer));
3603 }
3604
3605 scanSpaces(tokenizer);
3606 tokenizer.eat(COMMA);
3607 scanSpaces(tokenizer);
3608
3609 if (tokenizer.charCode() === INFINITY) {
3610 tokenizer.peek();
3611 } else {
3612 sign = 1;
3613
3614 if (tokenizer.charCode() === HYPERMINUS) {
3615 tokenizer.peek();
3616 sign = -1;
3617 }
3618
3619 max = sign * Number(scanNumber(tokenizer));
3620 }
3621
3622 tokenizer.eat(RIGHTSQUAREBRACKET);
3623
3624 // If no range is indicated, either by using the bracketed range notation
3625 // or in the property description, then [−∞,∞] is assumed.
3626 if (min === null && max === null) {
3627 return null;
3628 }
3629
3630 return {
3631 type: 'Range',
3632 min: min,
3633 max: max
3634 };
3635 }
3636
3637 function readType(tokenizer) {
3638 var name;
3639 var opts = null;
3640
3641 tokenizer.eat(LESSTHANSIGN);
3642 name = scanWord(tokenizer);
3643
3644 if (tokenizer.charCode() === LEFTPARENTHESIS &&
3645 tokenizer.nextCharCode() === RIGHTPARENTHESIS) {
3646 tokenizer.pos += 2;
3647 name += '()';
3648 }
3649
3650 if (tokenizer.charCodeAt(tokenizer.findWsEnd(tokenizer.pos)) === LEFTSQUAREBRACKET) {
3651 scanSpaces(tokenizer);
3652 opts = readTypeRange(tokenizer);
3653 }
3654
3655 tokenizer.eat(GREATERTHANSIGN);
3656
3657 return maybeMultiplied(tokenizer, {
3658 type: 'Type',
3659 name: name,
3660 opts: opts
3661 });
3662 }
3663
3664 function readKeywordOrFunction(tokenizer) {
3665 var name;
3666
3667 name = scanWord(tokenizer);
3668
3669 if (tokenizer.charCode() === LEFTPARENTHESIS) {
3670 tokenizer.pos++;
3671
3672 return {
3673 type: 'Function',
3674 name: name
3675 };
3676 }
3677
3678 return maybeMultiplied(tokenizer, {
3679 type: 'Keyword',
3680 name: name
3681 });
3682 }
3683
3684 function regroupTerms(terms, combinators) {
3685 function createGroup(terms, combinator) {
3686 return {
3687 type: 'Group',
3688 terms: terms,
3689 combinator: combinator,
3690 disallowEmpty: false,
3691 explicit: false
3692 };
3693 }
3694
3695 combinators = Object.keys(combinators).sort(function(a, b) {
3696 return COMBINATOR_PRECEDENCE[a] - COMBINATOR_PRECEDENCE[b];
3697 });
3698
3699 while (combinators.length > 0) {
3700 var combinator = combinators.shift();
3701 for (var i = 0, subgroupStart = 0; i < terms.length; i++) {
3702 var term = terms[i];
3703 if (term.type === 'Combinator') {
3704 if (term.value === combinator) {
3705 if (subgroupStart === -1) {
3706 subgroupStart = i - 1;
3707 }
3708 terms.splice(i, 1);
3709 i--;
3710 } else {
3711 if (subgroupStart !== -1 && i - subgroupStart > 1) {
3712 terms.splice(
3713 subgroupStart,
3714 i - subgroupStart,
3715 createGroup(terms.slice(subgroupStart, i), combinator)
3716 );
3717 i = subgroupStart + 1;
3718 }
3719 subgroupStart = -1;
3720 }
3721 }
3722 }
3723
3724 if (subgroupStart !== -1 && combinators.length) {
3725 terms.splice(
3726 subgroupStart,
3727 i - subgroupStart,
3728 createGroup(terms.slice(subgroupStart, i), combinator)
3729 );
3730 }
3731 }
3732
3733 return combinator;
3734 }
3735
3736 function readImplicitGroup(tokenizer) {
3737 var terms = [];
3738 var combinators = {};
3739 var token;
3740 var prevToken = null;
3741 var prevTokenPos = tokenizer.pos;
3742
3743 while (token = peek(tokenizer)) {
3744 if (token.type !== 'Spaces') {
3745 if (token.type === 'Combinator') {
3746 // check for combinator in group beginning and double combinator sequence
3747 if (prevToken === null || prevToken.type === 'Combinator') {
3748 tokenizer.pos = prevTokenPos;
3749 tokenizer.error('Unexpected combinator');
3750 }
3751
3752 combinators[token.value] = true;
3753 } else if (prevToken !== null && prevToken.type !== 'Combinator') {
3754 combinators[' '] = true; // a b
3755 terms.push({
3756 type: 'Combinator',
3757 value: ' '
3758 });
3759 }
3760
3761 terms.push(token);
3762 prevToken = token;
3763 prevTokenPos = tokenizer.pos;
3764 }
3765 }
3766
3767 // check for combinator in group ending
3768 if (prevToken !== null && prevToken.type === 'Combinator') {
3769 tokenizer.pos -= prevTokenPos;
3770 tokenizer.error('Unexpected combinator');
3771 }
3772
3773 return {
3774 type: 'Group',
3775 terms: terms,
3776 combinator: regroupTerms(terms, combinators) || ' ',
3777 disallowEmpty: false,
3778 explicit: false
3779 };
3780 }
3781
3782 function readGroup(tokenizer) {
3783 var result;
3784
3785 tokenizer.eat(LEFTSQUAREBRACKET);
3786 result = readImplicitGroup(tokenizer);
3787 tokenizer.eat(RIGHTSQUAREBRACKET);
3788
3789 result.explicit = true;
3790
3791 if (tokenizer.charCode() === EXCLAMATIONMARK) {
3792 tokenizer.pos++;
3793 result.disallowEmpty = true;
3794 }
3795
3796 return result;
3797 }
3798
3799 function peek(tokenizer) {
3800 var code = tokenizer.charCode();
3801
3802 if (code < 128 && NAME_CHAR[code] === 1) {
3803 return readKeywordOrFunction(tokenizer);
3804 }
3805
3806 switch (code) {
3807 case RIGHTSQUAREBRACKET:
3808 // don't eat, stop scan a group
3809 break;
3810
3811 case LEFTSQUAREBRACKET:
3812 return maybeMultiplied(tokenizer, readGroup(tokenizer));
3813
3814 case LESSTHANSIGN:
3815 return tokenizer.nextCharCode() === APOSTROPHE
3816 ? readProperty(tokenizer)
3817 : readType(tokenizer);
3818
3819 case VERTICALLINE:
3820 return {
3821 type: 'Combinator',
3822 value: tokenizer.substringToPos(
3823 tokenizer.nextCharCode() === VERTICALLINE
3824 ? tokenizer.pos + 2
3825 : tokenizer.pos + 1
3826 )
3827 };
3828
3829 case AMPERSAND:
3830 tokenizer.pos++;
3831 tokenizer.eat(AMPERSAND);
3832
3833 return {
3834 type: 'Combinator',
3835 value: '&&'
3836 };
3837
3838 case COMMA:
3839 tokenizer.pos++;
3840 return {
3841 type: 'Comma'
3842 };
3843
3844 case APOSTROPHE:
3845 return maybeMultiplied(tokenizer, {
3846 type: 'String',
3847 value: scanString(tokenizer)
3848 });
3849
3850 case SPACE$1:
3851 case TAB$1:
3852 case N$2:
3853 case R$1:
3854 case F$1:
3855 return {
3856 type: 'Spaces',
3857 value: scanSpaces(tokenizer)
3858 };
3859
3860 case COMMERCIALAT:
3861 code = tokenizer.nextCharCode();
3862
3863 if (code < 128 && NAME_CHAR[code] === 1) {
3864 tokenizer.pos++;
3865 return {
3866 type: 'AtKeyword',
3867 name: scanWord(tokenizer)
3868 };
3869 }
3870
3871 return maybeToken(tokenizer);
3872
3873 case ASTERISK:
3874 case PLUSSIGN$2:
3875 case QUESTIONMARK$1:
3876 case NUMBERSIGN:
3877 case EXCLAMATIONMARK:
3878 // prohibited tokens (used as a multiplier start)
3879 break;
3880
3881 case LEFTCURLYBRACKET:
3882 // LEFTCURLYBRACKET is allowed since mdn/data uses it w/o quoting
3883 // check next char isn't a number, because it's likely a disjoined multiplier
3884 code = tokenizer.nextCharCode();
3885
3886 if (code < 48 || code > 57) {
3887 return maybeToken(tokenizer);
3888 }
3889
3890 break;
3891
3892 default:
3893 return maybeToken(tokenizer);
3894 }
3895 }
3896
3897 function parse(source) {
3898 var tokenizer = new tokenizer$1(source);
3899 var result = readImplicitGroup(tokenizer);
3900
3901 if (tokenizer.pos !== source.length) {
3902 tokenizer.error('Unexpected input');
3903 }
3904
3905 // reduce redundant groups with single group term
3906 if (result.terms.length === 1 && result.terms[0].type === 'Group') {
3907 result = result.terms[0];
3908 }
3909
3910 return result;
3911 }
3912
3913 // warm up parse to elimitate code branches that never execute
3914 // fix soft deoptimizations (insufficient type feedback)
3915 parse('[a&&<b>#|<\'c\'>*||e() f{2} /,(% g#{1,2} h{2,})]!');
3916
3917 var parse_1 = parse;
3918
3919 var noop$1 = function() {};
3920
3921 function ensureFunction(value) {
3922 return typeof value === 'function' ? value : noop$1;
3923 }
3924
3925 var walk = function(node, options, context) {
3926 function walk(node) {
3927 enter.call(context, node);
3928
3929 switch (node.type) {
3930 case 'Group':
3931 node.terms.forEach(walk);
3932 break;
3933
3934 case 'Multiplier':
3935 walk(node.term);
3936 break;
3937
3938 case 'Type':
3939 case 'Property':
3940 case 'Keyword':
3941 case 'AtKeyword':
3942 case 'Function':
3943 case 'String':
3944 case 'Token':
3945 case 'Comma':
3946 break;
3947
3948 default:
3949 throw new Error('Unknown type: ' + node.type);
3950 }
3951
3952 leave.call(context, node);
3953 }
3954
3955 var enter = noop$1;
3956 var leave = noop$1;
3957
3958 if (typeof options === 'function') {
3959 enter = options;
3960 } else if (options) {
3961 enter = ensureFunction(options.enter);
3962 leave = ensureFunction(options.leave);
3963 }
3964
3965 if (enter === noop$1 && leave === noop$1) {
3966 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
3967 }
3968
3969 walk(node);
3970 };
3971
3972 var tokenStream = new TokenStream_1();
3973 var astToTokens = {
3974 decorator: function(handlers) {
3975 var curNode = null;
3976 var prev = { len: 0, node: null };
3977 var nodes = [prev];
3978 var buffer = '';
3979
3980 return {
3981 children: handlers.children,
3982 node: function(node) {
3983 var tmp = curNode;
3984 curNode = node;
3985 handlers.node.call(this, node);
3986 curNode = tmp;
3987 },
3988 chunk: function(chunk) {
3989 buffer += chunk;
3990 if (prev.node !== curNode) {
3991 nodes.push({
3992 len: chunk.length,
3993 node: curNode
3994 });
3995 } else {
3996 prev.len += chunk.length;
3997 }
3998 },
3999 result: function() {
4000 return prepareTokens(buffer, nodes);
4001 }
4002 };
4003 }
4004 };
4005
4006 function prepareTokens(str, nodes) {
4007 var tokens = [];
4008 var nodesOffset = 0;
4009 var nodesIndex = 0;
4010 var currentNode = nodes ? nodes[nodesIndex].node : null;
4011
4012 tokenizer(str, tokenStream);
4013
4014 while (!tokenStream.eof) {
4015 if (nodes) {
4016 while (nodesIndex < nodes.length && nodesOffset + nodes[nodesIndex].len <= tokenStream.tokenStart) {
4017 nodesOffset += nodes[nodesIndex++].len;
4018 currentNode = nodes[nodesIndex].node;
4019 }
4020 }
4021
4022 tokens.push({
4023 type: tokenStream.tokenType,
4024 value: tokenStream.getTokenValue(),
4025 index: tokenStream.tokenIndex, // TODO: remove it, temporary solution
4026 balance: tokenStream.balance[tokenStream.tokenIndex], // TODO: remove it, temporary solution
4027 node: currentNode
4028 });
4029 tokenStream.next();
4030 // console.log({ ...tokens[tokens.length - 1], node: undefined });
4031 }
4032
4033 return tokens;
4034 }
4035
4036 var prepareTokens_1 = function(value, syntax) {
4037 if (typeof value === 'string') {
4038 return prepareTokens(value, null);
4039 }
4040
4041 return syntax.generate(value, astToTokens);
4042 };
4043
4044 var MATCH = { type: 'Match' };
4045 var MISMATCH = { type: 'Mismatch' };
4046 var DISALLOW_EMPTY = { type: 'DisallowEmpty' };
4047 var LEFTPARENTHESIS$1 = 40; // (
4048 var RIGHTPARENTHESIS$1 = 41; // )
4049
4050 function createCondition(match, thenBranch, elseBranch) {
4051 // reduce node count
4052 if (thenBranch === MATCH && elseBranch === MISMATCH) {
4053 return match;
4054 }
4055
4056 if (match === MATCH && thenBranch === MATCH && elseBranch === MATCH) {
4057 return match;
4058 }
4059
4060 if (match.type === 'If' && match.else === MISMATCH && thenBranch === MATCH) {
4061 thenBranch = match.then;
4062 match = match.match;
4063 }
4064
4065 return {
4066 type: 'If',
4067 match: match,
4068 then: thenBranch,
4069 else: elseBranch
4070 };
4071 }
4072
4073 function isFunctionType(name) {
4074 return (
4075 name.length > 2 &&
4076 name.charCodeAt(name.length - 2) === LEFTPARENTHESIS$1 &&
4077 name.charCodeAt(name.length - 1) === RIGHTPARENTHESIS$1
4078 );
4079 }
4080
4081 function isEnumCapatible(term) {
4082 return (
4083 term.type === 'Keyword' ||
4084 term.type === 'AtKeyword' ||
4085 term.type === 'Function' ||
4086 term.type === 'Type' && isFunctionType(term.name)
4087 );
4088 }
4089
4090 function buildGroupMatchGraph(combinator, terms, atLeastOneTermMatched) {
4091 switch (combinator) {
4092 case ' ':
4093 // Juxtaposing components means that all of them must occur, in the given order.
4094 //
4095 // a b c
4096 // =
4097 // match a
4098 // then match b
4099 // then match c
4100 // then MATCH
4101 // else MISMATCH
4102 // else MISMATCH
4103 // else MISMATCH
4104 var result = MATCH;
4105
4106 for (var i = terms.length - 1; i >= 0; i--) {
4107 var term = terms[i];
4108
4109 result = createCondition(
4110 term,
4111 result,
4112 MISMATCH
4113 );
4114 }
4115 return result;
4116
4117 case '|':
4118 // A bar (|) separates two or more alternatives: exactly one of them must occur.
4119 //
4120 // a | b | c
4121 // =
4122 // match a
4123 // then MATCH
4124 // else match b
4125 // then MATCH
4126 // else match c
4127 // then MATCH
4128 // else MISMATCH
4129
4130 var result = MISMATCH;
4131 var map = null;
4132
4133 for (var i = terms.length - 1; i >= 0; i--) {
4134 var term = terms[i];
4135
4136 // reduce sequence of keywords into a Enum
4137 if (isEnumCapatible(term)) {
4138 if (map === null && i > 0 && isEnumCapatible(terms[i - 1])) {
4139 map = Object.create(null);
4140 result = createCondition(
4141 {
4142 type: 'Enum',
4143 map: map
4144 },
4145 MATCH,
4146 result
4147 );
4148 }
4149
4150 if (map !== null) {
4151 var key = (isFunctionType(term.name) ? term.name.slice(0, -1) : term.name).toLowerCase();
4152 if (key in map === false) {
4153 map[key] = term;
4154 continue;
4155 }
4156 }
4157 }
4158
4159 map = null;
4160
4161 // create a new conditonal node
4162 result = createCondition(
4163 term,
4164 MATCH,
4165 result
4166 );
4167 }
4168 return result;
4169
4170 case '&&':
4171 // A double ampersand (&&) separates two or more components,
4172 // all of which must occur, in any order.
4173
4174 // Use MatchOnce for groups with a large number of terms,
4175 // since &&-groups produces at least N!-node trees
4176 if (terms.length > 5) {
4177 return {
4178 type: 'MatchOnce',
4179 terms: terms,
4180 all: true
4181 };
4182 }
4183
4184 // Use a combination tree for groups with small number of terms
4185 //
4186 // a && b && c
4187 // =
4188 // match a
4189 // then [b && c]
4190 // else match b
4191 // then [a && c]
4192 // else match c
4193 // then [a && b]
4194 // else MISMATCH
4195 //
4196 // a && b
4197 // =
4198 // match a
4199 // then match b
4200 // then MATCH
4201 // else MISMATCH
4202 // else match b
4203 // then match a
4204 // then MATCH
4205 // else MISMATCH
4206 // else MISMATCH
4207 var result = MISMATCH;
4208
4209 for (var i = terms.length - 1; i >= 0; i--) {
4210 var term = terms[i];
4211 var thenClause;
4212
4213 if (terms.length > 1) {
4214 thenClause = buildGroupMatchGraph(
4215 combinator,
4216 terms.filter(function(newGroupTerm) {
4217 return newGroupTerm !== term;
4218 }),
4219 false
4220 );
4221 } else {
4222 thenClause = MATCH;
4223 }
4224
4225 result = createCondition(
4226 term,
4227 thenClause,
4228 result
4229 );
4230 }
4231 return result;
4232
4233 case '||':
4234 // A double bar (||) separates two or more options:
4235 // one or more of them must occur, in any order.
4236
4237 // Use MatchOnce for groups with a large number of terms,
4238 // since ||-groups produces at least N!-node trees
4239 if (terms.length > 5) {
4240 return {
4241 type: 'MatchOnce',
4242 terms: terms,
4243 all: false
4244 };
4245 }
4246
4247 // Use a combination tree for groups with small number of terms
4248 //
4249 // a || b || c
4250 // =
4251 // match a
4252 // then [b || c]
4253 // else match b
4254 // then [a || c]
4255 // else match c
4256 // then [a || b]
4257 // else MISMATCH
4258 //
4259 // a || b
4260 // =
4261 // match a
4262 // then match b
4263 // then MATCH
4264 // else MATCH
4265 // else match b
4266 // then match a
4267 // then MATCH
4268 // else MATCH
4269 // else MISMATCH
4270 var result = atLeastOneTermMatched ? MATCH : MISMATCH;
4271
4272 for (var i = terms.length - 1; i >= 0; i--) {
4273 var term = terms[i];
4274 var thenClause;
4275
4276 if (terms.length > 1) {
4277 thenClause = buildGroupMatchGraph(
4278 combinator,
4279 terms.filter(function(newGroupTerm) {
4280 return newGroupTerm !== term;
4281 }),
4282 true
4283 );
4284 } else {
4285 thenClause = MATCH;
4286 }
4287
4288 result = createCondition(
4289 term,
4290 thenClause,
4291 result
4292 );
4293 }
4294 return result;
4295 }
4296 }
4297
4298 function buildMultiplierMatchGraph(node) {
4299 var result = MATCH;
4300 var matchTerm = buildMatchGraph(node.term);
4301
4302 if (node.max === 0) {
4303 // disable repeating of empty match to prevent infinite loop
4304 matchTerm = createCondition(
4305 matchTerm,
4306 DISALLOW_EMPTY,
4307 MISMATCH
4308 );
4309
4310 // an occurrence count is not limited, make a cycle;
4311 // to collect more terms on each following matching mismatch
4312 result = createCondition(
4313 matchTerm,
4314 null, // will be a loop
4315 MISMATCH
4316 );
4317
4318 result.then = createCondition(
4319 MATCH,
4320 MATCH,
4321 result // make a loop
4322 );
4323
4324 if (node.comma) {
4325 result.then.else = createCondition(
4326 { type: 'Comma', syntax: node },
4327 result,
4328 MISMATCH
4329 );
4330 }
4331 } else {
4332 // create a match node chain for [min .. max] interval with optional matches
4333 for (var i = node.min || 1; i <= node.max; i++) {
4334 if (node.comma && result !== MATCH) {
4335 result = createCondition(
4336 { type: 'Comma', syntax: node },
4337 result,
4338 MISMATCH
4339 );
4340 }
4341
4342 result = createCondition(
4343 matchTerm,
4344 createCondition(
4345 MATCH,
4346 MATCH,
4347 result
4348 ),
4349 MISMATCH
4350 );
4351 }
4352 }
4353
4354 if (node.min === 0) {
4355 // allow zero match
4356 result = createCondition(
4357 MATCH,
4358 MATCH,
4359 result
4360 );
4361 } else {
4362 // create a match node chain to collect [0 ... min - 1] required matches
4363 for (var i = 0; i < node.min - 1; i++) {
4364 if (node.comma && result !== MATCH) {
4365 result = createCondition(
4366 { type: 'Comma', syntax: node },
4367 result,
4368 MISMATCH
4369 );
4370 }
4371
4372 result = createCondition(
4373 matchTerm,
4374 result,
4375 MISMATCH
4376 );
4377 }
4378 }
4379
4380 return result;
4381 }
4382
4383 function buildMatchGraph(node) {
4384 if (typeof node === 'function') {
4385 return {
4386 type: 'Generic',
4387 fn: node
4388 };
4389 }
4390
4391 switch (node.type) {
4392 case 'Group':
4393 var result = buildGroupMatchGraph(
4394 node.combinator,
4395 node.terms.map(buildMatchGraph),
4396 false
4397 );
4398
4399 if (node.disallowEmpty) {
4400 result = createCondition(
4401 result,
4402 DISALLOW_EMPTY,
4403 MISMATCH
4404 );
4405 }
4406
4407 return result;
4408
4409 case 'Multiplier':
4410 return buildMultiplierMatchGraph(node);
4411
4412 case 'Type':
4413 case 'Property':
4414 return {
4415 type: node.type,
4416 name: node.name,
4417 syntax: node
4418 };
4419
4420 case 'Keyword':
4421 return {
4422 type: node.type,
4423 name: node.name.toLowerCase(),
4424 syntax: node
4425 };
4426
4427 case 'AtKeyword':
4428 return {
4429 type: node.type,
4430 name: '@' + node.name.toLowerCase(),
4431 syntax: node
4432 };
4433
4434 case 'Function':
4435 return {
4436 type: node.type,
4437 name: node.name.toLowerCase() + '(',
4438 syntax: node
4439 };
4440
4441 case 'String':
4442 // convert a one char length String to a Token
4443 if (node.value.length === 3) {
4444 return {
4445 type: 'Token',
4446 value: node.value.charAt(1),
4447 syntax: node
4448 };
4449 }
4450
4451 // otherwise use it as is
4452 return {
4453 type: node.type,
4454 value: node.value.substr(1, node.value.length - 2).replace(/\\'/g, '\''),
4455 syntax: node
4456 };
4457
4458 case 'Token':
4459 return {
4460 type: node.type,
4461 value: node.value,
4462 syntax: node
4463 };
4464
4465 case 'Comma':
4466 return {
4467 type: node.type,
4468 syntax: node
4469 };
4470
4471 default:
4472 throw new Error('Unknown node type:', node.type);
4473 }
4474 }
4475
4476 var matchGraph = {
4477 MATCH: MATCH,
4478 MISMATCH: MISMATCH,
4479 DISALLOW_EMPTY: DISALLOW_EMPTY,
4480 buildMatchGraph: function(syntaxTree, ref) {
4481 if (typeof syntaxTree === 'string') {
4482 syntaxTree = parse_1(syntaxTree);
4483 }
4484
4485 return {
4486 type: 'MatchGraph',
4487 match: buildMatchGraph(syntaxTree),
4488 syntax: ref || null,
4489 source: syntaxTree
4490 };
4491 }
4492 };
4493
4494 var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
4495
4496 var MATCH$1 = matchGraph.MATCH;
4497 var MISMATCH$1 = matchGraph.MISMATCH;
4498 var DISALLOW_EMPTY$1 = matchGraph.DISALLOW_EMPTY;
4499 var TYPE$6 = _const.TYPE;
4500
4501 var STUB = 0;
4502 var TOKEN = 1;
4503 var OPEN_SYNTAX = 2;
4504 var CLOSE_SYNTAX = 3;
4505
4506 var EXIT_REASON_MATCH = 'Match';
4507 var EXIT_REASON_MISMATCH = 'Mismatch';
4508 var EXIT_REASON_ITERATION_LIMIT = 'Maximum iteration number exceeded (please fill an issue on https://github.com/csstree/csstree/issues)';
4509
4510 var ITERATION_LIMIT = 15000;
4511 var totalIterationCount = 0;
4512
4513 function reverseList(list) {
4514 var prev = null;
4515 var next = null;
4516 var item = list;
4517
4518 while (item !== null) {
4519 next = item.prev;
4520 item.prev = prev;
4521 prev = item;
4522 item = next;
4523 }
4524
4525 return prev;
4526 }
4527
4528 function areStringsEqualCaseInsensitive(testStr, referenceStr) {
4529 if (testStr.length !== referenceStr.length) {
4530 return false;
4531 }
4532
4533 for (var i = 0; i < testStr.length; i++) {
4534 var testCode = testStr.charCodeAt(i);
4535 var referenceCode = referenceStr.charCodeAt(i);
4536
4537 // testCode.toLowerCase() for U+0041 LATIN CAPITAL LETTER A (A) .. U+005A LATIN CAPITAL LETTER Z (Z).
4538 if (testCode >= 0x0041 && testCode <= 0x005A) {
4539 testCode = testCode | 32;
4540 }
4541
4542 if (testCode !== referenceCode) {
4543 return false;
4544 }
4545 }
4546
4547 return true;
4548 }
4549
4550 function isCommaContextStart(token) {
4551 if (token === null) {
4552 return true;
4553 }
4554
4555 return (
4556 token.type === TYPE$6.Comma ||
4557 token.type === TYPE$6.Function ||
4558 token.type === TYPE$6.LeftParenthesis ||
4559 token.type === TYPE$6.LeftSquareBracket ||
4560 token.type === TYPE$6.LeftCurlyBracket ||
4561 token.type === TYPE$6.Delim
4562 );
4563 }
4564
4565 function isCommaContextEnd(token) {
4566 if (token === null) {
4567 return true;
4568 }
4569
4570 return (
4571 token.type === TYPE$6.RightParenthesis ||
4572 token.type === TYPE$6.RightSquareBracket ||
4573 token.type === TYPE$6.RightCurlyBracket ||
4574 token.type === TYPE$6.Delim
4575 );
4576 }
4577
4578 function internalMatch(tokens, state, syntaxes) {
4579 function moveToNextToken() {
4580 do {
4581 tokenIndex++;
4582 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
4583 } while (token !== null && (token.type === TYPE$6.WhiteSpace || token.type === TYPE$6.Comment));
4584 }
4585
4586 function getNextToken(offset) {
4587 var nextIndex = tokenIndex + offset;
4588
4589 return nextIndex < tokens.length ? tokens[nextIndex] : null;
4590 }
4591
4592 function stateSnapshotFromSyntax(nextState, prev) {
4593 return {
4594 nextState: nextState,
4595 matchStack: matchStack,
4596 syntaxStack: syntaxStack,
4597 thenStack: thenStack,
4598 tokenIndex: tokenIndex,
4599 prev: prev
4600 };
4601 }
4602
4603 function pushThenStack(nextState) {
4604 thenStack = {
4605 nextState: nextState,
4606 matchStack: matchStack,
4607 syntaxStack: syntaxStack,
4608 prev: thenStack
4609 };
4610 }
4611
4612 function pushElseStack(nextState) {
4613 elseStack = stateSnapshotFromSyntax(nextState, elseStack);
4614 }
4615
4616 function addTokenToMatch() {
4617 matchStack = {
4618 type: TOKEN,
4619 syntax: state.syntax,
4620 token: token,
4621 prev: matchStack
4622 };
4623
4624 moveToNextToken();
4625 syntaxStash = null;
4626
4627 if (tokenIndex > longestMatch) {
4628 longestMatch = tokenIndex;
4629 }
4630 }
4631
4632 function openSyntax() {
4633 syntaxStack = {
4634 syntax: state.syntax,
4635 opts: state.syntax.opts || (syntaxStack !== null && syntaxStack.opts) || null,
4636 prev: syntaxStack
4637 };
4638
4639 matchStack = {
4640 type: OPEN_SYNTAX,
4641 syntax: state.syntax,
4642 token: matchStack.token,
4643 prev: matchStack
4644 };
4645 }
4646
4647 function closeSyntax() {
4648 if (matchStack.type === OPEN_SYNTAX) {
4649 matchStack = matchStack.prev;
4650 } else {
4651 matchStack = {
4652 type: CLOSE_SYNTAX,
4653 syntax: syntaxStack.syntax,
4654 token: matchStack.token,
4655 prev: matchStack
4656 };
4657 }
4658
4659 syntaxStack = syntaxStack.prev;
4660 }
4661
4662 var syntaxStack = null;
4663 var thenStack = null;
4664 var elseStack = null;
4665
4666 // null – stashing allowed, nothing stashed
4667 // false – stashing disabled, nothing stashed
4668 // anithing else – fail stashable syntaxes, some syntax stashed
4669 var syntaxStash = null;
4670
4671 var iterationCount = 0; // count iterations and prevent infinite loop
4672 var exitReason = null;
4673
4674 var token = null;
4675 var tokenIndex = -1;
4676 var longestMatch = 0;
4677 var matchStack = {
4678 type: STUB,
4679 syntax: null,
4680 token: null,
4681 prev: null
4682 };
4683
4684 moveToNextToken();
4685
4686 while (exitReason === null && ++iterationCount < ITERATION_LIMIT) {
4687 // function mapList(list, fn) {
4688 // var result = [];
4689 // while (list) {
4690 // result.unshift(fn(list));
4691 // list = list.prev;
4692 // }
4693 // return result;
4694 // }
4695 // console.log('--\n',
4696 // '#' + iterationCount,
4697 // require('util').inspect({
4698 // match: mapList(matchStack, x => x.type === TOKEN ? x.token && x.token.value : x.syntax ? ({ [OPEN_SYNTAX]: '<', [CLOSE_SYNTAX]: '</' }[x.type] || x.type) + '!' + x.syntax.name : null),
4699 // token: token && token.value,
4700 // tokenIndex,
4701 // syntax: syntax.type + (syntax.id ? ' #' + syntax.id : '')
4702 // }, { depth: null })
4703 // );
4704 switch (state.type) {
4705 case 'Match':
4706 if (thenStack === null) {
4707 // turn to MISMATCH when some tokens left unmatched
4708 if (token !== null) {
4709 // doesn't mismatch if just one token left and it's an IE hack
4710 if (tokenIndex !== tokens.length - 1 || (token.value !== '\\0' && token.value !== '\\9')) {
4711 state = MISMATCH$1;
4712 break;
4713 }
4714 }
4715
4716 // break the main loop, return a result - MATCH
4717 exitReason = EXIT_REASON_MATCH;
4718 break;
4719 }
4720
4721 // go to next syntax (`then` branch)
4722 state = thenStack.nextState;
4723
4724 // check match is not empty
4725 if (state === DISALLOW_EMPTY$1) {
4726 if (thenStack.matchStack === matchStack) {
4727 state = MISMATCH$1;
4728 break;
4729 } else {
4730 state = MATCH$1;
4731 }
4732 }
4733
4734 // close syntax if needed
4735 while (thenStack.syntaxStack !== syntaxStack) {
4736 closeSyntax();
4737 }
4738
4739 // pop stack
4740 thenStack = thenStack.prev;
4741 break;
4742
4743 case 'Mismatch':
4744 // when some syntax is stashed
4745 if (syntaxStash !== null && syntaxStash !== false) {
4746 // there is no else branches or a branch reduce match stack
4747 if (elseStack === null || tokenIndex > elseStack.tokenIndex) {
4748 // restore state from the stash
4749 elseStack = syntaxStash;
4750 syntaxStash = false; // disable stashing
4751 }
4752 } else if (elseStack === null) {
4753 // no else branches -> break the main loop
4754 // return a result - MISMATCH
4755 exitReason = EXIT_REASON_MISMATCH;
4756 break;
4757 }
4758
4759 // go to next syntax (`else` branch)
4760 state = elseStack.nextState;
4761
4762 // restore all the rest stack states
4763 thenStack = elseStack.thenStack;
4764 syntaxStack = elseStack.syntaxStack;
4765 matchStack = elseStack.matchStack;
4766 tokenIndex = elseStack.tokenIndex;
4767 token = tokenIndex < tokens.length ? tokens[tokenIndex] : null;
4768
4769 // pop stack
4770 elseStack = elseStack.prev;
4771 break;
4772
4773 case 'MatchGraph':
4774 state = state.match;
4775 break;
4776
4777 case 'If':
4778 // IMPORTANT: else stack push must go first,
4779 // since it stores the state of thenStack before changes
4780 if (state.else !== MISMATCH$1) {
4781 pushElseStack(state.else);
4782 }
4783
4784 if (state.then !== MATCH$1) {
4785 pushThenStack(state.then);
4786 }
4787
4788 state = state.match;
4789 break;
4790
4791 case 'MatchOnce':
4792 state = {
4793 type: 'MatchOnceBuffer',
4794 syntax: state,
4795 index: 0,
4796 mask: 0
4797 };
4798 break;
4799
4800 case 'MatchOnceBuffer':
4801 var terms = state.syntax.terms;
4802
4803 if (state.index === terms.length) {
4804 // no matches at all or it's required all terms to be matched
4805 if (state.mask === 0 || state.syntax.all) {
4806 state = MISMATCH$1;
4807 break;
4808 }
4809
4810 // a partial match is ok
4811 state = MATCH$1;
4812 break;
4813 }
4814
4815 // all terms are matched
4816 if (state.mask === (1 << terms.length) - 1) {
4817 state = MATCH$1;
4818 break;
4819 }
4820
4821 for (; state.index < terms.length; state.index++) {
4822 var matchFlag = 1 << state.index;
4823
4824 if ((state.mask & matchFlag) === 0) {
4825 // IMPORTANT: else stack push must go first,
4826 // since it stores the state of thenStack before changes
4827 pushElseStack(state);
4828 pushThenStack({
4829 type: 'AddMatchOnce',
4830 syntax: state.syntax,
4831 mask: state.mask | matchFlag
4832 });
4833
4834 // match
4835 state = terms[state.index++];
4836 break;
4837 }
4838 }
4839 break;
4840
4841 case 'AddMatchOnce':
4842 state = {
4843 type: 'MatchOnceBuffer',
4844 syntax: state.syntax,
4845 index: 0,
4846 mask: state.mask
4847 };
4848 break;
4849
4850 case 'Enum':
4851 if (token !== null) {
4852 var name = token.value.toLowerCase();
4853
4854 // drop \0 and \9 hack from keyword name
4855 if (name.indexOf('\\') !== -1) {
4856 name = name.replace(/\\[09].*$/, '');
4857 }
4858
4859 if (hasOwnProperty$1.call(state.map, name)) {
4860 state = state.map[name];
4861 break;
4862 }
4863 }
4864
4865 state = MISMATCH$1;
4866 break;
4867
4868 case 'Generic':
4869 var opts = syntaxStack !== null ? syntaxStack.opts : null;
4870 var lastTokenIndex = tokenIndex + Math.floor(state.fn(token, getNextToken, opts));
4871
4872 if (!isNaN(lastTokenIndex) && lastTokenIndex > tokenIndex) {
4873 while (tokenIndex < lastTokenIndex) {
4874 addTokenToMatch();
4875 }
4876
4877 state = MATCH$1;
4878 } else {
4879 state = MISMATCH$1;
4880 }
4881
4882 break;
4883
4884 case 'Type':
4885 case 'Property':
4886 var syntaxDict = state.type === 'Type' ? 'types' : 'properties';
4887 var dictSyntax = hasOwnProperty$1.call(syntaxes, syntaxDict) ? syntaxes[syntaxDict][state.name] : null;
4888
4889 if (!dictSyntax || !dictSyntax.match) {
4890 throw new Error(
4891 'Bad syntax reference: ' +
4892 (state.type === 'Type'
4893 ? '<' + state.name + '>'
4894 : '<\'' + state.name + '\'>')
4895 );
4896 }
4897
4898 // stash a syntax for types with low priority
4899 if (syntaxStash !== false && token !== null && state.type === 'Type') {
4900 var lowPriorityMatching =
4901 // https://drafts.csswg.org/css-values-4/#custom-idents
4902 // When parsing positionally-ambiguous keywords in a property value, a <custom-ident> production
4903 // can only claim the keyword if no other unfulfilled production can claim it.
4904 (state.name === 'custom-ident' && token.type === TYPE$6.Ident) ||
4905
4906 // https://drafts.csswg.org/css-values-4/#lengths
4907 // ... if a `0` could be parsed as either a <number> or a <length> in a property (such as line-height),
4908 // it must parse as a <number>
4909 (state.name === 'length' && token.value === '0');
4910
4911 if (lowPriorityMatching) {
4912 if (syntaxStash === null) {
4913 syntaxStash = stateSnapshotFromSyntax(state, elseStack);
4914 }
4915
4916 state = MISMATCH$1;
4917 break;
4918 }
4919 }
4920
4921 openSyntax();
4922 state = dictSyntax.match;
4923 break;
4924
4925 case 'Keyword':
4926 var name = state.name;
4927
4928 if (token !== null) {
4929 var keywordName = token.value;
4930
4931 // drop \0 and \9 hack from keyword name
4932 if (keywordName.indexOf('\\') !== -1) {
4933 keywordName = keywordName.replace(/\\[09].*$/, '');
4934 }
4935
4936 if (areStringsEqualCaseInsensitive(keywordName, name)) {
4937 addTokenToMatch();
4938 state = MATCH$1;
4939 break;
4940 }
4941 }
4942
4943 state = MISMATCH$1;
4944 break;
4945
4946 case 'AtKeyword':
4947 case 'Function':
4948 if (token !== null && areStringsEqualCaseInsensitive(token.value, state.name)) {
4949 addTokenToMatch();
4950 state = MATCH$1;
4951 break;
4952 }
4953
4954 state = MISMATCH$1;
4955 break;
4956
4957 case 'Token':
4958 if (token !== null && token.value === state.value) {
4959 addTokenToMatch();
4960 state = MATCH$1;
4961 break;
4962 }
4963
4964 state = MISMATCH$1;
4965 break;
4966
4967 case 'Comma':
4968 if (token !== null && token.type === TYPE$6.Comma) {
4969 if (isCommaContextStart(matchStack.token)) {
4970 state = MISMATCH$1;
4971 } else {
4972 addTokenToMatch();
4973 state = isCommaContextEnd(token) ? MISMATCH$1 : MATCH$1;
4974 }
4975 } else {
4976 state = isCommaContextStart(matchStack.token) || isCommaContextEnd(token) ? MATCH$1 : MISMATCH$1;
4977 }
4978
4979 break;
4980
4981 case 'String':
4982 var string = '';
4983
4984 for (var lastTokenIndex = tokenIndex; lastTokenIndex < tokens.length && string.length < state.value.length; lastTokenIndex++) {
4985 string += tokens[lastTokenIndex].value;
4986 }
4987
4988 if (areStringsEqualCaseInsensitive(string, state.value)) {
4989 while (tokenIndex < lastTokenIndex) {
4990 addTokenToMatch();
4991 }
4992
4993 state = MATCH$1;
4994 } else {
4995 state = MISMATCH$1;
4996 }
4997
4998 break;
4999
5000 default:
5001 throw new Error('Unknown node type: ' + state.type);
5002 }
5003 }
5004
5005 totalIterationCount += iterationCount;
5006
5007 switch (exitReason) {
5008 case null:
5009 console.warn('[csstree-match] BREAK after ' + ITERATION_LIMIT + ' iterations');
5010 exitReason = EXIT_REASON_ITERATION_LIMIT;
5011 matchStack = null;
5012 break;
5013
5014 case EXIT_REASON_MATCH:
5015 while (syntaxStack !== null) {
5016 closeSyntax();
5017 }
5018 break;
5019
5020 default:
5021 matchStack = null;
5022 }
5023
5024 return {
5025 tokens: tokens,
5026 reason: exitReason,
5027 iterations: iterationCount,
5028 match: matchStack,
5029 longestMatch: longestMatch
5030 };
5031 }
5032
5033 function matchAsList(tokens, matchGraph, syntaxes) {
5034 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
5035
5036 if (matchResult.match !== null) {
5037 var item = reverseList(matchResult.match).prev;
5038
5039 matchResult.match = [];
5040
5041 while (item !== null) {
5042 switch (item.type) {
5043 case STUB:
5044 break;
5045
5046 case OPEN_SYNTAX:
5047 case CLOSE_SYNTAX:
5048 matchResult.match.push({
5049 type: item.type,
5050 syntax: item.syntax
5051 });
5052 break;
5053
5054 default:
5055 matchResult.match.push({
5056 token: item.token.value,
5057 node: item.token.node
5058 });
5059 break;
5060 }
5061
5062 item = item.prev;
5063 }
5064 }
5065
5066 return matchResult;
5067 }
5068
5069 function matchAsTree(tokens, matchGraph, syntaxes) {
5070 var matchResult = internalMatch(tokens, matchGraph, syntaxes || {});
5071
5072 if (matchResult.match === null) {
5073 return matchResult;
5074 }
5075
5076 var item = matchResult.match;
5077 var host = matchResult.match = {
5078 syntax: matchGraph.syntax || null,
5079 match: []
5080 };
5081 var hostStack = [host];
5082
5083 // revert a list and start with 2nd item since 1st is a stub item
5084 item = reverseList(item).prev;
5085
5086 // build a tree
5087 while (item !== null) {
5088 switch (item.type) {
5089 case OPEN_SYNTAX:
5090 host.match.push(host = {
5091 syntax: item.syntax,
5092 match: []
5093 });
5094 hostStack.push(host);
5095 break;
5096
5097 case CLOSE_SYNTAX:
5098 hostStack.pop();
5099 host = hostStack[hostStack.length - 1];
5100 break;
5101
5102 default:
5103 host.match.push({
5104 syntax: item.syntax || null,
5105 token: item.token.value,
5106 node: item.token.node
5107 });
5108 }
5109
5110 item = item.prev;
5111 }
5112
5113 return matchResult;
5114 }
5115
5116 var match = {
5117 matchAsList: matchAsList,
5118 matchAsTree: matchAsTree,
5119 getTotalIterationCount: function() {
5120 return totalIterationCount;
5121 }
5122 };
5123
5124 function getTrace(node) {
5125 function shouldPutToTrace(syntax) {
5126 if (syntax === null) {
5127 return false;
5128 }
5129
5130 return (
5131 syntax.type === 'Type' ||
5132 syntax.type === 'Property' ||
5133 syntax.type === 'Keyword'
5134 );
5135 }
5136
5137 function hasMatch(matchNode) {
5138 if (Array.isArray(matchNode.match)) {
5139 // use for-loop for better perfomance
5140 for (var i = 0; i < matchNode.match.length; i++) {
5141 if (hasMatch(matchNode.match[i])) {
5142 if (shouldPutToTrace(matchNode.syntax)) {
5143 result.unshift(matchNode.syntax);
5144 }
5145
5146 return true;
5147 }
5148 }
5149 } else if (matchNode.node === node) {
5150 result = shouldPutToTrace(matchNode.syntax)
5151 ? [matchNode.syntax]
5152 : [];
5153
5154 return true;
5155 }
5156
5157 return false;
5158 }
5159
5160 var result = null;
5161
5162 if (this.matched !== null) {
5163 hasMatch(this.matched);
5164 }
5165
5166 return result;
5167 }
5168
5169 function testNode(match, node, fn) {
5170 var trace = getTrace.call(match, node);
5171
5172 if (trace === null) {
5173 return false;
5174 }
5175
5176 return trace.some(fn);
5177 }
5178
5179 function isType(node, type) {
5180 return testNode(this, node, function(matchNode) {
5181 return matchNode.type === 'Type' && matchNode.name === type;
5182 });
5183 }
5184
5185 function isProperty(node, property) {
5186 return testNode(this, node, function(matchNode) {
5187 return matchNode.type === 'Property' && matchNode.name === property;
5188 });
5189 }
5190
5191 function isKeyword(node) {
5192 return testNode(this, node, function(matchNode) {
5193 return matchNode.type === 'Keyword';
5194 });
5195 }
5196
5197 var trace = {
5198 getTrace: getTrace,
5199 isType: isType,
5200 isProperty: isProperty,
5201 isKeyword: isKeyword
5202 };
5203
5204 function getFirstMatchNode(matchNode) {
5205 if ('node' in matchNode) {
5206 return matchNode.node;
5207 }
5208
5209 return getFirstMatchNode(matchNode.match[0]);
5210 }
5211
5212 function getLastMatchNode(matchNode) {
5213 if ('node' in matchNode) {
5214 return matchNode.node;
5215 }
5216
5217 return getLastMatchNode(matchNode.match[matchNode.match.length - 1]);
5218 }
5219
5220 function matchFragments(lexer, ast, match, type, name) {
5221 function findFragments(matchNode) {
5222 if (matchNode.syntax !== null &&
5223 matchNode.syntax.type === type &&
5224 matchNode.syntax.name === name) {
5225 var start = getFirstMatchNode(matchNode);
5226 var end = getLastMatchNode(matchNode);
5227
5228 lexer.syntax.walk(ast, function(node, item, list) {
5229 if (node === start) {
5230 var nodes = new List_1();
5231
5232 do {
5233 nodes.appendData(item.data);
5234
5235 if (item.data === end) {
5236 break;
5237 }
5238
5239 item = item.next;
5240 } while (item !== null);
5241
5242 fragments.push({
5243 parent: list,
5244 nodes: nodes
5245 });
5246 }
5247 });
5248 }
5249
5250 if (Array.isArray(matchNode.match)) {
5251 matchNode.match.forEach(findFragments);
5252 }
5253 }
5254
5255 var fragments = [];
5256
5257 if (match.matched !== null) {
5258 findFragments(match.matched);
5259 }
5260
5261 return fragments;
5262 }
5263
5264 var search = {
5265 matchFragments: matchFragments
5266 };
5267
5268 var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
5269
5270 function isValidNumber(value) {
5271 // Number.isInteger(value) && value >= 0
5272 return (
5273 typeof value === 'number' &&
5274 isFinite(value) &&
5275 Math.floor(value) === value &&
5276 value >= 0
5277 );
5278 }
5279
5280 function isValidLocation(loc) {
5281 return (
5282 Boolean(loc) &&
5283 isValidNumber(loc.offset) &&
5284 isValidNumber(loc.line) &&
5285 isValidNumber(loc.column)
5286 );
5287 }
5288
5289 function createNodeStructureChecker(type, fields) {
5290 return function checkNode(node, warn) {
5291 if (!node || node.constructor !== Object) {
5292 return warn(node, 'Type of node should be an Object');
5293 }
5294
5295 for (var key in node) {
5296 var valid = true;
5297
5298 if (hasOwnProperty$2.call(node, key) === false) {
5299 continue;
5300 }
5301
5302 if (key === 'type') {
5303 if (node.type !== type) {
5304 warn(node, 'Wrong node type `' + node.type + '`, expected `' + type + '`');
5305 }
5306 } else if (key === 'loc') {
5307 if (node.loc === null) {
5308 continue;
5309 } else if (node.loc && node.loc.constructor === Object) {
5310 if (typeof node.loc.source !== 'string') {
5311 key += '.source';
5312 } else if (!isValidLocation(node.loc.start)) {
5313 key += '.start';
5314 } else if (!isValidLocation(node.loc.end)) {
5315 key += '.end';
5316 } else {
5317 continue;
5318 }
5319 }
5320
5321 valid = false;
5322 } else if (fields.hasOwnProperty(key)) {
5323 for (var i = 0, valid = false; !valid && i < fields[key].length; i++) {
5324 var fieldType = fields[key][i];
5325
5326 switch (fieldType) {
5327 case String:
5328 valid = typeof node[key] === 'string';
5329 break;
5330
5331 case Boolean:
5332 valid = typeof node[key] === 'boolean';
5333 break;
5334
5335 case null:
5336 valid = node[key] === null;
5337 break;
5338
5339 default:
5340 if (typeof fieldType === 'string') {
5341 valid = node[key] && node[key].type === fieldType;
5342 } else if (Array.isArray(fieldType)) {
5343 valid = node[key] instanceof List_1;
5344 }
5345 }
5346 }
5347 } else {
5348 warn(node, 'Unknown field `' + key + '` for ' + type + ' node type');
5349 }
5350
5351 if (!valid) {
5352 warn(node, 'Bad value for `' + type + '.' + key + '`');
5353 }
5354 }
5355
5356 for (var key in fields) {
5357 if (hasOwnProperty$2.call(fields, key) &&
5358 hasOwnProperty$2.call(node, key) === false) {
5359 warn(node, 'Field `' + type + '.' + key + '` is missed');
5360 }
5361 }
5362 };
5363 }
5364
5365 function processStructure(name, nodeType) {
5366 var structure = nodeType.structure;
5367 var fields = {
5368 type: String,
5369 loc: true
5370 };
5371 var docs = {
5372 type: '"' + name + '"'
5373 };
5374
5375 for (var key in structure) {
5376 if (hasOwnProperty$2.call(structure, key) === false) {
5377 continue;
5378 }
5379
5380 var docsTypes = [];
5381 var fieldTypes = fields[key] = Array.isArray(structure[key])
5382 ? structure[key].slice()
5383 : [structure[key]];
5384
5385 for (var i = 0; i < fieldTypes.length; i++) {
5386 var fieldType = fieldTypes[i];
5387 if (fieldType === String || fieldType === Boolean) {
5388 docsTypes.push(fieldType.name);
5389 } else if (fieldType === null) {
5390 docsTypes.push('null');
5391 } else if (typeof fieldType === 'string') {
5392 docsTypes.push('<' + fieldType + '>');
5393 } else if (Array.isArray(fieldType)) {
5394 docsTypes.push('List'); // TODO: use type enum
5395 } else {
5396 throw new Error('Wrong value `' + fieldType + '` in `' + name + '.' + key + '` structure definition');
5397 }
5398 }
5399
5400 docs[key] = docsTypes.join(' | ');
5401 }
5402
5403 return {
5404 docs: docs,
5405 check: createNodeStructureChecker(name, fields)
5406 };
5407 }
5408
5409 var structure = {
5410 getStructureFromConfig: function(config) {
5411 var structure = {};
5412
5413 if (config.node) {
5414 for (var name in config.node) {
5415 if (hasOwnProperty$2.call(config.node, name)) {
5416 var nodeType = config.node[name];
5417
5418 if (nodeType.structure) {
5419 structure[name] = processStructure(name, nodeType);
5420 } else {
5421 throw new Error('Missed `structure` field in `' + name + '` node type definition');
5422 }
5423 }
5424 }
5425 }
5426
5427 return structure;
5428 }
5429 };
5430
5431 var SyntaxReferenceError$1 = error.SyntaxReferenceError;
5432 var MatchError$1 = error.MatchError;
5433
5434
5435
5436
5437
5438
5439 var buildMatchGraph$1 = matchGraph.buildMatchGraph;
5440 var matchAsTree$1 = match.matchAsTree;
5441
5442
5443 var getStructureFromConfig = structure.getStructureFromConfig;
5444 var cssWideKeywords$1 = buildMatchGraph$1('inherit | initial | unset');
5445 var cssWideKeywordsWithExpression = buildMatchGraph$1('inherit | initial | unset | <-ms-legacy-expression>');
5446
5447 function dumpMapSyntax(map, compact, syntaxAsAst) {
5448 var result = {};
5449
5450 for (var name in map) {
5451 if (map[name].syntax) {
5452 result[name] = syntaxAsAst
5453 ? map[name].syntax
5454 : generate_1(map[name].syntax, { compact: compact });
5455 }
5456 }
5457
5458 return result;
5459 }
5460
5461 function valueHasVar(tokens) {
5462 for (var i = 0; i < tokens.length; i++) {
5463 if (tokens[i].value.toLowerCase() === 'var(') {
5464 return true;
5465 }
5466 }
5467
5468 return false;
5469 }
5470
5471 function buildMatchResult(match, error, iterations) {
5472 return {
5473 matched: match,
5474 iterations: iterations,
5475 error: error,
5476 getTrace: trace.getTrace,
5477 isType: trace.isType,
5478 isProperty: trace.isProperty,
5479 isKeyword: trace.isKeyword
5480 };
5481 }
5482
5483 function matchSyntax(lexer, syntax, value, useCommon) {
5484 var tokens = prepareTokens_1(value, lexer.syntax);
5485 var result;
5486
5487 if (valueHasVar(tokens)) {
5488 return buildMatchResult(null, new Error('Matching for a tree with var() is not supported'));
5489 }
5490
5491 if (useCommon) {
5492 result = matchAsTree$1(tokens, lexer.valueCommonSyntax, lexer);
5493 }
5494
5495 if (!useCommon || !result.match) {
5496 result = matchAsTree$1(tokens, syntax.match, lexer);
5497 if (!result.match) {
5498 return buildMatchResult(
5499 null,
5500 new MatchError$1(result.reason, syntax.syntax, value, result),
5501 result.iterations
5502 );
5503 }
5504 }
5505
5506 return buildMatchResult(result.match, null, result.iterations);
5507 }
5508
5509 var Lexer = function(config, syntax, structure) {
5510 this.valueCommonSyntax = cssWideKeywords$1;
5511 this.syntax = syntax;
5512 this.generic = false;
5513 this.properties = {};
5514 this.types = {};
5515 this.structure = structure || getStructureFromConfig(config);
5516
5517 if (config) {
5518 if (config.types) {
5519 for (var name in config.types) {
5520 this.addType_(name, config.types[name]);
5521 }
5522 }
5523
5524 if (config.generic) {
5525 this.generic = true;
5526 for (var name in generic) {
5527 this.addType_(name, generic[name]);
5528 }
5529 }
5530
5531 if (config.properties) {
5532 for (var name in config.properties) {
5533 this.addProperty_(name, config.properties[name]);
5534 }
5535 }
5536 }
5537 };
5538
5539 Lexer.prototype = {
5540 structure: {},
5541 checkStructure: function(ast) {
5542 function collectWarning(node, message) {
5543 warns.push({
5544 node: node,
5545 message: message
5546 });
5547 }
5548
5549 var structure = this.structure;
5550 var warns = [];
5551
5552 this.syntax.walk(ast, function(node) {
5553 if (structure.hasOwnProperty(node.type)) {
5554 structure[node.type].check(node, collectWarning);
5555 } else {
5556 collectWarning(node, 'Unknown node type `' + node.type + '`');
5557 }
5558 });
5559
5560 return warns.length ? warns : false;
5561 },
5562
5563 createDescriptor: function(syntax, type, name) {
5564 var ref = {
5565 type: type,
5566 name: name
5567 };
5568 var descriptor = {
5569 type: type,
5570 name: name,
5571 syntax: null,
5572 match: null
5573 };
5574
5575 if (typeof syntax === 'function') {
5576 descriptor.match = buildMatchGraph$1(syntax, ref);
5577 } else {
5578 if (typeof syntax === 'string') {
5579 // lazy parsing on first access
5580 Object.defineProperty(descriptor, 'syntax', {
5581 get: function() {
5582 Object.defineProperty(descriptor, 'syntax', {
5583 value: parse_1(syntax)
5584 });
5585
5586 return descriptor.syntax;
5587 }
5588 });
5589 } else {
5590 descriptor.syntax = syntax;
5591 }
5592
5593 // lazy graph build on first access
5594 Object.defineProperty(descriptor, 'match', {
5595 get: function() {
5596 Object.defineProperty(descriptor, 'match', {
5597 value: buildMatchGraph$1(descriptor.syntax, ref)
5598 });
5599
5600 return descriptor.match;
5601 }
5602 });
5603 }
5604
5605 return descriptor;
5606 },
5607 addProperty_: function(name, syntax) {
5608 this.properties[name] = this.createDescriptor(syntax, 'Property', name);
5609 },
5610 addType_: function(name, syntax) {
5611 this.types[name] = this.createDescriptor(syntax, 'Type', name);
5612
5613 if (syntax === generic['-ms-legacy-expression']) {
5614 this.valueCommonSyntax = cssWideKeywordsWithExpression;
5615 }
5616 },
5617
5618 matchDeclaration: function(node) {
5619 if (node.type !== 'Declaration') {
5620 return buildMatchResult(null, new Error('Not a Declaration node'));
5621 }
5622
5623 return this.matchProperty(node.property, node.value);
5624 },
5625 matchProperty: function(propertyName, value) {
5626 var property = names.property(propertyName);
5627
5628 // don't match syntax for a custom property
5629 if (property.custom) {
5630 return buildMatchResult(null, new Error('Lexer matching doesn\'t applicable for custom properties'));
5631 }
5632
5633 var propertySyntax = property.vendor
5634 ? this.getProperty(property.name) || this.getProperty(property.basename)
5635 : this.getProperty(property.name);
5636
5637 if (!propertySyntax) {
5638 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown property', propertyName));
5639 }
5640
5641 return matchSyntax(this, propertySyntax, value, true);
5642 },
5643 matchType: function(typeName, value) {
5644 var typeSyntax = this.getType(typeName);
5645
5646 if (!typeSyntax) {
5647 return buildMatchResult(null, new SyntaxReferenceError$1('Unknown type', typeName));
5648 }
5649
5650 return matchSyntax(this, typeSyntax, value, false);
5651 },
5652 match: function(syntax, value) {
5653 if (typeof syntax !== 'string' && (!syntax || !syntax.type)) {
5654 return buildMatchResult(null, new SyntaxReferenceError$1('Bad syntax'));
5655 }
5656
5657 if (typeof syntax === 'string' || !syntax.match) {
5658 syntax = this.createDescriptor(syntax, 'Type', 'anonymous');
5659 }
5660
5661 return matchSyntax(this, syntax, value, false);
5662 },
5663
5664 findValueFragments: function(propertyName, value, type, name) {
5665 return search.matchFragments(this, value, this.matchProperty(propertyName, value), type, name);
5666 },
5667 findDeclarationValueFragments: function(declaration, type, name) {
5668 return search.matchFragments(this, declaration.value, this.matchDeclaration(declaration), type, name);
5669 },
5670 findAllFragments: function(ast, type, name) {
5671 var result = [];
5672
5673 this.syntax.walk(ast, {
5674 visit: 'Declaration',
5675 enter: function(declaration) {
5676 result.push.apply(result, this.findDeclarationValueFragments(declaration, type, name));
5677 }.bind(this)
5678 });
5679
5680 return result;
5681 },
5682
5683 getProperty: function(name) {
5684 return this.properties.hasOwnProperty(name) ? this.properties[name] : null;
5685 },
5686 getType: function(name) {
5687 return this.types.hasOwnProperty(name) ? this.types[name] : null;
5688 },
5689
5690 validate: function() {
5691 function validate(syntax, name, broken, descriptor) {
5692 if (broken.hasOwnProperty(name)) {
5693 return broken[name];
5694 }
5695
5696 broken[name] = false;
5697 if (descriptor.syntax !== null) {
5698 walk(descriptor.syntax, function(node) {
5699 if (node.type !== 'Type' && node.type !== 'Property') {
5700 return;
5701 }
5702
5703 var map = node.type === 'Type' ? syntax.types : syntax.properties;
5704 var brokenMap = node.type === 'Type' ? brokenTypes : brokenProperties;
5705
5706 if (!map.hasOwnProperty(node.name) || validate(syntax, node.name, brokenMap, map[node.name])) {
5707 broken[name] = true;
5708 }
5709 }, this);
5710 }
5711 }
5712
5713 var brokenTypes = {};
5714 var brokenProperties = {};
5715
5716 for (var key in this.types) {
5717 validate(this, key, brokenTypes, this.types[key]);
5718 }
5719
5720 for (var key in this.properties) {
5721 validate(this, key, brokenProperties, this.properties[key]);
5722 }
5723
5724 brokenTypes = Object.keys(brokenTypes).filter(function(name) {
5725 return brokenTypes[name];
5726 });
5727 brokenProperties = Object.keys(brokenProperties).filter(function(name) {
5728 return brokenProperties[name];
5729 });
5730
5731 if (brokenTypes.length || brokenProperties.length) {
5732 return {
5733 types: brokenTypes,
5734 properties: brokenProperties
5735 };
5736 }
5737
5738 return null;
5739 },
5740 dump: function(syntaxAsAst, pretty) {
5741 return {
5742 generic: this.generic,
5743 types: dumpMapSyntax(this.types, !pretty, syntaxAsAst),
5744 properties: dumpMapSyntax(this.properties, !pretty, syntaxAsAst)
5745 };
5746 },
5747 toString: function() {
5748 return JSON.stringify(this.dump());
5749 }
5750 };
5751
5752 var Lexer_1 = Lexer;
5753
5754 var definitionSyntax = {
5755 SyntaxError: _SyntaxError$1,
5756 parse: parse_1,
5757 generate: generate_1,
5758 walk: walk
5759 };
5760
5761 var isBOM$2 = tokenizer.isBOM;
5762
5763 var N$3 = 10;
5764 var F$2 = 12;
5765 var R$2 = 13;
5766
5767 function computeLinesAndColumns(host, source) {
5768 var sourceLength = source.length;
5769 var lines = adoptBuffer(host.lines, sourceLength); // +1
5770 var line = host.startLine;
5771 var columns = adoptBuffer(host.columns, sourceLength);
5772 var column = host.startColumn;
5773 var startOffset = source.length > 0 ? isBOM$2(source.charCodeAt(0)) : 0;
5774
5775 for (var i = startOffset; i < sourceLength; i++) { // -1
5776 var code = source.charCodeAt(i);
5777
5778 lines[i] = line;
5779 columns[i] = column++;
5780
5781 if (code === N$3 || code === R$2 || code === F$2) {
5782 if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$3) {
5783 i++;
5784 lines[i] = line;
5785 columns[i] = column;
5786 }
5787
5788 line++;
5789 column = 1;
5790 }
5791 }
5792
5793 lines[i] = line;
5794 columns[i] = column;
5795
5796 host.lines = lines;
5797 host.columns = columns;
5798 }
5799
5800 var OffsetToLocation = function() {
5801 this.lines = null;
5802 this.columns = null;
5803 this.linesAndColumnsComputed = false;
5804 };
5805
5806 OffsetToLocation.prototype = {
5807 setSource: function(source, startOffset, startLine, startColumn) {
5808 this.source = source;
5809 this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
5810 this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
5811 this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
5812 this.linesAndColumnsComputed = false;
5813 },
5814
5815 ensureLinesAndColumnsComputed: function() {
5816 if (!this.linesAndColumnsComputed) {
5817 computeLinesAndColumns(this, this.source);
5818 this.linesAndColumnsComputed = true;
5819 }
5820 },
5821 getLocation: function(offset, filename) {
5822 this.ensureLinesAndColumnsComputed();
5823
5824 return {
5825 source: filename,
5826 offset: this.startOffset + offset,
5827 line: this.lines[offset],
5828 column: this.columns[offset]
5829 };
5830 },
5831 getLocationRange: function(start, end, filename) {
5832 this.ensureLinesAndColumnsComputed();
5833
5834 return {
5835 source: filename,
5836 start: {
5837 offset: this.startOffset + start,
5838 line: this.lines[start],
5839 column: this.columns[start]
5840 },
5841 end: {
5842 offset: this.startOffset + end,
5843 line: this.lines[end],
5844 column: this.columns[end]
5845 }
5846 };
5847 }
5848 };
5849
5850 var OffsetToLocation_1 = OffsetToLocation;
5851
5852 var TYPE$7 = tokenizer.TYPE;
5853 var WHITESPACE$2 = TYPE$7.WhiteSpace;
5854 var COMMENT$2 = TYPE$7.Comment;
5855
5856 var sequence = function readSequence(recognizer) {
5857 var children = this.createList();
5858 var child = null;
5859 var context = {
5860 recognizer: recognizer,
5861 space: null,
5862 ignoreWS: false,
5863 ignoreWSAfter: false
5864 };
5865
5866 this.scanner.skipSC();
5867
5868 while (!this.scanner.eof) {
5869 switch (this.scanner.tokenType) {
5870 case COMMENT$2:
5871 this.scanner.next();
5872 continue;
5873
5874 case WHITESPACE$2:
5875 if (context.ignoreWS) {
5876 this.scanner.next();
5877 } else {
5878 context.space = this.WhiteSpace();
5879 }
5880 continue;
5881 }
5882
5883 child = recognizer.getNode.call(this, context);
5884
5885 if (child === undefined) {
5886 break;
5887 }
5888
5889 if (context.space !== null) {
5890 children.push(context.space);
5891 context.space = null;
5892 }
5893
5894 children.push(child);
5895
5896 if (context.ignoreWSAfter) {
5897 context.ignoreWSAfter = false;
5898 context.ignoreWS = true;
5899 } else {
5900 context.ignoreWS = false;
5901 }
5902 }
5903
5904 return children;
5905 };
5906
5907 var findWhiteSpaceStart$1 = utils.findWhiteSpaceStart;
5908
5909 var noop$2 = function() {};
5910
5911 var TYPE$8 = _const.TYPE;
5912 var NAME$2 = _const.NAME;
5913 var WHITESPACE$3 = TYPE$8.WhiteSpace;
5914 var IDENT$2 = TYPE$8.Ident;
5915 var FUNCTION = TYPE$8.Function;
5916 var URL = TYPE$8.Url;
5917 var HASH = TYPE$8.Hash;
5918 var PERCENTAGE = TYPE$8.Percentage;
5919 var NUMBER$2 = TYPE$8.Number;
5920 var NUMBERSIGN$1 = 0x0023; // U+0023 NUMBER SIGN (#)
5921 var NULL = 0;
5922
5923 function createParseContext(name) {
5924 return function() {
5925 return this[name]();
5926 };
5927 }
5928
5929 function processConfig(config) {
5930 var parserConfig = {
5931 context: {},
5932 scope: {},
5933 atrule: {},
5934 pseudo: {}
5935 };
5936
5937 if (config.parseContext) {
5938 for (var name in config.parseContext) {
5939 switch (typeof config.parseContext[name]) {
5940 case 'function':
5941 parserConfig.context[name] = config.parseContext[name];
5942 break;
5943
5944 case 'string':
5945 parserConfig.context[name] = createParseContext(config.parseContext[name]);
5946 break;
5947 }
5948 }
5949 }
5950
5951 if (config.scope) {
5952 for (var name in config.scope) {
5953 parserConfig.scope[name] = config.scope[name];
5954 }
5955 }
5956
5957 if (config.atrule) {
5958 for (var name in config.atrule) {
5959 var atrule = config.atrule[name];
5960
5961 if (atrule.parse) {
5962 parserConfig.atrule[name] = atrule.parse;
5963 }
5964 }
5965 }
5966
5967 if (config.pseudo) {
5968 for (var name in config.pseudo) {
5969 var pseudo = config.pseudo[name];
5970
5971 if (pseudo.parse) {
5972 parserConfig.pseudo[name] = pseudo.parse;
5973 }
5974 }
5975 }
5976
5977 if (config.node) {
5978 for (var name in config.node) {
5979 parserConfig[name] = config.node[name].parse;
5980 }
5981 }
5982
5983 return parserConfig;
5984 }
5985
5986 var create = function createParser(config) {
5987 var parser = {
5988 scanner: new TokenStream_1(),
5989 locationMap: new OffsetToLocation_1(),
5990
5991 filename: '<unknown>',
5992 needPositions: false,
5993 onParseError: noop$2,
5994 onParseErrorThrow: false,
5995 parseAtrulePrelude: true,
5996 parseRulePrelude: true,
5997 parseValue: true,
5998 parseCustomProperty: false,
5999
6000 readSequence: sequence,
6001
6002 createList: function() {
6003 return new List_1();
6004 },
6005 createSingleNodeList: function(node) {
6006 return new List_1().appendData(node);
6007 },
6008 getFirstListNode: function(list) {
6009 return list && list.first();
6010 },
6011 getLastListNode: function(list) {
6012 return list.last();
6013 },
6014
6015 parseWithFallback: function(consumer, fallback) {
6016 var startToken = this.scanner.tokenIndex;
6017
6018 try {
6019 return consumer.call(this);
6020 } catch (e) {
6021 if (this.onParseErrorThrow) {
6022 throw e;
6023 }
6024
6025 var fallbackNode = fallback.call(this, startToken);
6026
6027 this.onParseErrorThrow = true;
6028 this.onParseError(e, fallbackNode);
6029 this.onParseErrorThrow = false;
6030
6031 return fallbackNode;
6032 }
6033 },
6034
6035 lookupNonWSType: function(offset) {
6036 do {
6037 var type = this.scanner.lookupType(offset++);
6038 if (type !== WHITESPACE$3) {
6039 return type;
6040 }
6041 } while (type !== NULL);
6042
6043 return NULL;
6044 },
6045
6046 eat: function(tokenType) {
6047 if (this.scanner.tokenType !== tokenType) {
6048 var offset = this.scanner.tokenStart;
6049 var message = NAME$2[tokenType] + ' is expected';
6050
6051 // tweak message and offset
6052 switch (tokenType) {
6053 case IDENT$2:
6054 // when identifier is expected but there is a function or url
6055 if (this.scanner.tokenType === FUNCTION || this.scanner.tokenType === URL) {
6056 offset = this.scanner.tokenEnd - 1;
6057 message = 'Identifier is expected but function found';
6058 } else {
6059 message = 'Identifier is expected';
6060 }
6061 break;
6062
6063 case HASH:
6064 if (this.scanner.isDelim(NUMBERSIGN$1)) {
6065 this.scanner.next();
6066 offset++;
6067 message = 'Name is expected';
6068 }
6069 break;
6070
6071 case PERCENTAGE:
6072 if (this.scanner.tokenType === NUMBER$2) {
6073 offset = this.scanner.tokenEnd;
6074 message = 'Percent sign is expected';
6075 }
6076 break;
6077
6078 default:
6079 // when test type is part of another token show error for current position + 1
6080 // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
6081 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === tokenType) {
6082 offset = offset + 1;
6083 }
6084 }
6085
6086 this.error(message, offset);
6087 }
6088
6089 this.scanner.next();
6090 },
6091
6092 consume: function(tokenType) {
6093 var value = this.scanner.getTokenValue();
6094
6095 this.eat(tokenType);
6096
6097 return value;
6098 },
6099 consumeFunctionName: function() {
6100 var name = this.scanner.source.substring(this.scanner.tokenStart, this.scanner.tokenEnd - 1);
6101
6102 this.eat(FUNCTION);
6103
6104 return name;
6105 },
6106
6107 getLocation: function(start, end) {
6108 if (this.needPositions) {
6109 return this.locationMap.getLocationRange(
6110 start,
6111 end,
6112 this.filename
6113 );
6114 }
6115
6116 return null;
6117 },
6118 getLocationFromList: function(list) {
6119 if (this.needPositions) {
6120 var head = this.getFirstListNode(list);
6121 var tail = this.getLastListNode(list);
6122 return this.locationMap.getLocationRange(
6123 head !== null ? head.loc.start.offset - this.locationMap.startOffset : this.scanner.tokenStart,
6124 tail !== null ? tail.loc.end.offset - this.locationMap.startOffset : this.scanner.tokenStart,
6125 this.filename
6126 );
6127 }
6128
6129 return null;
6130 },
6131
6132 error: function(message, offset) {
6133 var location = typeof offset !== 'undefined' && offset < this.scanner.source.length
6134 ? this.locationMap.getLocation(offset)
6135 : this.scanner.eof
6136 ? this.locationMap.getLocation(findWhiteSpaceStart$1(this.scanner.source, this.scanner.source.length - 1))
6137 : this.locationMap.getLocation(this.scanner.tokenStart);
6138
6139 throw new _SyntaxError(
6140 message || 'Unexpected input',
6141 this.scanner.source,
6142 location.offset,
6143 location.line,
6144 location.column
6145 );
6146 }
6147 };
6148
6149 config = processConfig(config || {});
6150 for (var key in config) {
6151 parser[key] = config[key];
6152 }
6153
6154 return function(source, options) {
6155 options = options || {};
6156
6157 var context = options.context || 'default';
6158 var ast;
6159
6160 tokenizer(source, parser.scanner);
6161 parser.locationMap.setSource(
6162 source,
6163 options.offset,
6164 options.line,
6165 options.column
6166 );
6167
6168 parser.filename = options.filename || '<unknown>';
6169 parser.needPositions = Boolean(options.positions);
6170 parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$2;
6171 parser.onParseErrorThrow = false;
6172 parser.parseAtrulePrelude = 'parseAtrulePrelude' in options ? Boolean(options.parseAtrulePrelude) : true;
6173 parser.parseRulePrelude = 'parseRulePrelude' in options ? Boolean(options.parseRulePrelude) : true;
6174 parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
6175 parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
6176
6177 if (!parser.context.hasOwnProperty(context)) {
6178 throw new Error('Unknown context `' + context + '`');
6179 }
6180
6181 ast = parser.context[context].call(parser, options);
6182
6183 if (!parser.scanner.eof) {
6184 parser.error();
6185 }
6186
6187 return ast;
6188 };
6189 };
6190
6191 /* -*- Mode: js; js-indent-level: 2; -*- */
6192 /*
6193 * Copyright 2011 Mozilla Foundation and contributors
6194 * Licensed under the New BSD license. See LICENSE or:
6195 * http://opensource.org/licenses/BSD-3-Clause
6196 */
6197
6198 var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
6199
6200 /**
6201 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
6202 */
6203 var encode = function (number) {
6204 if (0 <= number && number < intToCharMap.length) {
6205 return intToCharMap[number];
6206 }
6207 throw new TypeError("Must be between 0 and 63: " + number);
6208 };
6209
6210 /**
6211 * Decode a single base 64 character code digit to an integer. Returns -1 on
6212 * failure.
6213 */
6214 var decode = function (charCode) {
6215 var bigA = 65; // 'A'
6216 var bigZ = 90; // 'Z'
6217
6218 var littleA = 97; // 'a'
6219 var littleZ = 122; // 'z'
6220
6221 var zero = 48; // '0'
6222 var nine = 57; // '9'
6223
6224 var plus = 43; // '+'
6225 var slash = 47; // '/'
6226
6227 var littleOffset = 26;
6228 var numberOffset = 52;
6229
6230 // 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
6231 if (bigA <= charCode && charCode <= bigZ) {
6232 return (charCode - bigA);
6233 }
6234
6235 // 26 - 51: abcdefghijklmnopqrstuvwxyz
6236 if (littleA <= charCode && charCode <= littleZ) {
6237 return (charCode - littleA + littleOffset);
6238 }
6239
6240 // 52 - 61: 0123456789
6241 if (zero <= charCode && charCode <= nine) {
6242 return (charCode - zero + numberOffset);
6243 }
6244
6245 // 62: +
6246 if (charCode == plus) {
6247 return 62;
6248 }
6249
6250 // 63: /
6251 if (charCode == slash) {
6252 return 63;
6253 }
6254
6255 // Invalid base64 digit.
6256 return -1;
6257 };
6258
6259 var base64 = {
6260 encode: encode,
6261 decode: decode
6262 };
6263
6264 /* -*- Mode: js; js-indent-level: 2; -*- */
6265 /*
6266 * Copyright 2011 Mozilla Foundation and contributors
6267 * Licensed under the New BSD license. See LICENSE or:
6268 * http://opensource.org/licenses/BSD-3-Clause
6269 *
6270 * Based on the Base 64 VLQ implementation in Closure Compiler:
6271 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
6272 *
6273 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
6274 * Redistribution and use in source and binary forms, with or without
6275 * modification, are permitted provided that the following conditions are
6276 * met:
6277 *
6278 * * Redistributions of source code must retain the above copyright
6279 * notice, this list of conditions and the following disclaimer.
6280 * * Redistributions in binary form must reproduce the above
6281 * copyright notice, this list of conditions and the following
6282 * disclaimer in the documentation and/or other materials provided
6283 * with the distribution.
6284 * * Neither the name of Google Inc. nor the names of its
6285 * contributors may be used to endorse or promote products derived
6286 * from this software without specific prior written permission.
6287 *
6288 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6289 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6290 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6291 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
6292 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
6293 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
6294 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6295 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6296 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6297 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
6298 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6299 */
6300
6301
6302
6303 // A single base 64 digit can contain 6 bits of data. For the base 64 variable
6304 // length quantities we use in the source map spec, the first bit is the sign,
6305 // the next four bits are the actual value, and the 6th bit is the
6306 // continuation bit. The continuation bit tells us whether there are more
6307 // digits in this value following this digit.
6308 //
6309 // Continuation
6310 // | Sign
6311 // | |
6312 // V V
6313 // 101011
6314
6315 var VLQ_BASE_SHIFT = 5;
6316
6317 // binary: 100000
6318 var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
6319
6320 // binary: 011111
6321 var VLQ_BASE_MASK = VLQ_BASE - 1;
6322
6323 // binary: 100000
6324 var VLQ_CONTINUATION_BIT = VLQ_BASE;
6325
6326 /**
6327 * Converts from a two-complement value to a value where the sign bit is
6328 * placed in the least significant bit. For example, as decimals:
6329 * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
6330 * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
6331 */
6332 function toVLQSigned(aValue) {
6333 return aValue < 0
6334 ? ((-aValue) << 1) + 1
6335 : (aValue << 1) + 0;
6336 }
6337
6338 /**
6339 * Converts to a two-complement value from a value where the sign bit is
6340 * placed in the least significant bit. For example, as decimals:
6341 * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
6342 * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
6343 */
6344 function fromVLQSigned(aValue) {
6345 var isNegative = (aValue & 1) === 1;
6346 var shifted = aValue >> 1;
6347 return isNegative
6348 ? -shifted
6349 : shifted;
6350 }
6351
6352 /**
6353 * Returns the base 64 VLQ encoded value.
6354 */
6355 var encode$1 = function base64VLQ_encode(aValue) {
6356 var encoded = "";
6357 var digit;
6358
6359 var vlq = toVLQSigned(aValue);
6360
6361 do {
6362 digit = vlq & VLQ_BASE_MASK;
6363 vlq >>>= VLQ_BASE_SHIFT;
6364 if (vlq > 0) {
6365 // There are still more digits in this value, so we must make sure the
6366 // continuation bit is marked.
6367 digit |= VLQ_CONTINUATION_BIT;
6368 }
6369 encoded += base64.encode(digit);
6370 } while (vlq > 0);
6371
6372 return encoded;
6373 };
6374
6375 /**
6376 * Decodes the next base 64 VLQ value from the given string and returns the
6377 * value and the rest of the string via the out parameter.
6378 */
6379 var decode$1 = function base64VLQ_decode(aStr, aIndex, aOutParam) {
6380 var strLen = aStr.length;
6381 var result = 0;
6382 var shift = 0;
6383 var continuation, digit;
6384
6385 do {
6386 if (aIndex >= strLen) {
6387 throw new Error("Expected more digits in base 64 VLQ value.");
6388 }
6389
6390 digit = base64.decode(aStr.charCodeAt(aIndex++));
6391 if (digit === -1) {
6392 throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
6393 }
6394
6395 continuation = !!(digit & VLQ_CONTINUATION_BIT);
6396 digit &= VLQ_BASE_MASK;
6397 result = result + (digit << shift);
6398 shift += VLQ_BASE_SHIFT;
6399 } while (continuation);
6400
6401 aOutParam.value = fromVLQSigned(result);
6402 aOutParam.rest = aIndex;
6403 };
6404
6405 var base64Vlq = {
6406 encode: encode$1,
6407 decode: decode$1
6408 };
6409
6410 function createCommonjsModule(fn, module) {
6411 return module = { exports: {} }, fn(module, module.exports), module.exports;
6412 }
6413
6414 function getCjsExportFromNamespace (n) {
6415 return n && n['default'] || n;
6416 }
6417
6418 var util = createCommonjsModule(function (module, exports) {
6419 /* -*- Mode: js; js-indent-level: 2; -*- */
6420 /*
6421 * Copyright 2011 Mozilla Foundation and contributors
6422 * Licensed under the New BSD license. See LICENSE or:
6423 * http://opensource.org/licenses/BSD-3-Clause
6424 */
6425
6426 /**
6427 * This is a helper function for getting values from parameter/options
6428 * objects.
6429 *
6430 * @param args The object we are extracting values from
6431 * @param name The name of the property we are getting.
6432 * @param defaultValue An optional value to return if the property is missing
6433 * from the object. If this is not specified and the property is missing, an
6434 * error will be thrown.
6435 */
6436 function getArg(aArgs, aName, aDefaultValue) {
6437 if (aName in aArgs) {
6438 return aArgs[aName];
6439 } else if (arguments.length === 3) {
6440 return aDefaultValue;
6441 } else {
6442 throw new Error('"' + aName + '" is a required argument.');
6443 }
6444 }
6445 exports.getArg = getArg;
6446
6447 var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
6448 var dataUrlRegexp = /^data:.+\,.+$/;
6449
6450 function urlParse(aUrl) {
6451 var match = aUrl.match(urlRegexp);
6452 if (!match) {
6453 return null;
6454 }
6455 return {
6456 scheme: match[1],
6457 auth: match[2],
6458 host: match[3],
6459 port: match[4],
6460 path: match[5]
6461 };
6462 }
6463 exports.urlParse = urlParse;
6464
6465 function urlGenerate(aParsedUrl) {
6466 var url = '';
6467 if (aParsedUrl.scheme) {
6468 url += aParsedUrl.scheme + ':';
6469 }
6470 url += '//';
6471 if (aParsedUrl.auth) {
6472 url += aParsedUrl.auth + '@';
6473 }
6474 if (aParsedUrl.host) {
6475 url += aParsedUrl.host;
6476 }
6477 if (aParsedUrl.port) {
6478 url += ":" + aParsedUrl.port;
6479 }
6480 if (aParsedUrl.path) {
6481 url += aParsedUrl.path;
6482 }
6483 return url;
6484 }
6485 exports.urlGenerate = urlGenerate;
6486
6487 /**
6488 * Normalizes a path, or the path portion of a URL:
6489 *
6490 * - Replaces consecutive slashes with one slash.
6491 * - Removes unnecessary '.' parts.
6492 * - Removes unnecessary '<dir>/..' parts.
6493 *
6494 * Based on code in the Node.js 'path' core module.
6495 *
6496 * @param aPath The path or url to normalize.
6497 */
6498 function normalize(aPath) {
6499 var path = aPath;
6500 var url = urlParse(aPath);
6501 if (url) {
6502 if (!url.path) {
6503 return aPath;
6504 }
6505 path = url.path;
6506 }
6507 var isAbsolute = exports.isAbsolute(path);
6508
6509 var parts = path.split(/\/+/);
6510 for (var part, up = 0, i = parts.length - 1; i >= 0; i--) {
6511 part = parts[i];
6512 if (part === '.') {
6513 parts.splice(i, 1);
6514 } else if (part === '..') {
6515 up++;
6516 } else if (up > 0) {
6517 if (part === '') {
6518 // The first part is blank if the path is absolute. Trying to go
6519 // above the root is a no-op. Therefore we can remove all '..' parts
6520 // directly after the root.
6521 parts.splice(i + 1, up);
6522 up = 0;
6523 } else {
6524 parts.splice(i, 2);
6525 up--;
6526 }
6527 }
6528 }
6529 path = parts.join('/');
6530
6531 if (path === '') {
6532 path = isAbsolute ? '/' : '.';
6533 }
6534
6535 if (url) {
6536 url.path = path;
6537 return urlGenerate(url);
6538 }
6539 return path;
6540 }
6541 exports.normalize = normalize;
6542
6543 /**
6544 * Joins two paths/URLs.
6545 *
6546 * @param aRoot The root path or URL.
6547 * @param aPath The path or URL to be joined with the root.
6548 *
6549 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
6550 * scheme-relative URL: Then the scheme of aRoot, if any, is prepended
6551 * first.
6552 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
6553 * is updated with the result and aRoot is returned. Otherwise the result
6554 * is returned.
6555 * - If aPath is absolute, the result is aPath.
6556 * - Otherwise the two paths are joined with a slash.
6557 * - Joining for example 'http://' and 'www.example.com' is also supported.
6558 */
6559 function join(aRoot, aPath) {
6560 if (aRoot === "") {
6561 aRoot = ".";
6562 }
6563 if (aPath === "") {
6564 aPath = ".";
6565 }
6566 var aPathUrl = urlParse(aPath);
6567 var aRootUrl = urlParse(aRoot);
6568 if (aRootUrl) {
6569 aRoot = aRootUrl.path || '/';
6570 }
6571
6572 // `join(foo, '//www.example.org')`
6573 if (aPathUrl && !aPathUrl.scheme) {
6574 if (aRootUrl) {
6575 aPathUrl.scheme = aRootUrl.scheme;
6576 }
6577 return urlGenerate(aPathUrl);
6578 }
6579
6580 if (aPathUrl || aPath.match(dataUrlRegexp)) {
6581 return aPath;
6582 }
6583
6584 // `join('http://', 'www.example.com')`
6585 if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
6586 aRootUrl.host = aPath;
6587 return urlGenerate(aRootUrl);
6588 }
6589
6590 var joined = aPath.charAt(0) === '/'
6591 ? aPath
6592 : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath);
6593
6594 if (aRootUrl) {
6595 aRootUrl.path = joined;
6596 return urlGenerate(aRootUrl);
6597 }
6598 return joined;
6599 }
6600 exports.join = join;
6601
6602 exports.isAbsolute = function (aPath) {
6603 return aPath.charAt(0) === '/' || urlRegexp.test(aPath);
6604 };
6605
6606 /**
6607 * Make a path relative to a URL or another path.
6608 *
6609 * @param aRoot The root path or URL.
6610 * @param aPath The path or URL to be made relative to aRoot.
6611 */
6612 function relative(aRoot, aPath) {
6613 if (aRoot === "") {
6614 aRoot = ".";
6615 }
6616
6617 aRoot = aRoot.replace(/\/$/, '');
6618
6619 // It is possible for the path to be above the root. In this case, simply
6620 // checking whether the root is a prefix of the path won't work. Instead, we
6621 // need to remove components from the root one by one, until either we find
6622 // a prefix that fits, or we run out of components to remove.
6623 var level = 0;
6624 while (aPath.indexOf(aRoot + '/') !== 0) {
6625 var index = aRoot.lastIndexOf("/");
6626 if (index < 0) {
6627 return aPath;
6628 }
6629
6630 // If the only part of the root that is left is the scheme (i.e. http://,
6631 // file:///, etc.), one or more slashes (/), or simply nothing at all, we
6632 // have exhausted all components, so the path is not relative to the root.
6633 aRoot = aRoot.slice(0, index);
6634 if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
6635 return aPath;
6636 }
6637
6638 ++level;
6639 }
6640
6641 // Make sure we add a "../" for each component we removed from the root.
6642 return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
6643 }
6644 exports.relative = relative;
6645
6646 var supportsNullProto = (function () {
6647 var obj = Object.create(null);
6648 return !('__proto__' in obj);
6649 }());
6650
6651 function identity (s) {
6652 return s;
6653 }
6654
6655 /**
6656 * Because behavior goes wacky when you set `__proto__` on objects, we
6657 * have to prefix all the strings in our set with an arbitrary character.
6658 *
6659 * See https://github.com/mozilla/source-map/pull/31 and
6660 * https://github.com/mozilla/source-map/issues/30
6661 *
6662 * @param String aStr
6663 */
6664 function toSetString(aStr) {
6665 if (isProtoString(aStr)) {
6666 return '$' + aStr;
6667 }
6668
6669 return aStr;
6670 }
6671 exports.toSetString = supportsNullProto ? identity : toSetString;
6672
6673 function fromSetString(aStr) {
6674 if (isProtoString(aStr)) {
6675 return aStr.slice(1);
6676 }
6677
6678 return aStr;
6679 }
6680 exports.fromSetString = supportsNullProto ? identity : fromSetString;
6681
6682 function isProtoString(s) {
6683 if (!s) {
6684 return false;
6685 }
6686
6687 var length = s.length;
6688
6689 if (length < 9 /* "__proto__".length */) {
6690 return false;
6691 }
6692
6693 if (s.charCodeAt(length - 1) !== 95 /* '_' */ ||
6694 s.charCodeAt(length - 2) !== 95 /* '_' */ ||
6695 s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
6696 s.charCodeAt(length - 4) !== 116 /* 't' */ ||
6697 s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
6698 s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
6699 s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
6700 s.charCodeAt(length - 8) !== 95 /* '_' */ ||
6701 s.charCodeAt(length - 9) !== 95 /* '_' */) {
6702 return false;
6703 }
6704
6705 for (var i = length - 10; i >= 0; i--) {
6706 if (s.charCodeAt(i) !== 36 /* '$' */) {
6707 return false;
6708 }
6709 }
6710
6711 return true;
6712 }
6713
6714 /**
6715 * Comparator between two mappings where the original positions are compared.
6716 *
6717 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
6718 * mappings with the same original source/line/column, but different generated
6719 * line and column the same. Useful when searching for a mapping with a
6720 * stubbed out mapping.
6721 */
6722 function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
6723 var cmp = strcmp(mappingA.source, mappingB.source);
6724 if (cmp !== 0) {
6725 return cmp;
6726 }
6727
6728 cmp = mappingA.originalLine - mappingB.originalLine;
6729 if (cmp !== 0) {
6730 return cmp;
6731 }
6732
6733 cmp = mappingA.originalColumn - mappingB.originalColumn;
6734 if (cmp !== 0 || onlyCompareOriginal) {
6735 return cmp;
6736 }
6737
6738 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
6739 if (cmp !== 0) {
6740 return cmp;
6741 }
6742
6743 cmp = mappingA.generatedLine - mappingB.generatedLine;
6744 if (cmp !== 0) {
6745 return cmp;
6746 }
6747
6748 return strcmp(mappingA.name, mappingB.name);
6749 }
6750 exports.compareByOriginalPositions = compareByOriginalPositions;
6751
6752 /**
6753 * Comparator between two mappings with deflated source and name indices where
6754 * the generated positions are compared.
6755 *
6756 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
6757 * mappings with the same generated line and column, but different
6758 * source/name/original line and column the same. Useful when searching for a
6759 * mapping with a stubbed out mapping.
6760 */
6761 function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
6762 var cmp = mappingA.generatedLine - mappingB.generatedLine;
6763 if (cmp !== 0) {
6764 return cmp;
6765 }
6766
6767 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
6768 if (cmp !== 0 || onlyCompareGenerated) {
6769 return cmp;
6770 }
6771
6772 cmp = strcmp(mappingA.source, mappingB.source);
6773 if (cmp !== 0) {
6774 return cmp;
6775 }
6776
6777 cmp = mappingA.originalLine - mappingB.originalLine;
6778 if (cmp !== 0) {
6779 return cmp;
6780 }
6781
6782 cmp = mappingA.originalColumn - mappingB.originalColumn;
6783 if (cmp !== 0) {
6784 return cmp;
6785 }
6786
6787 return strcmp(mappingA.name, mappingB.name);
6788 }
6789 exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;
6790
6791 function strcmp(aStr1, aStr2) {
6792 if (aStr1 === aStr2) {
6793 return 0;
6794 }
6795
6796 if (aStr1 === null) {
6797 return 1; // aStr2 !== null
6798 }
6799
6800 if (aStr2 === null) {
6801 return -1; // aStr1 !== null
6802 }
6803
6804 if (aStr1 > aStr2) {
6805 return 1;
6806 }
6807
6808 return -1;
6809 }
6810
6811 /**
6812 * Comparator between two mappings with inflated source and name strings where
6813 * the generated positions are compared.
6814 */
6815 function compareByGeneratedPositionsInflated(mappingA, mappingB) {
6816 var cmp = mappingA.generatedLine - mappingB.generatedLine;
6817 if (cmp !== 0) {
6818 return cmp;
6819 }
6820
6821 cmp = mappingA.generatedColumn - mappingB.generatedColumn;
6822 if (cmp !== 0) {
6823 return cmp;
6824 }
6825
6826 cmp = strcmp(mappingA.source, mappingB.source);
6827 if (cmp !== 0) {
6828 return cmp;
6829 }
6830
6831 cmp = mappingA.originalLine - mappingB.originalLine;
6832 if (cmp !== 0) {
6833 return cmp;
6834 }
6835
6836 cmp = mappingA.originalColumn - mappingB.originalColumn;
6837 if (cmp !== 0) {
6838 return cmp;
6839 }
6840
6841 return strcmp(mappingA.name, mappingB.name);
6842 }
6843 exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;
6844
6845 /**
6846 * Strip any JSON XSSI avoidance prefix from the string (as documented
6847 * in the source maps specification), and then parse the string as
6848 * JSON.
6849 */
6850 function parseSourceMapInput(str) {
6851 return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ''));
6852 }
6853 exports.parseSourceMapInput = parseSourceMapInput;
6854
6855 /**
6856 * Compute the URL of a source given the the source root, the source's
6857 * URL, and the source map's URL.
6858 */
6859 function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
6860 sourceURL = sourceURL || '';
6861
6862 if (sourceRoot) {
6863 // This follows what Chrome does.
6864 if (sourceRoot[sourceRoot.length - 1] !== '/' && sourceURL[0] !== '/') {
6865 sourceRoot += '/';
6866 }
6867 // The spec says:
6868 // Line 4: An optional source root, useful for relocating source
6869 // files on a server or removing repeated values in the
6870 // “sources” entry. This value is prepended to the individual
6871 // entries in the “source” field.
6872 sourceURL = sourceRoot + sourceURL;
6873 }
6874
6875 // Historically, SourceMapConsumer did not take the sourceMapURL as
6876 // a parameter. This mode is still somewhat supported, which is why
6877 // this code block is conditional. However, it's preferable to pass
6878 // the source map URL to SourceMapConsumer, so that this function
6879 // can implement the source URL resolution algorithm as outlined in
6880 // the spec. This block is basically the equivalent of:
6881 // new URL(sourceURL, sourceMapURL).toString()
6882 // ... except it avoids using URL, which wasn't available in the
6883 // older releases of node still supported by this library.
6884 //
6885 // The spec says:
6886 // If the sources are not absolute URLs after prepending of the
6887 // “sourceRoot”, the sources are resolved relative to the
6888 // SourceMap (like resolving script src in a html document).
6889 if (sourceMapURL) {
6890 var parsed = urlParse(sourceMapURL);
6891 if (!parsed) {
6892 throw new Error("sourceMapURL could not be parsed");
6893 }
6894 if (parsed.path) {
6895 // Strip the last path component, but keep the "/".
6896 var index = parsed.path.lastIndexOf('/');
6897 if (index >= 0) {
6898 parsed.path = parsed.path.substring(0, index + 1);
6899 }
6900 }
6901 sourceURL = join(urlGenerate(parsed), sourceURL);
6902 }
6903
6904 return normalize(sourceURL);
6905 }
6906 exports.computeSourceURL = computeSourceURL;
6907 });
6908 var util_1 = util.getArg;
6909 var util_2 = util.urlParse;
6910 var util_3 = util.urlGenerate;
6911 var util_4 = util.normalize;
6912 var util_5 = util.join;
6913 var util_6 = util.isAbsolute;
6914 var util_7 = util.relative;
6915 var util_8 = util.toSetString;
6916 var util_9 = util.fromSetString;
6917 var util_10 = util.compareByOriginalPositions;
6918 var util_11 = util.compareByGeneratedPositionsDeflated;
6919 var util_12 = util.compareByGeneratedPositionsInflated;
6920 var util_13 = util.parseSourceMapInput;
6921 var util_14 = util.computeSourceURL;
6922
6923 /* -*- Mode: js; js-indent-level: 2; -*- */
6924 /*
6925 * Copyright 2011 Mozilla Foundation and contributors
6926 * Licensed under the New BSD license. See LICENSE or:
6927 * http://opensource.org/licenses/BSD-3-Clause
6928 */
6929
6930
6931 var has = Object.prototype.hasOwnProperty;
6932 var hasNativeMap = typeof Map !== "undefined";
6933
6934 /**
6935 * A data structure which is a combination of an array and a set. Adding a new
6936 * member is O(1), testing for membership is O(1), and finding the index of an
6937 * element is O(1). Removing elements from the set is not supported. Only
6938 * strings are supported for membership.
6939 */
6940 function ArraySet() {
6941 this._array = [];
6942 this._set = hasNativeMap ? new Map() : Object.create(null);
6943 }
6944
6945 /**
6946 * Static method for creating ArraySet instances from an existing array.
6947 */
6948 ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
6949 var set = new ArraySet();
6950 for (var i = 0, len = aArray.length; i < len; i++) {
6951 set.add(aArray[i], aAllowDuplicates);
6952 }
6953 return set;
6954 };
6955
6956 /**
6957 * Return how many unique items are in this ArraySet. If duplicates have been
6958 * added, than those do not count towards the size.
6959 *
6960 * @returns Number
6961 */
6962 ArraySet.prototype.size = function ArraySet_size() {
6963 return hasNativeMap ? this._set.size : Object.getOwnPropertyNames(this._set).length;
6964 };
6965
6966 /**
6967 * Add the given string to this set.
6968 *
6969 * @param String aStr
6970 */
6971 ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
6972 var sStr = hasNativeMap ? aStr : util.toSetString(aStr);
6973 var isDuplicate = hasNativeMap ? this.has(aStr) : has.call(this._set, sStr);
6974 var idx = this._array.length;
6975 if (!isDuplicate || aAllowDuplicates) {
6976 this._array.push(aStr);
6977 }
6978 if (!isDuplicate) {
6979 if (hasNativeMap) {
6980 this._set.set(aStr, idx);
6981 } else {
6982 this._set[sStr] = idx;
6983 }
6984 }
6985 };
6986
6987 /**
6988 * Is the given string a member of this set?
6989 *
6990 * @param String aStr
6991 */
6992 ArraySet.prototype.has = function ArraySet_has(aStr) {
6993 if (hasNativeMap) {
6994 return this._set.has(aStr);
6995 } else {
6996 var sStr = util.toSetString(aStr);
6997 return has.call(this._set, sStr);
6998 }
6999 };
7000
7001 /**
7002 * What is the index of the given string in the array?
7003 *
7004 * @param String aStr
7005 */
7006 ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
7007 if (hasNativeMap) {
7008 var idx = this._set.get(aStr);
7009 if (idx >= 0) {
7010 return idx;
7011 }
7012 } else {
7013 var sStr = util.toSetString(aStr);
7014 if (has.call(this._set, sStr)) {
7015 return this._set[sStr];
7016 }
7017 }
7018
7019 throw new Error('"' + aStr + '" is not in the set.');
7020 };
7021
7022 /**
7023 * What is the element at the given index?
7024 *
7025 * @param Number aIdx
7026 */
7027 ArraySet.prototype.at = function ArraySet_at(aIdx) {
7028 if (aIdx >= 0 && aIdx < this._array.length) {
7029 return this._array[aIdx];
7030 }
7031 throw new Error('No element indexed by ' + aIdx);
7032 };
7033
7034 /**
7035 * Returns the array representation of this set (which has the proper indices
7036 * indicated by indexOf). Note that this is a copy of the internal array used
7037 * for storing the members so that no one can mess with internal state.
7038 */
7039 ArraySet.prototype.toArray = function ArraySet_toArray() {
7040 return this._array.slice();
7041 };
7042
7043 var ArraySet_1 = ArraySet;
7044
7045 var arraySet = {
7046 ArraySet: ArraySet_1
7047 };
7048
7049 /* -*- Mode: js; js-indent-level: 2; -*- */
7050 /*
7051 * Copyright 2014 Mozilla Foundation and contributors
7052 * Licensed under the New BSD license. See LICENSE or:
7053 * http://opensource.org/licenses/BSD-3-Clause
7054 */
7055
7056
7057
7058 /**
7059 * Determine whether mappingB is after mappingA with respect to generated
7060 * position.
7061 */
7062 function generatedPositionAfter(mappingA, mappingB) {
7063 // Optimized for most common case
7064 var lineA = mappingA.generatedLine;
7065 var lineB = mappingB.generatedLine;
7066 var columnA = mappingA.generatedColumn;
7067 var columnB = mappingB.generatedColumn;
7068 return lineB > lineA || lineB == lineA && columnB >= columnA ||
7069 util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
7070 }
7071
7072 /**
7073 * A data structure to provide a sorted view of accumulated mappings in a
7074 * performance conscious manner. It trades a neglibable overhead in general
7075 * case for a large speedup in case of mappings being added in order.
7076 */
7077 function MappingList() {
7078 this._array = [];
7079 this._sorted = true;
7080 // Serves as infimum
7081 this._last = {generatedLine: -1, generatedColumn: 0};
7082 }
7083
7084 /**
7085 * Iterate through internal items. This method takes the same arguments that
7086 * `Array.prototype.forEach` takes.
7087 *
7088 * NOTE: The order of the mappings is NOT guaranteed.
7089 */
7090 MappingList.prototype.unsortedForEach =
7091 function MappingList_forEach(aCallback, aThisArg) {
7092 this._array.forEach(aCallback, aThisArg);
7093 };
7094
7095 /**
7096 * Add the given source mapping.
7097 *
7098 * @param Object aMapping
7099 */
7100 MappingList.prototype.add = function MappingList_add(aMapping) {
7101 if (generatedPositionAfter(this._last, aMapping)) {
7102 this._last = aMapping;
7103 this._array.push(aMapping);
7104 } else {
7105 this._sorted = false;
7106 this._array.push(aMapping);
7107 }
7108 };
7109
7110 /**
7111 * Returns the flat, sorted array of mappings. The mappings are sorted by
7112 * generated position.
7113 *
7114 * WARNING: This method returns internal data without copying, for
7115 * performance. The return value must NOT be mutated, and should be treated as
7116 * an immutable borrow. If you want to take ownership, you must make your own
7117 * copy.
7118 */
7119 MappingList.prototype.toArray = function MappingList_toArray() {
7120 if (!this._sorted) {
7121 this._array.sort(util.compareByGeneratedPositionsInflated);
7122 this._sorted = true;
7123 }
7124 return this._array;
7125 };
7126
7127 var MappingList_1 = MappingList;
7128
7129 var mappingList = {
7130 MappingList: MappingList_1
7131 };
7132
7133 /* -*- Mode: js; js-indent-level: 2; -*- */
7134 /*
7135 * Copyright 2011 Mozilla Foundation and contributors
7136 * Licensed under the New BSD license. See LICENSE or:
7137 * http://opensource.org/licenses/BSD-3-Clause
7138 */
7139
7140
7141
7142 var ArraySet$1 = arraySet.ArraySet;
7143 var MappingList$1 = mappingList.MappingList;
7144
7145 /**
7146 * An instance of the SourceMapGenerator represents a source map which is
7147 * being built incrementally. You may pass an object with the following
7148 * properties:
7149 *
7150 * - file: The filename of the generated source.
7151 * - sourceRoot: A root for all relative URLs in this source map.
7152 */
7153 function SourceMapGenerator(aArgs) {
7154 if (!aArgs) {
7155 aArgs = {};
7156 }
7157 this._file = util.getArg(aArgs, 'file', null);
7158 this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
7159 this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
7160 this._sources = new ArraySet$1();
7161 this._names = new ArraySet$1();
7162 this._mappings = new MappingList$1();
7163 this._sourcesContents = null;
7164 }
7165
7166 SourceMapGenerator.prototype._version = 3;
7167
7168 /**
7169 * Creates a new SourceMapGenerator based on a SourceMapConsumer
7170 *
7171 * @param aSourceMapConsumer The SourceMap.
7172 */
7173 SourceMapGenerator.fromSourceMap =
7174 function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
7175 var sourceRoot = aSourceMapConsumer.sourceRoot;
7176 var generator = new SourceMapGenerator({
7177 file: aSourceMapConsumer.file,
7178 sourceRoot: sourceRoot
7179 });
7180 aSourceMapConsumer.eachMapping(function (mapping) {
7181 var newMapping = {
7182 generated: {
7183 line: mapping.generatedLine,
7184 column: mapping.generatedColumn
7185 }
7186 };
7187
7188 if (mapping.source != null) {
7189 newMapping.source = mapping.source;
7190 if (sourceRoot != null) {
7191 newMapping.source = util.relative(sourceRoot, newMapping.source);
7192 }
7193
7194 newMapping.original = {
7195 line: mapping.originalLine,
7196 column: mapping.originalColumn
7197 };
7198
7199 if (mapping.name != null) {
7200 newMapping.name = mapping.name;
7201 }
7202 }
7203
7204 generator.addMapping(newMapping);
7205 });
7206 aSourceMapConsumer.sources.forEach(function (sourceFile) {
7207 var sourceRelative = sourceFile;
7208 if (sourceRoot !== null) {
7209 sourceRelative = util.relative(sourceRoot, sourceFile);
7210 }
7211
7212 if (!generator._sources.has(sourceRelative)) {
7213 generator._sources.add(sourceRelative);
7214 }
7215
7216 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
7217 if (content != null) {
7218 generator.setSourceContent(sourceFile, content);
7219 }
7220 });
7221 return generator;
7222 };
7223
7224 /**
7225 * Add a single mapping from original source line and column to the generated
7226 * source's line and column for this source map being created. The mapping
7227 * object should have the following properties:
7228 *
7229 * - generated: An object with the generated line and column positions.
7230 * - original: An object with the original line and column positions.
7231 * - source: The original source file (relative to the sourceRoot).
7232 * - name: An optional original token name for this mapping.
7233 */
7234 SourceMapGenerator.prototype.addMapping =
7235 function SourceMapGenerator_addMapping(aArgs) {
7236 var generated = util.getArg(aArgs, 'generated');
7237 var original = util.getArg(aArgs, 'original', null);
7238 var source = util.getArg(aArgs, 'source', null);
7239 var name = util.getArg(aArgs, 'name', null);
7240
7241 if (!this._skipValidation) {
7242 this._validateMapping(generated, original, source, name);
7243 }
7244
7245 if (source != null) {
7246 source = String(source);
7247 if (!this._sources.has(source)) {
7248 this._sources.add(source);
7249 }
7250 }
7251
7252 if (name != null) {
7253 name = String(name);
7254 if (!this._names.has(name)) {
7255 this._names.add(name);
7256 }
7257 }
7258
7259 this._mappings.add({
7260 generatedLine: generated.line,
7261 generatedColumn: generated.column,
7262 originalLine: original != null && original.line,
7263 originalColumn: original != null && original.column,
7264 source: source,
7265 name: name
7266 });
7267 };
7268
7269 /**
7270 * Set the source content for a source file.
7271 */
7272 SourceMapGenerator.prototype.setSourceContent =
7273 function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
7274 var source = aSourceFile;
7275 if (this._sourceRoot != null) {
7276 source = util.relative(this._sourceRoot, source);
7277 }
7278
7279 if (aSourceContent != null) {
7280 // Add the source content to the _sourcesContents map.
7281 // Create a new _sourcesContents map if the property is null.
7282 if (!this._sourcesContents) {
7283 this._sourcesContents = Object.create(null);
7284 }
7285 this._sourcesContents[util.toSetString(source)] = aSourceContent;
7286 } else if (this._sourcesContents) {
7287 // Remove the source file from the _sourcesContents map.
7288 // If the _sourcesContents map is empty, set the property to null.
7289 delete this._sourcesContents[util.toSetString(source)];
7290 if (Object.keys(this._sourcesContents).length === 0) {
7291 this._sourcesContents = null;
7292 }
7293 }
7294 };
7295
7296 /**
7297 * Applies the mappings of a sub-source-map for a specific source file to the
7298 * source map being generated. Each mapping to the supplied source file is
7299 * rewritten using the supplied source map. Note: The resolution for the
7300 * resulting mappings is the minimium of this map and the supplied map.
7301 *
7302 * @param aSourceMapConsumer The source map to be applied.
7303 * @param aSourceFile Optional. The filename of the source file.
7304 * If omitted, SourceMapConsumer's file property will be used.
7305 * @param aSourceMapPath Optional. The dirname of the path to the source map
7306 * to be applied. If relative, it is relative to the SourceMapConsumer.
7307 * This parameter is needed when the two source maps aren't in the same
7308 * directory, and the source map to be applied contains relative source
7309 * paths. If so, those relative source paths need to be rewritten
7310 * relative to the SourceMapGenerator.
7311 */
7312 SourceMapGenerator.prototype.applySourceMap =
7313 function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
7314 var sourceFile = aSourceFile;
7315 // If aSourceFile is omitted, we will use the file property of the SourceMap
7316 if (aSourceFile == null) {
7317 if (aSourceMapConsumer.file == null) {
7318 throw new Error(
7319 'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
7320 'or the source map\'s "file" property. Both were omitted.'
7321 );
7322 }
7323 sourceFile = aSourceMapConsumer.file;
7324 }
7325 var sourceRoot = this._sourceRoot;
7326 // Make "sourceFile" relative if an absolute Url is passed.
7327 if (sourceRoot != null) {
7328 sourceFile = util.relative(sourceRoot, sourceFile);
7329 }
7330 // Applying the SourceMap can add and remove items from the sources and
7331 // the names array.
7332 var newSources = new ArraySet$1();
7333 var newNames = new ArraySet$1();
7334
7335 // Find mappings for the "sourceFile"
7336 this._mappings.unsortedForEach(function (mapping) {
7337 if (mapping.source === sourceFile && mapping.originalLine != null) {
7338 // Check if it can be mapped by the source map, then update the mapping.
7339 var original = aSourceMapConsumer.originalPositionFor({
7340 line: mapping.originalLine,
7341 column: mapping.originalColumn
7342 });
7343 if (original.source != null) {
7344 // Copy mapping
7345 mapping.source = original.source;
7346 if (aSourceMapPath != null) {
7347 mapping.source = util.join(aSourceMapPath, mapping.source);
7348 }
7349 if (sourceRoot != null) {
7350 mapping.source = util.relative(sourceRoot, mapping.source);
7351 }
7352 mapping.originalLine = original.line;
7353 mapping.originalColumn = original.column;
7354 if (original.name != null) {
7355 mapping.name = original.name;
7356 }
7357 }
7358 }
7359
7360 var source = mapping.source;
7361 if (source != null && !newSources.has(source)) {
7362 newSources.add(source);
7363 }
7364
7365 var name = mapping.name;
7366 if (name != null && !newNames.has(name)) {
7367 newNames.add(name);
7368 }
7369
7370 }, this);
7371 this._sources = newSources;
7372 this._names = newNames;
7373
7374 // Copy sourcesContents of applied map.
7375 aSourceMapConsumer.sources.forEach(function (sourceFile) {
7376 var content = aSourceMapConsumer.sourceContentFor(sourceFile);
7377 if (content != null) {
7378 if (aSourceMapPath != null) {
7379 sourceFile = util.join(aSourceMapPath, sourceFile);
7380 }
7381 if (sourceRoot != null) {
7382 sourceFile = util.relative(sourceRoot, sourceFile);
7383 }
7384 this.setSourceContent(sourceFile, content);
7385 }
7386 }, this);
7387 };
7388
7389 /**
7390 * A mapping can have one of the three levels of data:
7391 *
7392 * 1. Just the generated position.
7393 * 2. The Generated position, original position, and original source.
7394 * 3. Generated and original position, original source, as well as a name
7395 * token.
7396 *
7397 * To maintain consistency, we validate that any new mapping being added falls
7398 * in to one of these categories.
7399 */
7400 SourceMapGenerator.prototype._validateMapping =
7401 function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
7402 aName) {
7403 // When aOriginal is truthy but has empty values for .line and .column,
7404 // it is most likely a programmer error. In this case we throw a very
7405 // specific error message to try to guide them the right way.
7406 // For example: https://github.com/Polymer/polymer-bundler/pull/519
7407 if (aOriginal && typeof aOriginal.line !== 'number' && typeof aOriginal.column !== 'number') {
7408 throw new Error(
7409 'original.line and original.column are not numbers -- you probably meant to omit ' +
7410 'the original mapping entirely and only map the generated position. If so, pass ' +
7411 'null for the original mapping instead of an object with empty or null values.'
7412 );
7413 }
7414
7415 if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
7416 && aGenerated.line > 0 && aGenerated.column >= 0
7417 && !aOriginal && !aSource && !aName) {
7418 // Case 1.
7419 return;
7420 }
7421 else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
7422 && aOriginal && 'line' in aOriginal && 'column' in aOriginal
7423 && aGenerated.line > 0 && aGenerated.column >= 0
7424 && aOriginal.line > 0 && aOriginal.column >= 0
7425 && aSource) {
7426 // Cases 2 and 3.
7427 return;
7428 }
7429 else {
7430 throw new Error('Invalid mapping: ' + JSON.stringify({
7431 generated: aGenerated,
7432 source: aSource,
7433 original: aOriginal,
7434 name: aName
7435 }));
7436 }
7437 };
7438
7439 /**
7440 * Serialize the accumulated mappings in to the stream of base 64 VLQs
7441 * specified by the source map format.
7442 */
7443 SourceMapGenerator.prototype._serializeMappings =
7444 function SourceMapGenerator_serializeMappings() {
7445 var previousGeneratedColumn = 0;
7446 var previousGeneratedLine = 1;
7447 var previousOriginalColumn = 0;
7448 var previousOriginalLine = 0;
7449 var previousName = 0;
7450 var previousSource = 0;
7451 var result = '';
7452 var next;
7453 var mapping;
7454 var nameIdx;
7455 var sourceIdx;
7456
7457 var mappings = this._mappings.toArray();
7458 for (var i = 0, len = mappings.length; i < len; i++) {
7459 mapping = mappings[i];
7460 next = '';
7461
7462 if (mapping.generatedLine !== previousGeneratedLine) {
7463 previousGeneratedColumn = 0;
7464 while (mapping.generatedLine !== previousGeneratedLine) {
7465 next += ';';
7466 previousGeneratedLine++;
7467 }
7468 }
7469 else {
7470 if (i > 0) {
7471 if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
7472 continue;
7473 }
7474 next += ',';
7475 }
7476 }
7477
7478 next += base64Vlq.encode(mapping.generatedColumn
7479 - previousGeneratedColumn);
7480 previousGeneratedColumn = mapping.generatedColumn;
7481
7482 if (mapping.source != null) {
7483 sourceIdx = this._sources.indexOf(mapping.source);
7484 next += base64Vlq.encode(sourceIdx - previousSource);
7485 previousSource = sourceIdx;
7486
7487 // lines are stored 0-based in SourceMap spec version 3
7488 next += base64Vlq.encode(mapping.originalLine - 1
7489 - previousOriginalLine);
7490 previousOriginalLine = mapping.originalLine - 1;
7491
7492 next += base64Vlq.encode(mapping.originalColumn
7493 - previousOriginalColumn);
7494 previousOriginalColumn = mapping.originalColumn;
7495
7496 if (mapping.name != null) {
7497 nameIdx = this._names.indexOf(mapping.name);
7498 next += base64Vlq.encode(nameIdx - previousName);
7499 previousName = nameIdx;
7500 }
7501 }
7502
7503 result += next;
7504 }
7505
7506 return result;
7507 };
7508
7509 SourceMapGenerator.prototype._generateSourcesContent =
7510 function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
7511 return aSources.map(function (source) {
7512 if (!this._sourcesContents) {
7513 return null;
7514 }
7515 if (aSourceRoot != null) {
7516 source = util.relative(aSourceRoot, source);
7517 }
7518 var key = util.toSetString(source);
7519 return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
7520 ? this._sourcesContents[key]
7521 : null;
7522 }, this);
7523 };
7524
7525 /**
7526 * Externalize the source map.
7527 */
7528 SourceMapGenerator.prototype.toJSON =
7529 function SourceMapGenerator_toJSON() {
7530 var map = {
7531 version: this._version,
7532 sources: this._sources.toArray(),
7533 names: this._names.toArray(),
7534 mappings: this._serializeMappings()
7535 };
7536 if (this._file != null) {
7537 map.file = this._file;
7538 }
7539 if (this._sourceRoot != null) {
7540 map.sourceRoot = this._sourceRoot;
7541 }
7542 if (this._sourcesContents) {
7543 map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
7544 }
7545
7546 return map;
7547 };
7548
7549 /**
7550 * Render the source map being generated to a string.
7551 */
7552 SourceMapGenerator.prototype.toString =
7553 function SourceMapGenerator_toString() {
7554 return JSON.stringify(this.toJSON());
7555 };
7556
7557 var SourceMapGenerator_1 = SourceMapGenerator;
7558
7559 var sourceMapGenerator = {
7560 SourceMapGenerator: SourceMapGenerator_1
7561 };
7562
7563 var SourceMapGenerator$1 = sourceMapGenerator.SourceMapGenerator;
7564 var trackNodes = {
7565 Atrule: true,
7566 Selector: true,
7567 Declaration: true
7568 };
7569
7570 var sourceMap = function generateSourceMap(handlers) {
7571 var map = new SourceMapGenerator$1();
7572 var line = 1;
7573 var column = 0;
7574 var generated = {
7575 line: 1,
7576 column: 0
7577 };
7578 var original = {
7579 line: 0, // should be zero to add first mapping
7580 column: 0
7581 };
7582 var sourceMappingActive = false;
7583 var activatedGenerated = {
7584 line: 1,
7585 column: 0
7586 };
7587 var activatedMapping = {
7588 generated: activatedGenerated
7589 };
7590
7591 var handlersNode = handlers.node;
7592 handlers.node = function(node) {
7593 if (node.loc && node.loc.start && trackNodes.hasOwnProperty(node.type)) {
7594 var nodeLine = node.loc.start.line;
7595 var nodeColumn = node.loc.start.column - 1;
7596
7597 if (original.line !== nodeLine ||
7598 original.column !== nodeColumn) {
7599 original.line = nodeLine;
7600 original.column = nodeColumn;
7601
7602 generated.line = line;
7603 generated.column = column;
7604
7605 if (sourceMappingActive) {
7606 sourceMappingActive = false;
7607 if (generated.line !== activatedGenerated.line ||
7608 generated.column !== activatedGenerated.column) {
7609 map.addMapping(activatedMapping);
7610 }
7611 }
7612
7613 sourceMappingActive = true;
7614 map.addMapping({
7615 source: node.loc.source,
7616 original: original,
7617 generated: generated
7618 });
7619 }
7620 }
7621
7622 handlersNode.call(this, node);
7623
7624 if (sourceMappingActive && trackNodes.hasOwnProperty(node.type)) {
7625 activatedGenerated.line = line;
7626 activatedGenerated.column = column;
7627 }
7628 };
7629
7630 var handlersChunk = handlers.chunk;
7631 handlers.chunk = function(chunk) {
7632 for (var i = 0; i < chunk.length; i++) {
7633 if (chunk.charCodeAt(i) === 10) { // \n
7634 line++;
7635 column = 0;
7636 } else {
7637 column++;
7638 }
7639 }
7640
7641 handlersChunk(chunk);
7642 };
7643
7644 var handlersResult = handlers.result;
7645 handlers.result = function() {
7646 if (sourceMappingActive) {
7647 map.addMapping(activatedMapping);
7648 }
7649
7650 return {
7651 css: handlersResult(),
7652 map: map
7653 };
7654 };
7655
7656 return handlers;
7657 };
7658
7659 var hasOwnProperty$3 = Object.prototype.hasOwnProperty;
7660
7661 function processChildren(node, delimeter) {
7662 var list = node.children;
7663 var prev = null;
7664
7665 if (typeof delimeter !== 'function') {
7666 list.forEach(this.node, this);
7667 } else {
7668 list.forEach(function(node) {
7669 if (prev !== null) {
7670 delimeter.call(this, prev);
7671 }
7672
7673 this.node(node);
7674 prev = node;
7675 }, this);
7676 }
7677 }
7678
7679 var create$1 = function createGenerator(config) {
7680 function processNode(node) {
7681 if (hasOwnProperty$3.call(types, node.type)) {
7682 types[node.type].call(this, node);
7683 } else {
7684 throw new Error('Unknown node type: ' + node.type);
7685 }
7686 }
7687
7688 var types = {};
7689
7690 if (config.node) {
7691 for (var name in config.node) {
7692 types[name] = config.node[name].generate;
7693 }
7694 }
7695
7696 return function(node, options) {
7697 var buffer = '';
7698 var handlers = {
7699 children: processChildren,
7700 node: processNode,
7701 chunk: function(chunk) {
7702 buffer += chunk;
7703 },
7704 result: function() {
7705 return buffer;
7706 }
7707 };
7708
7709 if (options) {
7710 if (typeof options.decorator === 'function') {
7711 handlers = options.decorator(handlers);
7712 }
7713
7714 if (options.sourceMap) {
7715 handlers = sourceMap(handlers);
7716 }
7717 }
7718
7719 handlers.node(node);
7720
7721 return handlers.result();
7722 };
7723 };
7724
7725 var create$2 = function createConvertors(walk) {
7726 return {
7727 fromPlainObject: function(ast) {
7728 walk(ast, {
7729 enter: function(node) {
7730 if (node.children && node.children instanceof List_1 === false) {
7731 node.children = new List_1().fromArray(node.children);
7732 }
7733 }
7734 });
7735
7736 return ast;
7737 },
7738 toPlainObject: function(ast) {
7739 walk(ast, {
7740 leave: function(node) {
7741 if (node.children && node.children instanceof List_1) {
7742 node.children = node.children.toArray();
7743 }
7744 }
7745 });
7746
7747 return ast;
7748 }
7749 };
7750 };
7751
7752 var hasOwnProperty$4 = Object.prototype.hasOwnProperty;
7753 var noop$3 = function() {};
7754
7755 function ensureFunction$1(value) {
7756 return typeof value === 'function' ? value : noop$3;
7757 }
7758
7759 function invokeForType(fn, type) {
7760 return function(node, item, list) {
7761 if (node.type === type) {
7762 fn.call(this, node, item, list);
7763 }
7764 };
7765 }
7766
7767 function getWalkersFromStructure(name, nodeType) {
7768 var structure = nodeType.structure;
7769 var walkers = [];
7770
7771 for (var key in structure) {
7772 if (hasOwnProperty$4.call(structure, key) === false) {
7773 continue;
7774 }
7775
7776 var fieldTypes = structure[key];
7777 var walker = {
7778 name: key,
7779 type: false,
7780 nullable: false
7781 };
7782
7783 if (!Array.isArray(structure[key])) {
7784 fieldTypes = [structure[key]];
7785 }
7786
7787 for (var i = 0; i < fieldTypes.length; i++) {
7788 var fieldType = fieldTypes[i];
7789 if (fieldType === null) {
7790 walker.nullable = true;
7791 } else if (typeof fieldType === 'string') {
7792 walker.type = 'node';
7793 } else if (Array.isArray(fieldType)) {
7794 walker.type = 'list';
7795 }
7796 }
7797
7798 if (walker.type) {
7799 walkers.push(walker);
7800 }
7801 }
7802
7803 if (walkers.length) {
7804 return {
7805 context: nodeType.walkContext,
7806 fields: walkers
7807 };
7808 }
7809
7810 return null;
7811 }
7812
7813 function getTypesFromConfig(config) {
7814 var types = {};
7815
7816 for (var name in config.node) {
7817 if (hasOwnProperty$4.call(config.node, name)) {
7818 var nodeType = config.node[name];
7819
7820 if (!nodeType.structure) {
7821 throw new Error('Missed `structure` field in `' + name + '` node type definition');
7822 }
7823
7824 types[name] = getWalkersFromStructure(name, nodeType);
7825 }
7826 }
7827
7828 return types;
7829 }
7830
7831 function createTypeIterator(config, reverse) {
7832 var fields = config.fields.slice();
7833 var contextName = config.context;
7834 var useContext = typeof contextName === 'string';
7835
7836 if (reverse) {
7837 fields.reverse();
7838 }
7839
7840 return function(node, context, walk) {
7841 var prevContextValue;
7842
7843 if (useContext) {
7844 prevContextValue = context[contextName];
7845 context[contextName] = node;
7846 }
7847
7848 for (var i = 0; i < fields.length; i++) {
7849 var field = fields[i];
7850 var ref = node[field.name];
7851
7852 if (!field.nullable || ref) {
7853 if (field.type === 'list') {
7854 if (reverse) {
7855 ref.forEachRight(walk);
7856 } else {
7857 ref.forEach(walk);
7858 }
7859 } else {
7860 walk(ref);
7861 }
7862 }
7863 }
7864
7865 if (useContext) {
7866 context[contextName] = prevContextValue;
7867 }
7868 };
7869 }
7870
7871 function createFastTraveralMap(iterators) {
7872 return {
7873 Atrule: {
7874 StyleSheet: iterators.StyleSheet,
7875 Atrule: iterators.Atrule,
7876 Rule: iterators.Rule,
7877 Block: iterators.Block
7878 },
7879 Rule: {
7880 StyleSheet: iterators.StyleSheet,
7881 Atrule: iterators.Atrule,
7882 Rule: iterators.Rule,
7883 Block: iterators.Block
7884 },
7885 Declaration: {
7886 StyleSheet: iterators.StyleSheet,
7887 Atrule: iterators.Atrule,
7888 Rule: iterators.Rule,
7889 Block: iterators.Block
7890 }
7891 };
7892 }
7893
7894 var create$3 = function createWalker(config) {
7895 var types = getTypesFromConfig(config);
7896 var iteratorsNatural = {};
7897 var iteratorsReverse = {};
7898
7899 for (var name in types) {
7900 if (hasOwnProperty$4.call(types, name) && types[name] !== null) {
7901 iteratorsNatural[name] = createTypeIterator(types[name], false);
7902 iteratorsReverse[name] = createTypeIterator(types[name], true);
7903 }
7904 }
7905
7906 var fastTraversalIteratorsNatural = createFastTraveralMap(iteratorsNatural);
7907 var fastTraversalIteratorsReverse = createFastTraveralMap(iteratorsReverse);
7908
7909 var walk = function(root, options) {
7910 function walkNode(node, item, list) {
7911 enter.call(context, node, item, list);
7912
7913 if (iterators.hasOwnProperty(node.type)) {
7914 iterators[node.type](node, context, walkNode);
7915 }
7916
7917 leave.call(context, node, item, list);
7918 }
7919
7920 var enter = noop$3;
7921 var leave = noop$3;
7922 var iterators = iteratorsNatural;
7923 var context = {
7924 root: root,
7925 stylesheet: null,
7926 atrule: null,
7927 atrulePrelude: null,
7928 rule: null,
7929 selector: null,
7930 block: null,
7931 declaration: null,
7932 function: null
7933 };
7934
7935 if (typeof options === 'function') {
7936 enter = options;
7937 } else if (options) {
7938 enter = ensureFunction$1(options.enter);
7939 leave = ensureFunction$1(options.leave);
7940
7941 if (options.reverse) {
7942 iterators = iteratorsReverse;
7943 }
7944
7945 if (options.visit) {
7946 if (fastTraversalIteratorsNatural.hasOwnProperty(options.visit)) {
7947 iterators = options.reverse
7948 ? fastTraversalIteratorsReverse[options.visit]
7949 : fastTraversalIteratorsNatural[options.visit];
7950 } else if (!types.hasOwnProperty(options.visit)) {
7951 throw new Error('Bad value `' + options.visit + '` for `visit` option (should be: ' + Object.keys(types).join(', ') + ')');
7952 }
7953
7954 enter = invokeForType(enter, options.visit);
7955 leave = invokeForType(leave, options.visit);
7956 }
7957 }
7958
7959 if (enter === noop$3 && leave === noop$3) {
7960 throw new Error('Neither `enter` nor `leave` walker handler is set or both aren\'t a function');
7961 }
7962
7963 // swap handlers in reverse mode to invert visit order
7964 if (options.reverse) {
7965 var tmp = enter;
7966 enter = leave;
7967 leave = tmp;
7968 }
7969
7970 walkNode(root);
7971 };
7972
7973 walk.find = function(ast, fn) {
7974 var found = null;
7975
7976 walk(ast, function(node, item, list) {
7977 if (found === null && fn.call(this, node, item, list)) {
7978 found = node;
7979 }
7980 });
7981
7982 return found;
7983 };
7984
7985 walk.findLast = function(ast, fn) {
7986 var found = null;
7987
7988 walk(ast, {
7989 reverse: true,
7990 enter: function(node, item, list) {
7991 if (found === null && fn.call(this, node, item, list)) {
7992 found = node;
7993 }
7994 }
7995 });
7996
7997 return found;
7998 };
7999
8000 walk.findAll = function(ast, fn) {
8001 var found = [];
8002
8003 walk(ast, function(node, item, list) {
8004 if (fn.call(this, node, item, list)) {
8005 found.push(node);
8006 }
8007 });
8008
8009 return found;
8010 };
8011
8012 return walk;
8013 };
8014
8015 var clone = function clone(node) {
8016 var result = {};
8017
8018 for (var key in node) {
8019 var value = node[key];
8020
8021 if (value) {
8022 if (Array.isArray(value) || value instanceof List_1) {
8023 value = value.map(clone);
8024 } else if (value.constructor === Object) {
8025 value = clone(value);
8026 }
8027 }
8028
8029 result[key] = value;
8030 }
8031
8032 return result;
8033 };
8034
8035 var hasOwnProperty$5 = Object.prototype.hasOwnProperty;
8036 var shape = {
8037 generic: true,
8038 types: {},
8039 properties: {},
8040 parseContext: {},
8041 scope: {},
8042 atrule: ['parse'],
8043 pseudo: ['parse'],
8044 node: ['name', 'structure', 'parse', 'generate', 'walkContext']
8045 };
8046
8047 function isObject(value) {
8048 return value && value.constructor === Object;
8049 }
8050
8051 function copy(value) {
8052 if (isObject(value)) {
8053 var res = {};
8054 for (var key in value) {
8055 if (hasOwnProperty$5.call(value, key)) {
8056 res[key] = value[key];
8057 }
8058 }
8059 return res;
8060 } else {
8061 return value;
8062 }
8063 }
8064
8065 function extend(dest, src) {
8066 for (var key in src) {
8067 if (hasOwnProperty$5.call(src, key)) {
8068 if (isObject(dest[key])) {
8069 extend(dest[key], copy(src[key]));
8070 } else {
8071 dest[key] = copy(src[key]);
8072 }
8073 }
8074 }
8075 }
8076
8077 function mix(dest, src, shape) {
8078 for (var key in shape) {
8079 if (hasOwnProperty$5.call(shape, key) === false) {
8080 continue;
8081 }
8082
8083 if (shape[key] === true) {
8084 if (key in src) {
8085 if (hasOwnProperty$5.call(src, key)) {
8086 dest[key] = copy(src[key]);
8087 }
8088 }
8089 } else if (shape[key]) {
8090 if (isObject(shape[key])) {
8091 var res = {};
8092 extend(res, dest[key]);
8093 extend(res, src[key]);
8094 dest[key] = res;
8095 } else if (Array.isArray(shape[key])) {
8096 var res = {};
8097 var innerShape = shape[key].reduce(function(s, k) {
8098 s[k] = true;
8099 return s;
8100 }, {});
8101 for (var name in dest[key]) {
8102 if (hasOwnProperty$5.call(dest[key], name)) {
8103 res[name] = {};
8104 if (dest[key] && dest[key][name]) {
8105 mix(res[name], dest[key][name], innerShape);
8106 }
8107 }
8108 }
8109 for (var name in src[key]) {
8110 if (hasOwnProperty$5.call(src[key], name)) {
8111 if (!res[name]) {
8112 res[name] = {};
8113 }
8114 if (src[key] && src[key][name]) {
8115 mix(res[name], src[key][name], innerShape);
8116 }
8117 }
8118 }
8119 dest[key] = res;
8120 }
8121 }
8122 }
8123 return dest;
8124 }
8125
8126 var mix_1 = function(dest, src) {
8127 return mix(dest, src, shape);
8128 };
8129
8130 function assign(dest, src) {
8131 for (var key in src) {
8132 dest[key] = src[key];
8133 }
8134
8135 return dest;
8136 }
8137
8138 function createSyntax(config) {
8139 var parse = create(config);
8140 var walk = create$3(config);
8141 var generate = create$1(config);
8142 var convert = create$2(walk);
8143
8144 var syntax = {
8145 List: List_1,
8146 SyntaxError: _SyntaxError,
8147 TokenStream: TokenStream_1,
8148 Lexer: Lexer_1,
8149
8150 vendorPrefix: names.vendorPrefix,
8151 keyword: names.keyword,
8152 property: names.property,
8153 isCustomProperty: names.isCustomProperty,
8154
8155 definitionSyntax: definitionSyntax,
8156 lexer: null,
8157 createLexer: function(config) {
8158 return new Lexer_1(config, syntax, syntax.lexer.structure);
8159 },
8160
8161 tokenize: tokenizer,
8162 parse: parse,
8163 walk: walk,
8164 generate: generate,
8165
8166 find: walk.find,
8167 findLast: walk.findLast,
8168 findAll: walk.findAll,
8169
8170 clone: clone,
8171 fromPlainObject: convert.fromPlainObject,
8172 toPlainObject: convert.toPlainObject,
8173
8174 createSyntax: function(config) {
8175 return createSyntax(mix_1({}, config));
8176 },
8177 fork: function(extension) {
8178 var base = mix_1({}, config); // copy of config
8179 return createSyntax(
8180 typeof extension === 'function'
8181 ? extension(base, assign)
8182 : mix_1(base, extension)
8183 );
8184 }
8185 };
8186
8187 syntax.lexer = new Lexer_1({
8188 generic: true,
8189 types: config.types,
8190 properties: config.properties,
8191 node: config.node
8192 }, syntax);
8193
8194 return syntax;
8195 }
8196 var create_1 = function(config) {
8197 return createSyntax(mix_1({}, config));
8198 };
8199
8200 var create$4 = {
8201 create: create_1
8202 };
8203
8204 var generic$1 = true;
8205 var types = {
8206 "absolute-size": "xx-small|x-small|small|medium|large|x-large|xx-large",
8207 "alpha-value": "<number>|<percentage>",
8208 "angle-percentage": "<angle>|<percentage>",
8209 "angular-color-hint": "<angle-percentage>",
8210 "angular-color-stop": "<color>&&<color-stop-angle>?",
8211 "angular-color-stop-list": "[<angular-color-stop> [, <angular-color-hint>]?]# , <angular-color-stop>",
8212 "animateable-feature": "scroll-position|contents|<custom-ident>",
8213 attachment: "scroll|fixed|local",
8214 "attr()": "attr( <attr-name> <type-or-unit>? [, <attr-fallback>]? )",
8215 "attr-matcher": "['~'|'|'|'^'|'$'|'*']? '='",
8216 "attr-modifier": "i|s",
8217 "attribute-selector": "'[' <wq-name> ']'|'[' <wq-name> <attr-matcher> [<string-token>|<ident-token>] <attr-modifier>? ']'",
8218 "auto-repeat": "repeat( [auto-fill|auto-fit] , [<line-names>? <fixed-size>]+ <line-names>? )",
8219 "auto-track-list": "[<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>? <auto-repeat> [<line-names>? [<fixed-size>|<fixed-repeat>]]* <line-names>?",
8220 "baseline-position": "[first|last]? baseline",
8221 "basic-shape": "<inset()>|<circle()>|<ellipse()>|<polygon()>",
8222 "bg-image": "none|<image>",
8223 "bg-layer": "<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
8224 "bg-position": "[[left|center|right|top|bottom|<length-percentage>]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]|[center|[left|right] <length-percentage>?]&&[center|[top|bottom] <length-percentage>?]]",
8225 "bg-size": "[<length-percentage>|auto]{1,2}|cover|contain",
8226 "blur()": "blur( <length> )",
8227 "blend-mode": "normal|multiply|screen|overlay|darken|lighten|color-dodge|color-burn|hard-light|soft-light|difference|exclusion|hue|saturation|color|luminosity",
8228 box: "border-box|padding-box|content-box",
8229 "brightness()": "brightness( <number-percentage> )",
8230 "calc()": "calc( <calc-sum> )",
8231 "calc-sum": "<calc-product> [['+'|'-'] <calc-product>]*",
8232 "calc-product": "<calc-value> ['*' <calc-value>|'/' <number>]*",
8233 "calc-value": "<number>|<dimension>|<percentage>|( <calc-sum> )",
8234 "cf-final-image": "<image>|<color>",
8235 "cf-mixing-image": "<percentage>?&&<image>",
8236 "circle()": "circle( [<shape-radius>]? [at <position>]? )",
8237 "clamp()": "clamp( <calc-sum>#{3} )",
8238 "class-selector": "'.' <ident-token>",
8239 "clip-source": "<url>",
8240 color: "<rgb()>|<rgba()>|<hsl()>|<hsla()>|<hex-color>|<named-color>|currentcolor|<deprecated-system-color>",
8241 "color-stop": "<color-stop-length>|<color-stop-angle>",
8242 "color-stop-angle": "<angle-percentage>{1,2}",
8243 "color-stop-length": "<length-percentage>{1,2}",
8244 "color-stop-list": "[<linear-color-stop> [, <linear-color-hint>]?]# , <linear-color-stop>",
8245 combinator: "'>'|'+'|'~'|['||']",
8246 "common-lig-values": "[common-ligatures|no-common-ligatures]",
8247 compat: "searchfield|textarea|push-button|button-bevel|slider-horizontal|checkbox|radio|square-button|menulist|menulist-button|listbox|meter|progress-bar",
8248 "composite-style": "clear|copy|source-over|source-in|source-out|source-atop|destination-over|destination-in|destination-out|destination-atop|xor",
8249 "compositing-operator": "add|subtract|intersect|exclude",
8250 "compound-selector": "[<type-selector>? <subclass-selector>* [<pseudo-element-selector> <pseudo-class-selector>*]*]!",
8251 "compound-selector-list": "<compound-selector>#",
8252 "complex-selector": "<compound-selector> [<combinator>? <compound-selector>]*",
8253 "complex-selector-list": "<complex-selector>#",
8254 "conic-gradient()": "conic-gradient( [from <angle>]? [at <position>]? , <angular-color-stop-list> )",
8255 "contextual-alt-values": "[contextual|no-contextual]",
8256 "content-distribution": "space-between|space-around|space-evenly|stretch",
8257 "content-list": "[<string>|contents|<url>|<quote>|<attr()>|counter( <ident> , <'list-style-type'>? )]+",
8258 "content-position": "center|start|end|flex-start|flex-end",
8259 "content-replacement": "<image>",
8260 "contrast()": "contrast( [<number-percentage>] )",
8261 "counter()": "counter( <custom-ident> , [<counter-style>|none]? )",
8262 "counter-style": "<counter-style-name>|symbols( )",
8263 "counter-style-name": "<custom-ident>",
8264 "counters()": "counters( <custom-ident> , <string> , [<counter-style>|none]? )",
8265 "cross-fade()": "cross-fade( <cf-mixing-image> , <cf-final-image>? )",
8266 "cubic-bezier-timing-function": "ease|ease-in|ease-out|ease-in-out|cubic-bezier( <number> , <number> , <number> , <number> )",
8267 "deprecated-system-color": "ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText",
8268 "discretionary-lig-values": "[discretionary-ligatures|no-discretionary-ligatures]",
8269 "display-box": "contents|none",
8270 "display-inside": "flow|flow-root|table|flex|grid|ruby",
8271 "display-internal": "table-row-group|table-header-group|table-footer-group|table-row|table-cell|table-column-group|table-column|table-caption|ruby-base|ruby-text|ruby-base-container|ruby-text-container",
8272 "display-legacy": "inline-block|inline-list-item|inline-table|inline-flex|inline-grid",
8273 "display-listitem": "<display-outside>?&&[flow|flow-root]?&&list-item",
8274 "display-outside": "block|inline|run-in",
8275 "drop-shadow()": "drop-shadow( <length>{2,3} <color>? )",
8276 "east-asian-variant-values": "[jis78|jis83|jis90|jis04|simplified|traditional]",
8277 "east-asian-width-values": "[full-width|proportional-width]",
8278 "element()": "element( <id-selector> )",
8279 "ellipse()": "ellipse( [<shape-radius>{2}]? [at <position>]? )",
8280 "ending-shape": "circle|ellipse",
8281 "env()": "env( <custom-ident> , <declaration-value>? )",
8282 "explicit-track-list": "[<line-names>? <track-size>]+ <line-names>?",
8283 "family-name": "<string>|<custom-ident>+",
8284 "feature-tag-value": "<string> [<integer>|on|off]?",
8285 "feature-type": "@stylistic|@historical-forms|@styleset|@character-variant|@swash|@ornaments|@annotation",
8286 "feature-value-block": "<feature-type> '{' <feature-value-declaration-list> '}'",
8287 "feature-value-block-list": "<feature-value-block>+",
8288 "feature-value-declaration": "<custom-ident> : <integer>+ ;",
8289 "feature-value-declaration-list": "<feature-value-declaration>",
8290 "feature-value-name": "<custom-ident>",
8291 "fill-rule": "nonzero|evenodd",
8292 "filter-function": "<blur()>|<brightness()>|<contrast()>|<drop-shadow()>|<grayscale()>|<hue-rotate()>|<invert()>|<opacity()>|<saturate()>|<sepia()>",
8293 "filter-function-list": "[<filter-function>|<url>]+",
8294 "final-bg-layer": "<'background-color'>||<bg-image>||<bg-position> [/ <bg-size>]?||<repeat-style>||<attachment>||<box>||<box>",
8295 "fit-content()": "fit-content( [<length>|<percentage>] )",
8296 "fixed-breadth": "<length-percentage>",
8297 "fixed-repeat": "repeat( [<positive-integer>] , [<line-names>? <fixed-size>]+ <line-names>? )",
8298 "fixed-size": "<fixed-breadth>|minmax( <fixed-breadth> , <track-breadth> )|minmax( <inflexible-breadth> , <fixed-breadth> )",
8299 "font-stretch-absolute": "normal|ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded|<percentage>",
8300 "font-variant-css21": "[normal|small-caps]",
8301 "font-weight-absolute": "normal|bold|<number>",
8302 "frequency-percentage": "<frequency>|<percentage>",
8303 "general-enclosed": "[<function-token> <any-value> )]|( <ident> <any-value> )",
8304 "generic-family": "serif|sans-serif|cursive|fantasy|monospace|-apple-system",
8305 "generic-name": "serif|sans-serif|cursive|fantasy|monospace",
8306 "geometry-box": "<shape-box>|fill-box|stroke-box|view-box",
8307 gradient: "<linear-gradient()>|<repeating-linear-gradient()>|<radial-gradient()>|<repeating-radial-gradient()>|<conic-gradient()>|<-legacy-gradient>",
8308 "grayscale()": "grayscale( <number-percentage> )",
8309 "grid-line": "auto|<custom-ident>|[<integer>&&<custom-ident>?]|[span&&[<integer>||<custom-ident>]]",
8310 "historical-lig-values": "[historical-ligatures|no-historical-ligatures]",
8311 "hsl()": "hsl( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsl( <hue> , <percentage> , <percentage> , <alpha-value>? )",
8312 "hsla()": "hsla( <hue> <percentage> <percentage> [/ <alpha-value>]? )|hsla( <hue> , <percentage> , <percentage> , <alpha-value>? )",
8313 hue: "<number>|<angle>",
8314 "hue-rotate()": "hue-rotate( <angle> )",
8315 image: "<url>|<image()>|<image-set()>|<element()>|<cross-fade()>|<gradient>",
8316 "image()": "image( <image-tags>? [<image-src>? , <color>?]! )",
8317 "image-set()": "image-set( <image-set-option># )",
8318 "image-set-option": "[<image>|<string>] <resolution>",
8319 "image-src": "<url>|<string>",
8320 "image-tags": "ltr|rtl",
8321 "inflexible-breadth": "<length>|<percentage>|min-content|max-content|auto",
8322 "inset()": "inset( <length-percentage>{1,4} [round <'border-radius'>]? )",
8323 "invert()": "invert( <number-percentage> )",
8324 "keyframes-name": "<custom-ident>|<string>",
8325 "keyframe-block": "<keyframe-selector># { <declaration-list> }",
8326 "keyframe-block-list": "<keyframe-block>+",
8327 "keyframe-selector": "from|to|<percentage>",
8328 "leader()": "leader( <leader-type> )",
8329 "leader-type": "dotted|solid|space|<string>",
8330 "length-percentage": "<length>|<percentage>",
8331 "line-names": "'[' <custom-ident>* ']'",
8332 "line-name-list": "[<line-names>|<name-repeat>]+",
8333 "line-style": "none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset",
8334 "line-width": "<length>|thin|medium|thick",
8335 "linear-color-hint": "<length-percentage>",
8336 "linear-color-stop": "<color> <color-stop-length>?",
8337 "linear-gradient()": "linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
8338 "mask-layer": "<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||<geometry-box>||[<geometry-box>|no-clip]||<compositing-operator>||<masking-mode>",
8339 "mask-position": "[<length-percentage>|left|center|right] [<length-percentage>|top|center|bottom]?",
8340 "mask-reference": "none|<image>|<mask-source>",
8341 "mask-source": "<url>",
8342 "masking-mode": "alpha|luminance|match-source",
8343 "matrix()": "matrix( <number>#{6} )",
8344 "matrix3d()": "matrix3d( <number>#{16} )",
8345 "max()": "max( <calc-sum># )",
8346 "media-and": "<media-in-parens> [and <media-in-parens>]+",
8347 "media-condition": "<media-not>|<media-and>|<media-or>|<media-in-parens>",
8348 "media-condition-without-or": "<media-not>|<media-and>|<media-in-parens>",
8349 "media-feature": "( [<mf-plain>|<mf-boolean>|<mf-range>] )",
8350 "media-in-parens": "( <media-condition> )|<media-feature>|<general-enclosed>",
8351 "media-not": "not <media-in-parens>",
8352 "media-or": "<media-in-parens> [or <media-in-parens>]+",
8353 "media-query": "<media-condition>|[not|only]? <media-type> [and <media-condition-without-or>]?",
8354 "media-query-list": "<media-query>#",
8355 "media-type": "<ident>",
8356 "mf-boolean": "<mf-name>",
8357 "mf-name": "<ident>",
8358 "mf-plain": "<mf-name> : <mf-value>",
8359 "mf-range": "<mf-name> ['<'|'>']? '='? <mf-value>|<mf-value> ['<'|'>']? '='? <mf-name>|<mf-value> '<' '='? <mf-name> '<' '='? <mf-value>|<mf-value> '>' '='? <mf-name> '>' '='? <mf-value>",
8360 "mf-value": "<number>|<dimension>|<ident>|<ratio>",
8361 "min()": "min( <calc-sum># )",
8362 "minmax()": "minmax( [<length>|<percentage>|<flex>|min-content|max-content|auto] , [<length>|<percentage>|<flex>|min-content|max-content|auto] )",
8363 "named-color": "transparent|aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen|<-non-standard-color>",
8364 "namespace-prefix": "<ident>",
8365 "ns-prefix": "[<ident-token>|'*']? '|'",
8366 "number-percentage": "<number>|<percentage>",
8367 "numeric-figure-values": "[lining-nums|oldstyle-nums]",
8368 "numeric-fraction-values": "[diagonal-fractions|stacked-fractions]",
8369 "numeric-spacing-values": "[proportional-nums|tabular-nums]",
8370 nth: "<an-plus-b>|even|odd",
8371 "opacity()": "opacity( [<number-percentage>] )",
8372 "overflow-position": "unsafe|safe",
8373 "outline-radius": "<length>|<percentage>",
8374 "page-body": "<declaration>? [; <page-body>]?|<page-margin-box> <page-body>",
8375 "page-margin-box": "<page-margin-box-type> '{' <declaration-list> '}'",
8376 "page-margin-box-type": "@top-left-corner|@top-left|@top-center|@top-right|@top-right-corner|@bottom-left-corner|@bottom-left|@bottom-center|@bottom-right|@bottom-right-corner|@left-top|@left-middle|@left-bottom|@right-top|@right-middle|@right-bottom",
8377 "page-selector-list": "[<page-selector>#]?",
8378 "page-selector": "<pseudo-page>+|<ident> <pseudo-page>*",
8379 "perspective()": "perspective( <length> )",
8380 "polygon()": "polygon( <fill-rule>? , [<length-percentage> <length-percentage>]# )",
8381 position: "[[left|center|right]||[top|center|bottom]|[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]?|[[left|right] <length-percentage>]&&[[top|bottom] <length-percentage>]]",
8382 "pseudo-class-selector": "':' <ident-token>|':' <function-token> <any-value> ')'",
8383 "pseudo-element-selector": "':' <pseudo-class-selector>",
8384 "pseudo-page": ": [left|right|first|blank]",
8385 quote: "open-quote|close-quote|no-open-quote|no-close-quote",
8386 "radial-gradient()": "radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
8387 "relative-selector": "<combinator>? <complex-selector>",
8388 "relative-selector-list": "<relative-selector>#",
8389 "relative-size": "larger|smaller",
8390 "repeat-style": "repeat-x|repeat-y|[repeat|space|round|no-repeat]{1,2}",
8391 "repeating-linear-gradient()": "repeating-linear-gradient( [<angle>|to <side-or-corner>]? , <color-stop-list> )",
8392 "repeating-radial-gradient()": "repeating-radial-gradient( [<ending-shape>||<size>]? [at <position>]? , <color-stop-list> )",
8393 "rgb()": "rgb( <percentage>{3} [/ <alpha-value>]? )|rgb( <number>{3} [/ <alpha-value>]? )|rgb( <percentage>#{3} , <alpha-value>? )|rgb( <number>#{3} , <alpha-value>? )",
8394 "rgba()": "rgba( <percentage>{3} [/ <alpha-value>]? )|rgba( <number>{3} [/ <alpha-value>]? )|rgba( <percentage>#{3} , <alpha-value>? )|rgba( <number>#{3} , <alpha-value>? )",
8395 "rotate()": "rotate( [<angle>|<zero>] )",
8396 "rotate3d()": "rotate3d( <number> , <number> , <number> , [<angle>|<zero>] )",
8397 "rotateX()": "rotateX( [<angle>|<zero>] )",
8398 "rotateY()": "rotateY( [<angle>|<zero>] )",
8399 "rotateZ()": "rotateZ( [<angle>|<zero>] )",
8400 "saturate()": "saturate( <number-percentage> )",
8401 "scale()": "scale( <number> , <number>? )",
8402 "scale3d()": "scale3d( <number> , <number> , <number> )",
8403 "scaleX()": "scaleX( <number> )",
8404 "scaleY()": "scaleY( <number> )",
8405 "scaleZ()": "scaleZ( <number> )",
8406 "self-position": "center|start|end|self-start|self-end|flex-start|flex-end",
8407 "shape-radius": "<length-percentage>|closest-side|farthest-side",
8408 "skew()": "skew( [<angle>|<zero>] , [<angle>|<zero>]? )",
8409 "skewX()": "skewX( [<angle>|<zero>] )",
8410 "skewY()": "skewY( [<angle>|<zero>] )",
8411 "sepia()": "sepia( <number-percentage> )",
8412 shadow: "inset?&&<length>{2,4}&&<color>?",
8413 "shadow-t": "[<length>{2,3}&&<color>?]",
8414 shape: "rect( <top> , <right> , <bottom> , <left> )|rect( <top> <right> <bottom> <left> )",
8415 "shape-box": "<box>|margin-box",
8416 "side-or-corner": "[left|right]||[top|bottom]",
8417 "single-animation": "<time>||<timing-function>||<time>||<single-animation-iteration-count>||<single-animation-direction>||<single-animation-fill-mode>||<single-animation-play-state>||[none|<keyframes-name>]",
8418 "single-animation-direction": "normal|reverse|alternate|alternate-reverse",
8419 "single-animation-fill-mode": "none|forwards|backwards|both",
8420 "single-animation-iteration-count": "infinite|<number>",
8421 "single-animation-play-state": "running|paused",
8422 "single-transition": "[none|<single-transition-property>]||<time>||<timing-function>||<time>",
8423 "single-transition-property": "all|<custom-ident>",
8424 size: "closest-side|farthest-side|closest-corner|farthest-corner|<length>|<length-percentage>{2}",
8425 "step-position": "jump-start|jump-end|jump-none|jump-both|start|end",
8426 "step-timing-function": "step-start|step-end|steps( <integer> [, <step-position>]? )",
8427 "subclass-selector": "<id-selector>|<class-selector>|<attribute-selector>|<pseudo-class-selector>",
8428 "supports-condition": "not <supports-in-parens>|<supports-in-parens> [and <supports-in-parens>]*|<supports-in-parens> [or <supports-in-parens>]*",
8429 "supports-in-parens": "( <supports-condition> )|<supports-feature>|<general-enclosed>",
8430 "supports-feature": "<supports-decl>|<supports-selector-fn>",
8431 "supports-decl": "( <declaration> )",
8432 "supports-selector-fn": "selector( <complex-selector> )",
8433 symbol: "<string>|<image>|<custom-ident>",
8434 target: "<target-counter()>|<target-counters()>|<target-text()>",
8435 "target-counter()": "target-counter( [<string>|<url>] , <custom-ident> , <counter-style>? )",
8436 "target-counters()": "target-counters( [<string>|<url>] , <custom-ident> , <string> , <counter-style>? )",
8437 "target-text()": "target-text( [<string>|<url>] , [content|before|after|first-letter]? )",
8438 "time-percentage": "<time>|<percentage>",
8439 "timing-function": "linear|<cubic-bezier-timing-function>|<step-timing-function>",
8440 "track-breadth": "<length-percentage>|<flex>|min-content|max-content|auto",
8441 "track-list": "[<line-names>? [<track-size>|<track-repeat>]]+ <line-names>?",
8442 "track-repeat": "repeat( [<positive-integer>] , [<line-names>? <track-size>]+ <line-names>? )",
8443 "track-size": "<track-breadth>|minmax( <inflexible-breadth> , <track-breadth> )|fit-content( [<length>|<percentage>] )",
8444 "transform-function": "<matrix()>|<translate()>|<translateX()>|<translateY()>|<scale()>|<scaleX()>|<scaleY()>|<rotate()>|<skew()>|<skewX()>|<skewY()>|<matrix3d()>|<translate3d()>|<translateZ()>|<scale3d()>|<scaleZ()>|<rotate3d()>|<rotateX()>|<rotateY()>|<rotateZ()>|<perspective()>",
8445 "transform-list": "<transform-function>+",
8446 "translate()": "translate( <length-percentage> , <length-percentage>? )",
8447 "translate3d()": "translate3d( <length-percentage> , <length-percentage> , <length> )",
8448 "translateX()": "translateX( <length-percentage> )",
8449 "translateY()": "translateY( <length-percentage> )",
8450 "translateZ()": "translateZ( <length> )",
8451 "type-or-unit": "string|color|url|integer|number|length|angle|time|frequency|cap|ch|em|ex|ic|lh|rlh|rem|vb|vi|vw|vh|vmin|vmax|mm|Q|cm|in|pt|pc|px|deg|grad|rad|turn|ms|s|Hz|kHz|%",
8452 "type-selector": "<wq-name>|<ns-prefix>? '*'",
8453 "var()": "var( <custom-property-name> , <declaration-value>? )",
8454 "viewport-length": "auto|<length-percentage>",
8455 "wq-name": "<ns-prefix>? <ident-token>",
8456 "-legacy-gradient": "<-webkit-gradient()>|<-legacy-linear-gradient>|<-legacy-repeating-linear-gradient>|<-legacy-radial-gradient>|<-legacy-repeating-radial-gradient>",
8457 "-legacy-linear-gradient": "-moz-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-linear-gradient( <-legacy-linear-gradient-arguments> )",
8458 "-legacy-repeating-linear-gradient": "-moz-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-webkit-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )|-o-repeating-linear-gradient( <-legacy-linear-gradient-arguments> )",
8459 "-legacy-linear-gradient-arguments": "[<angle>|<side-or-corner>]? , <color-stop-list>",
8460 "-legacy-radial-gradient": "-moz-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-radial-gradient( <-legacy-radial-gradient-arguments> )",
8461 "-legacy-repeating-radial-gradient": "-moz-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-webkit-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )|-o-repeating-radial-gradient( <-legacy-radial-gradient-arguments> )",
8462 "-legacy-radial-gradient-arguments": "[<position> ,]? [[[<-legacy-radial-gradient-shape>||<-legacy-radial-gradient-size>]|[<length>|<percentage>]{2}] ,]? <color-stop-list>",
8463 "-legacy-radial-gradient-size": "closest-side|closest-corner|farthest-side|farthest-corner|contain|cover",
8464 "-legacy-radial-gradient-shape": "circle|ellipse",
8465 "-non-standard-font": "-apple-system-body|-apple-system-headline|-apple-system-subheadline|-apple-system-caption1|-apple-system-caption2|-apple-system-footnote|-apple-system-short-body|-apple-system-short-headline|-apple-system-short-subheadline|-apple-system-short-caption1|-apple-system-short-footnote|-apple-system-tall-body",
8466 "-non-standard-color": "-moz-ButtonDefault|-moz-ButtonHoverFace|-moz-ButtonHoverText|-moz-CellHighlight|-moz-CellHighlightText|-moz-Combobox|-moz-ComboboxText|-moz-Dialog|-moz-DialogText|-moz-dragtargetzone|-moz-EvenTreeRow|-moz-Field|-moz-FieldText|-moz-html-CellHighlight|-moz-html-CellHighlightText|-moz-mac-accentdarkestshadow|-moz-mac-accentdarkshadow|-moz-mac-accentface|-moz-mac-accentlightesthighlight|-moz-mac-accentlightshadow|-moz-mac-accentregularhighlight|-moz-mac-accentregularshadow|-moz-mac-chrome-active|-moz-mac-chrome-inactive|-moz-mac-focusring|-moz-mac-menuselect|-moz-mac-menushadow|-moz-mac-menutextselect|-moz-MenuHover|-moz-MenuHoverText|-moz-MenuBarText|-moz-MenuBarHoverText|-moz-nativehyperlinktext|-moz-OddTreeRow|-moz-win-communicationstext|-moz-win-mediatext|-moz-activehyperlinktext|-moz-default-background-color|-moz-default-color|-moz-hyperlinktext|-moz-visitedhyperlinktext|-webkit-activelink|-webkit-focus-ring-color|-webkit-link|-webkit-text",
8467 "-non-standard-image-rendering": "optimize-contrast|-moz-crisp-edges|-o-crisp-edges|-webkit-optimize-contrast",
8468 "-non-standard-overflow": "-moz-scrollbars-none|-moz-scrollbars-horizontal|-moz-scrollbars-vertical|-moz-hidden-unscrollable",
8469 "-non-standard-width": "min-intrinsic|intrinsic|-moz-min-content|-moz-max-content|-webkit-min-content|-webkit-max-content",
8470 "-webkit-gradient()": "-webkit-gradient( <-webkit-gradient-type> , <-webkit-gradient-point> [, <-webkit-gradient-point>|, <-webkit-gradient-radius> , <-webkit-gradient-point>] [, <-webkit-gradient-radius>]? [, <-webkit-gradient-color-stop>]* )",
8471 "-webkit-gradient-color-stop": "from( <color> )|color-stop( [<number-zero-one>|<percentage>] , <color> )|to( <color> )",
8472 "-webkit-gradient-point": "[left|center|right|<length-percentage>] [top|center|bottom|<length-percentage>]",
8473 "-webkit-gradient-radius": "<length>|<percentage>",
8474 "-webkit-gradient-type": "linear|radial",
8475 "-webkit-mask-box-repeat": "repeat|stretch|round",
8476 "-webkit-mask-clip-style": "border|border-box|padding|padding-box|content|content-box|text",
8477 "-ms-filter-function-list": "<-ms-filter-function>+",
8478 "-ms-filter-function": "<-ms-filter-function-progid>|<-ms-filter-function-legacy>",
8479 "-ms-filter-function-progid": "'progid:' [<ident-token> '.']* [<ident-token>|<function-token> <any-value>? )]",
8480 "-ms-filter-function-legacy": "<ident-token>|<function-token> <any-value>? )",
8481 "-ms-filter": "<string>",
8482 age: "child|young|old",
8483 "attr-name": "<wq-name>",
8484 "attr-fallback": "<any-value>",
8485 "border-radius": "<length-percentage>{1,2}",
8486 bottom: "<length>|auto",
8487 "generic-voice": "[<age>? <gender> <integer>?]",
8488 gender: "male|female|neutral",
8489 left: "<length>|auto",
8490 "mask-image": "<mask-reference>#",
8491 "name-repeat": "repeat( [<positive-integer>|auto-fill] , <line-names>+ )",
8492 paint: "none|<color>|<url> [none|<color>]?|context-fill|context-stroke",
8493 "path()": "path( <string> )",
8494 ratio: "<integer> / <integer>",
8495 right: "<length>|auto",
8496 "svg-length": "<percentage>|<length>|<number>",
8497 "svg-writing-mode": "lr-tb|rl-tb|tb-rl|lr|rl|tb",
8498 top: "<length>|auto",
8499 x: "<number>",
8500 y: "<number>",
8501 declaration: "<ident-token> : <declaration-value>? ['!' important]?",
8502 "declaration-list": "[<declaration>? ';']* <declaration>?",
8503 url: "url( <string> <url-modifier>* )|<url-token>",
8504 "url-modifier": "<ident>|<function-token> <any-value> )",
8505 "number-zero-one": "<number [0,1]>",
8506 "number-one-or-greater": "<number [1,∞]>",
8507 "positive-integer": "<integer [0,∞]>"
8508 };
8509 var properties$1 = {
8510 "--*": "<declaration-value>",
8511 "-ms-accelerator": "false|true",
8512 "-ms-block-progression": "tb|rl|bt|lr",
8513 "-ms-content-zoom-chaining": "none|chained",
8514 "-ms-content-zooming": "none|zoom",
8515 "-ms-content-zoom-limit": "<'-ms-content-zoom-limit-min'> <'-ms-content-zoom-limit-max'>",
8516 "-ms-content-zoom-limit-max": "<percentage>",
8517 "-ms-content-zoom-limit-min": "<percentage>",
8518 "-ms-content-zoom-snap": "<'-ms-content-zoom-snap-type'>||<'-ms-content-zoom-snap-points'>",
8519 "-ms-content-zoom-snap-points": "snapInterval( <percentage> , <percentage> )|snapList( <percentage># )",
8520 "-ms-content-zoom-snap-type": "none|proximity|mandatory",
8521 "-ms-filter": "<string>",
8522 "-ms-flow-from": "[none|<custom-ident>]#",
8523 "-ms-flow-into": "[none|<custom-ident>]#",
8524 "-ms-high-contrast-adjust": "auto|none",
8525 "-ms-hyphenate-limit-chars": "auto|<integer>{1,3}",
8526 "-ms-hyphenate-limit-lines": "no-limit|<integer>",
8527 "-ms-hyphenate-limit-zone": "<percentage>|<length>",
8528 "-ms-ime-align": "auto|after",
8529 "-ms-overflow-style": "auto|none|scrollbar|-ms-autohiding-scrollbar",
8530 "-ms-scrollbar-3dlight-color": "<color>",
8531 "-ms-scrollbar-arrow-color": "<color>",
8532 "-ms-scrollbar-base-color": "<color>",
8533 "-ms-scrollbar-darkshadow-color": "<color>",
8534 "-ms-scrollbar-face-color": "<color>",
8535 "-ms-scrollbar-highlight-color": "<color>",
8536 "-ms-scrollbar-shadow-color": "<color>",
8537 "-ms-scrollbar-track-color": "<color>",
8538 "-ms-scroll-chaining": "chained|none",
8539 "-ms-scroll-limit": "<'-ms-scroll-limit-x-min'> <'-ms-scroll-limit-y-min'> <'-ms-scroll-limit-x-max'> <'-ms-scroll-limit-y-max'>",
8540 "-ms-scroll-limit-x-max": "auto|<length>",
8541 "-ms-scroll-limit-x-min": "<length>",
8542 "-ms-scroll-limit-y-max": "auto|<length>",
8543 "-ms-scroll-limit-y-min": "<length>",
8544 "-ms-scroll-rails": "none|railed",
8545 "-ms-scroll-snap-points-x": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
8546 "-ms-scroll-snap-points-y": "snapInterval( <length-percentage> , <length-percentage> )|snapList( <length-percentage># )",
8547 "-ms-scroll-snap-type": "none|proximity|mandatory",
8548 "-ms-scroll-snap-x": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-x'>",
8549 "-ms-scroll-snap-y": "<'-ms-scroll-snap-type'> <'-ms-scroll-snap-points-y'>",
8550 "-ms-scroll-translation": "none|vertical-to-horizontal",
8551 "-ms-text-autospace": "none|ideograph-alpha|ideograph-numeric|ideograph-parenthesis|ideograph-space",
8552 "-ms-touch-select": "grippers|none",
8553 "-ms-user-select": "none|element|text",
8554 "-ms-wrap-flow": "auto|both|start|end|maximum|clear",
8555 "-ms-wrap-margin": "<length>",
8556 "-ms-wrap-through": "wrap|none",
8557 "-moz-appearance": "none|button|button-arrow-down|button-arrow-next|button-arrow-previous|button-arrow-up|button-bevel|button-focus|caret|checkbox|checkbox-container|checkbox-label|checkmenuitem|dualbutton|groupbox|listbox|listitem|menuarrow|menubar|menucheckbox|menuimage|menuitem|menuitemtext|menulist|menulist-button|menulist-text|menulist-textfield|menupopup|menuradio|menuseparator|meterbar|meterchunk|progressbar|progressbar-vertical|progresschunk|progresschunk-vertical|radio|radio-container|radio-label|radiomenuitem|range|range-thumb|resizer|resizerpanel|scale-horizontal|scalethumbend|scalethumb-horizontal|scalethumbstart|scalethumbtick|scalethumb-vertical|scale-vertical|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|separator|sheet|spinner|spinner-downbutton|spinner-textfield|spinner-upbutton|splitter|statusbar|statusbarpanel|tab|tabpanel|tabpanels|tab-scroll-arrow-back|tab-scroll-arrow-forward|textfield|textfield-multiline|toolbar|toolbarbutton|toolbarbutton-dropdown|toolbargripper|toolbox|tooltip|treeheader|treeheadercell|treeheadersortarrow|treeitem|treeline|treetwisty|treetwistyopen|treeview|-moz-mac-unified-toolbar|-moz-win-borderless-glass|-moz-win-browsertabbar-toolbox|-moz-win-communicationstext|-moz-win-communications-toolbox|-moz-win-exclude-glass|-moz-win-glass|-moz-win-mediatext|-moz-win-media-toolbox|-moz-window-button-box|-moz-window-button-box-maximized|-moz-window-button-close|-moz-window-button-maximize|-moz-window-button-minimize|-moz-window-button-restore|-moz-window-frame-bottom|-moz-window-frame-left|-moz-window-frame-right|-moz-window-titlebar|-moz-window-titlebar-maximized",
8558 "-moz-binding": "<url>|none",
8559 "-moz-border-bottom-colors": "<color>+|none",
8560 "-moz-border-left-colors": "<color>+|none",
8561 "-moz-border-right-colors": "<color>+|none",
8562 "-moz-border-top-colors": "<color>+|none",
8563 "-moz-context-properties": "none|[fill|fill-opacity|stroke|stroke-opacity]#",
8564 "-moz-float-edge": "border-box|content-box|margin-box|padding-box",
8565 "-moz-force-broken-image-icon": "<integer>",
8566 "-moz-image-region": "<shape>|auto",
8567 "-moz-orient": "inline|block|horizontal|vertical",
8568 "-moz-outline-radius": "<outline-radius>{1,4} [/ <outline-radius>{1,4}]?",
8569 "-moz-outline-radius-bottomleft": "<outline-radius>",
8570 "-moz-outline-radius-bottomright": "<outline-radius>",
8571 "-moz-outline-radius-topleft": "<outline-radius>",
8572 "-moz-outline-radius-topright": "<outline-radius>",
8573 "-moz-stack-sizing": "ignore|stretch-to-fit",
8574 "-moz-text-blink": "none|blink",
8575 "-moz-user-focus": "ignore|normal|select-after|select-before|select-menu|select-same|select-all|none",
8576 "-moz-user-input": "auto|none|enabled|disabled",
8577 "-moz-user-modify": "read-only|read-write|write-only",
8578 "-moz-window-dragging": "drag|no-drag",
8579 "-moz-window-shadow": "default|menu|tooltip|sheet|none",
8580 "-webkit-appearance": "none|button|button-bevel|caps-lock-indicator|caret|checkbox|default-button|listbox|listitem|media-fullscreen-button|media-mute-button|media-play-button|media-seek-back-button|media-seek-forward-button|media-slider|media-sliderthumb|menulist|menulist-button|menulist-text|menulist-textfield|push-button|radio|scrollbarbutton-down|scrollbarbutton-left|scrollbarbutton-right|scrollbarbutton-up|scrollbargripper-horizontal|scrollbargripper-vertical|scrollbarthumb-horizontal|scrollbarthumb-vertical|scrollbartrack-horizontal|scrollbartrack-vertical|searchfield|searchfield-cancel-button|searchfield-decoration|searchfield-results-button|searchfield-results-decoration|slider-horizontal|slider-vertical|sliderthumb-horizontal|sliderthumb-vertical|square-button|textarea|textfield",
8581 "-webkit-border-before": "<'border-width'>||<'border-style'>||<'color'>",
8582 "-webkit-border-before-color": "<'color'>",
8583 "-webkit-border-before-style": "<'border-style'>",
8584 "-webkit-border-before-width": "<'border-width'>",
8585 "-webkit-box-reflect": "[above|below|right|left]? <length>? <image>?",
8586 "-webkit-line-clamp": "none|<integer>",
8587 "-webkit-mask": "[<mask-reference>||<position> [/ <bg-size>]?||<repeat-style>||[<box>|border|padding|content|text]||[<box>|border|padding|content]]#",
8588 "-webkit-mask-attachment": "<attachment>#",
8589 "-webkit-mask-clip": "[<box>|border|padding|content|text]#",
8590 "-webkit-mask-composite": "<composite-style>#",
8591 "-webkit-mask-image": "<mask-reference>#",
8592 "-webkit-mask-origin": "[<box>|border|padding|content]#",
8593 "-webkit-mask-position": "<position>#",
8594 "-webkit-mask-position-x": "[<length-percentage>|left|center|right]#",
8595 "-webkit-mask-position-y": "[<length-percentage>|top|center|bottom]#",
8596 "-webkit-mask-repeat": "<repeat-style>#",
8597 "-webkit-mask-repeat-x": "repeat|no-repeat|space|round",
8598 "-webkit-mask-repeat-y": "repeat|no-repeat|space|round",
8599 "-webkit-mask-size": "<bg-size>#",
8600 "-webkit-overflow-scrolling": "auto|touch",
8601 "-webkit-tap-highlight-color": "<color>",
8602 "-webkit-text-fill-color": "<color>",
8603 "-webkit-text-stroke": "<length>||<color>",
8604 "-webkit-text-stroke-color": "<color>",
8605 "-webkit-text-stroke-width": "<length>",
8606 "-webkit-touch-callout": "default|none",
8607 "-webkit-user-modify": "read-only|read-write|read-write-plaintext-only",
8608 "align-content": "normal|<baseline-position>|<content-distribution>|<overflow-position>? <content-position>",
8609 "align-items": "normal|stretch|<baseline-position>|[<overflow-position>? <self-position>]",
8610 "align-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? <self-position>",
8611 all: "initial|inherit|unset|revert",
8612 animation: "<single-animation>#",
8613 "animation-delay": "<time>#",
8614 "animation-direction": "<single-animation-direction>#",
8615 "animation-duration": "<time>#",
8616 "animation-fill-mode": "<single-animation-fill-mode>#",
8617 "animation-iteration-count": "<single-animation-iteration-count>#",
8618 "animation-name": "[none|<keyframes-name>]#",
8619 "animation-play-state": "<single-animation-play-state>#",
8620 "animation-timing-function": "<timing-function>#",
8621 appearance: "none|auto|button|textfield|<compat>",
8622 azimuth: "<angle>|[[left-side|far-left|left|center-left|center|center-right|right|far-right|right-side]||behind]|leftwards|rightwards",
8623 "backdrop-filter": "none|<filter-function-list>",
8624 "backface-visibility": "visible|hidden",
8625 background: "[<bg-layer> ,]* <final-bg-layer>",
8626 "background-attachment": "<attachment>#",
8627 "background-blend-mode": "<blend-mode>#",
8628 "background-clip": "<box>#",
8629 "background-color": "<color>",
8630 "background-image": "<bg-image>#",
8631 "background-origin": "<box>#",
8632 "background-position": "<bg-position>#",
8633 "background-position-x": "[center|[left|right|x-start|x-end]? <length-percentage>?]#",
8634 "background-position-y": "[center|[top|bottom|y-start|y-end]? <length-percentage>?]#",
8635 "background-repeat": "<repeat-style>#",
8636 "background-size": "<bg-size>#",
8637 "block-overflow": "clip|ellipsis|<string>",
8638 "block-size": "<'width'>",
8639 border: "<line-width>||<line-style>||<color>",
8640 "border-block": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8641 "border-block-color": "<'border-top-color'>{1,2}",
8642 "border-block-style": "<'border-top-style'>",
8643 "border-block-width": "<'border-top-width'>",
8644 "border-block-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8645 "border-block-end-color": "<'border-top-color'>",
8646 "border-block-end-style": "<'border-top-style'>",
8647 "border-block-end-width": "<'border-top-width'>",
8648 "border-block-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8649 "border-block-start-color": "<'border-top-color'>",
8650 "border-block-start-style": "<'border-top-style'>",
8651 "border-block-start-width": "<'border-top-width'>",
8652 "border-bottom": "<line-width>||<line-style>||<color>",
8653 "border-bottom-color": "<'border-top-color'>",
8654 "border-bottom-left-radius": "<length-percentage>{1,2}",
8655 "border-bottom-right-radius": "<length-percentage>{1,2}",
8656 "border-bottom-style": "<line-style>",
8657 "border-bottom-width": "<line-width>",
8658 "border-collapse": "collapse|separate",
8659 "border-color": "<color>{1,4}",
8660 "border-end-end-radius": "<length-percentage>{1,2}",
8661 "border-end-start-radius": "<length-percentage>{1,2}",
8662 "border-image": "<'border-image-source'>||<'border-image-slice'> [/ <'border-image-width'>|/ <'border-image-width'>? / <'border-image-outset'>]?||<'border-image-repeat'>",
8663 "border-image-outset": "[<length>|<number>]{1,4}",
8664 "border-image-repeat": "[stretch|repeat|round|space]{1,2}",
8665 "border-image-slice": "<number-percentage>{1,4}&&fill?",
8666 "border-image-source": "none|<image>",
8667 "border-image-width": "[<length-percentage>|<number>|auto]{1,4}",
8668 "border-inline": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8669 "border-inline-end": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8670 "border-inline-color": "<'border-top-color'>{1,2}",
8671 "border-inline-style": "<'border-top-style'>",
8672 "border-inline-width": "<'border-top-width'>",
8673 "border-inline-end-color": "<'border-top-color'>",
8674 "border-inline-end-style": "<'border-top-style'>",
8675 "border-inline-end-width": "<'border-top-width'>",
8676 "border-inline-start": "<'border-top-width'>||<'border-top-style'>||<'color'>",
8677 "border-inline-start-color": "<'border-top-color'>",
8678 "border-inline-start-style": "<'border-top-style'>",
8679 "border-inline-start-width": "<'border-top-width'>",
8680 "border-left": "<line-width>||<line-style>||<color>",
8681 "border-left-color": "<color>",
8682 "border-left-style": "<line-style>",
8683 "border-left-width": "<line-width>",
8684 "border-radius": "<length-percentage>{1,4} [/ <length-percentage>{1,4}]?",
8685 "border-right": "<line-width>||<line-style>||<color>",
8686 "border-right-color": "<color>",
8687 "border-right-style": "<line-style>",
8688 "border-right-width": "<line-width>",
8689 "border-spacing": "<length> <length>?",
8690 "border-start-end-radius": "<length-percentage>{1,2}",
8691 "border-start-start-radius": "<length-percentage>{1,2}",
8692 "border-style": "<line-style>{1,4}",
8693 "border-top": "<line-width>||<line-style>||<color>",
8694 "border-top-color": "<color>",
8695 "border-top-left-radius": "<length-percentage>{1,2}",
8696 "border-top-right-radius": "<length-percentage>{1,2}",
8697 "border-top-style": "<line-style>",
8698 "border-top-width": "<line-width>",
8699 "border-width": "<line-width>{1,4}",
8700 bottom: "<length>|<percentage>|auto",
8701 "box-align": "start|center|end|baseline|stretch",
8702 "box-decoration-break": "slice|clone",
8703 "box-direction": "normal|reverse|inherit",
8704 "box-flex": "<number>",
8705 "box-flex-group": "<integer>",
8706 "box-lines": "single|multiple",
8707 "box-ordinal-group": "<integer>",
8708 "box-orient": "horizontal|vertical|inline-axis|block-axis|inherit",
8709 "box-pack": "start|center|end|justify",
8710 "box-shadow": "none|<shadow>#",
8711 "box-sizing": "content-box|border-box",
8712 "break-after": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
8713 "break-before": "auto|avoid|always|all|avoid-page|page|left|right|recto|verso|avoid-column|column|avoid-region|region",
8714 "break-inside": "auto|avoid|avoid-page|avoid-column|avoid-region",
8715 "caption-side": "top|bottom|block-start|block-end|inline-start|inline-end",
8716 "caret-color": "auto|<color>",
8717 clear: "none|left|right|both|inline-start|inline-end",
8718 clip: "<shape>|auto",
8719 "clip-path": "<clip-source>|[<basic-shape>||<geometry-box>]|none",
8720 color: "<color>",
8721 "color-adjust": "economy|exact",
8722 "column-count": "<integer>|auto",
8723 "column-fill": "auto|balance|balance-all",
8724 "column-gap": "normal|<length-percentage>",
8725 "column-rule": "<'column-rule-width'>||<'column-rule-style'>||<'column-rule-color'>",
8726 "column-rule-color": "<color>",
8727 "column-rule-style": "<'border-style'>",
8728 "column-rule-width": "<'border-width'>",
8729 "column-span": "none|all",
8730 "column-width": "<length>|auto",
8731 columns: "<'column-width'>||<'column-count'>",
8732 contain: "none|strict|content|[size||layout||style||paint]",
8733 content: "normal|none|[<content-replacement>|<content-list>] [/ <string>]?",
8734 "counter-increment": "[<custom-ident> <integer>?]+|none",
8735 "counter-reset": "[<custom-ident> <integer>?]+|none",
8736 "counter-set": "[<custom-ident> <integer>?]+|none",
8737 cursor: "[[<url> [<x> <y>]? ,]* [auto|default|none|context-menu|help|pointer|progress|wait|cell|crosshair|text|vertical-text|alias|copy|move|no-drop|not-allowed|e-resize|n-resize|ne-resize|nw-resize|s-resize|se-resize|sw-resize|w-resize|ew-resize|ns-resize|nesw-resize|nwse-resize|col-resize|row-resize|all-scroll|zoom-in|zoom-out|grab|grabbing|hand|-webkit-grab|-webkit-grabbing|-webkit-zoom-in|-webkit-zoom-out|-moz-grab|-moz-grabbing|-moz-zoom-in|-moz-zoom-out]]",
8738 direction: "ltr|rtl",
8739 display: "none|inline|block|list-item|inline-list-item|inline-block|inline-table|table|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row|table-row-group|flex|inline-flex|grid|inline-grid|run-in|ruby|ruby-base|ruby-text|ruby-base-container|ruby-text-container|contents|-ms-flexbox|-ms-inline-flexbox|-ms-grid|-ms-inline-grid|-webkit-flex|-webkit-inline-flex|-webkit-box|-webkit-inline-box|-moz-inline-stack|-moz-box|-moz-inline-box",
8740 "empty-cells": "show|hide",
8741 filter: "none|<filter-function-list>|<-ms-filter-function-list>",
8742 flex: "none|[<'flex-grow'> <'flex-shrink'>?||<'flex-basis'>]",
8743 "flex-basis": "content|<'width'>",
8744 "flex-direction": "row|row-reverse|column|column-reverse",
8745 "flex-flow": "<'flex-direction'>||<'flex-wrap'>",
8746 "flex-grow": "<number>",
8747 "flex-shrink": "<number>",
8748 "flex-wrap": "nowrap|wrap|wrap-reverse",
8749 float: "left|right|none|inline-start|inline-end",
8750 font: "[[<'font-style'>||<font-variant-css21>||<'font-weight'>||<'font-stretch'>]? <'font-size'> [/ <'line-height'>]? <'font-family'>]|caption|icon|menu|message-box|small-caption|status-bar",
8751 "font-family": "[<family-name>|<generic-family>]#",
8752 "font-feature-settings": "normal|<feature-tag-value>#",
8753 "font-kerning": "auto|normal|none",
8754 "font-language-override": "normal|<string>",
8755 "font-optical-sizing": "auto|none",
8756 "font-variation-settings": "normal|[<string> <number>]#",
8757 "font-size": "<absolute-size>|<relative-size>|<length-percentage>",
8758 "font-size-adjust": "none|<number>",
8759 "font-stretch": "<font-stretch-absolute>",
8760 "font-style": "normal|italic|oblique <angle>?",
8761 "font-synthesis": "none|[weight||style]",
8762 "font-variant": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>||stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )||[small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps]||<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero||<east-asian-variant-values>||<east-asian-width-values>||ruby]",
8763 "font-variant-alternates": "normal|[stylistic( <feature-value-name> )||historical-forms||styleset( <feature-value-name># )||character-variant( <feature-value-name># )||swash( <feature-value-name> )||ornaments( <feature-value-name> )||annotation( <feature-value-name> )]",
8764 "font-variant-caps": "normal|small-caps|all-small-caps|petite-caps|all-petite-caps|unicase|titling-caps",
8765 "font-variant-east-asian": "normal|[<east-asian-variant-values>||<east-asian-width-values>||ruby]",
8766 "font-variant-ligatures": "normal|none|[<common-lig-values>||<discretionary-lig-values>||<historical-lig-values>||<contextual-alt-values>]",
8767 "font-variant-numeric": "normal|[<numeric-figure-values>||<numeric-spacing-values>||<numeric-fraction-values>||ordinal||slashed-zero]",
8768 "font-variant-position": "normal|sub|super",
8769 "font-weight": "<font-weight-absolute>|bolder|lighter",
8770 gap: "<'row-gap'> <'column-gap'>?",
8771 grid: "<'grid-template'>|<'grid-template-rows'> / [auto-flow&&dense?] <'grid-auto-columns'>?|[auto-flow&&dense?] <'grid-auto-rows'>? / <'grid-template-columns'>",
8772 "grid-area": "<grid-line> [/ <grid-line>]{0,3}",
8773 "grid-auto-columns": "<track-size>+",
8774 "grid-auto-flow": "[row|column]||dense",
8775 "grid-auto-rows": "<track-size>+",
8776 "grid-column": "<grid-line> [/ <grid-line>]?",
8777 "grid-column-end": "<grid-line>",
8778 "grid-column-gap": "<length-percentage>",
8779 "grid-column-start": "<grid-line>",
8780 "grid-gap": "<'grid-row-gap'> <'grid-column-gap'>?",
8781 "grid-row": "<grid-line> [/ <grid-line>]?",
8782 "grid-row-end": "<grid-line>",
8783 "grid-row-gap": "<length-percentage>",
8784 "grid-row-start": "<grid-line>",
8785 "grid-template": "none|[<'grid-template-rows'> / <'grid-template-columns'>]|[<line-names>? <string> <track-size>? <line-names>?]+ [/ <explicit-track-list>]?",
8786 "grid-template-areas": "none|<string>+",
8787 "grid-template-columns": "none|<track-list>|<auto-track-list>",
8788 "grid-template-rows": "none|<track-list>|<auto-track-list>",
8789 "hanging-punctuation": "none|[first||[force-end|allow-end]||last]",
8790 height: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
8791 hyphens: "none|manual|auto",
8792 "image-orientation": "from-image|<angle>|[<angle>? flip]",
8793 "image-rendering": "auto|crisp-edges|pixelated|optimizeSpeed|optimizeQuality|<-non-standard-image-rendering>",
8794 "image-resolution": "[from-image||<resolution>]&&snap?",
8795 "ime-mode": "auto|normal|active|inactive|disabled",
8796 "initial-letter": "normal|[<number> <integer>?]",
8797 "initial-letter-align": "[auto|alphabetic|hanging|ideographic]",
8798 "inline-size": "<'width'>",
8799 inset: "<'top'>{1,4}",
8800 "inset-block": "<'top'>{1,2}",
8801 "inset-block-end": "<'top'>",
8802 "inset-block-start": "<'top'>",
8803 "inset-inline": "<'top'>{1,2}",
8804 "inset-inline-end": "<'top'>",
8805 "inset-inline-start": "<'top'>",
8806 isolation: "auto|isolate",
8807 "justify-content": "normal|<content-distribution>|<overflow-position>? [<content-position>|left|right]",
8808 "justify-items": "normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]|legacy|legacy&&[left|right|center]",
8809 "justify-self": "auto|normal|stretch|<baseline-position>|<overflow-position>? [<self-position>|left|right]",
8810 left: "<length>|<percentage>|auto",
8811 "letter-spacing": "normal|<length-percentage>",
8812 "line-break": "auto|loose|normal|strict",
8813 "line-clamp": "none|<integer>",
8814 "line-height": "normal|<number>|<length>|<percentage>",
8815 "line-height-step": "<length>",
8816 "list-style": "<'list-style-type'>||<'list-style-position'>||<'list-style-image'>",
8817 "list-style-image": "<url>|none",
8818 "list-style-position": "inside|outside",
8819 "list-style-type": "<counter-style>|<string>|none",
8820 margin: "[<length>|<percentage>|auto]{1,4}",
8821 "margin-block": "<'margin-left'>{1,2}",
8822 "margin-block-end": "<'margin-left'>",
8823 "margin-block-start": "<'margin-left'>",
8824 "margin-bottom": "<length>|<percentage>|auto",
8825 "margin-inline": "<'margin-left'>{1,2}",
8826 "margin-inline-end": "<'margin-left'>",
8827 "margin-inline-start": "<'margin-left'>",
8828 "margin-left": "<length>|<percentage>|auto",
8829 "margin-right": "<length>|<percentage>|auto",
8830 "margin-top": "<length>|<percentage>|auto",
8831 mask: "<mask-layer>#",
8832 "mask-border": "<'mask-border-source'>||<'mask-border-slice'> [/ <'mask-border-width'>? [/ <'mask-border-outset'>]?]?||<'mask-border-repeat'>||<'mask-border-mode'>",
8833 "mask-border-mode": "luminance|alpha",
8834 "mask-border-outset": "[<length>|<number>]{1,4}",
8835 "mask-border-repeat": "[stretch|repeat|round|space]{1,2}",
8836 "mask-border-slice": "<number-percentage>{1,4} fill?",
8837 "mask-border-source": "none|<image>",
8838 "mask-border-width": "[<length-percentage>|<number>|auto]{1,4}",
8839 "mask-clip": "[<geometry-box>|no-clip]#",
8840 "mask-composite": "<compositing-operator>#",
8841 "mask-image": "<mask-reference>#",
8842 "mask-mode": "<masking-mode>#",
8843 "mask-origin": "<geometry-box>#",
8844 "mask-position": "<position>#",
8845 "mask-repeat": "<repeat-style>#",
8846 "mask-size": "<bg-size>#",
8847 "mask-type": "luminance|alpha",
8848 "max-block-size": "<'max-width'>",
8849 "max-height": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available",
8850 "max-inline-size": "<'max-width'>",
8851 "max-lines": "none|<integer>",
8852 "max-width": "<length>|<percentage>|none|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
8853 "min-block-size": "<'min-width'>",
8854 "min-height": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available",
8855 "min-inline-size": "<'min-width'>",
8856 "min-width": "<length>|<percentage>|auto|max-content|min-content|fit-content|fill-available|<-non-standard-width>",
8857 "mix-blend-mode": "<blend-mode>",
8858 "object-fit": "fill|contain|cover|none|scale-down",
8859 "object-position": "<position>",
8860 offset: "[<'offset-position'>? [<'offset-path'> [<'offset-distance'>||<'offset-rotate'>]?]?]! [/ <'offset-anchor'>]?",
8861 "offset-anchor": "auto|<position>",
8862 "offset-distance": "<length-percentage>",
8863 "offset-path": "none|ray( [<angle>&&<size>?&&contain?] )|<path()>|<url>|[<basic-shape>||<geometry-box>]",
8864 "offset-position": "auto|<position>",
8865 "offset-rotate": "[auto|reverse]||<angle>",
8866 opacity: "<number-zero-one>",
8867 order: "<integer>",
8868 orphans: "<integer>",
8869 outline: "[<'outline-color'>||<'outline-style'>||<'outline-width'>]",
8870 "outline-color": "<color>|invert",
8871 "outline-offset": "<length>",
8872 "outline-style": "auto|<'border-style'>",
8873 "outline-width": "<line-width>",
8874 overflow: "[visible|hidden|clip|scroll|auto]{1,2}|<-non-standard-overflow>",
8875 "overflow-anchor": "auto|none",
8876 "overflow-block": "visible|hidden|clip|scroll|auto",
8877 "overflow-clip-box": "padding-box|content-box",
8878 "overflow-inline": "visible|hidden|clip|scroll|auto",
8879 "overflow-wrap": "normal|break-word|anywhere",
8880 "overflow-x": "visible|hidden|clip|scroll|auto",
8881 "overflow-y": "visible|hidden|clip|scroll|auto",
8882 "overscroll-behavior": "[contain|none|auto]{1,2}",
8883 "overscroll-behavior-x": "contain|none|auto",
8884 "overscroll-behavior-y": "contain|none|auto",
8885 padding: "[<length>|<percentage>]{1,4}",
8886 "padding-block": "<'padding-left'>{1,2}",
8887 "padding-block-end": "<'padding-left'>",
8888 "padding-block-start": "<'padding-left'>",
8889 "padding-bottom": "<length>|<percentage>",
8890 "padding-inline": "<'padding-left'>{1,2}",
8891 "padding-inline-end": "<'padding-left'>",
8892 "padding-inline-start": "<'padding-left'>",
8893 "padding-left": "<length>|<percentage>",
8894 "padding-right": "<length>|<percentage>",
8895 "padding-top": "<length>|<percentage>",
8896 "page-break-after": "auto|always|avoid|left|right|recto|verso",
8897 "page-break-before": "auto|always|avoid|left|right|recto|verso",
8898 "page-break-inside": "auto|avoid",
8899 "paint-order": "normal|[fill||stroke||markers]",
8900 perspective: "none|<length>",
8901 "perspective-origin": "<position>",
8902 "place-content": "<'align-content'> <'justify-content'>?",
8903 "place-items": "<'align-items'> <'justify-items'>?",
8904 "place-self": "<'align-self'> <'justify-self'>?",
8905 "pointer-events": "auto|none|visiblePainted|visibleFill|visibleStroke|visible|painted|fill|stroke|all|inherit",
8906 position: "static|relative|absolute|sticky|fixed|-webkit-sticky",
8907 quotes: "none|[<string> <string>]+",
8908 resize: "none|both|horizontal|vertical|block|inline",
8909 right: "<length>|<percentage>|auto",
8910 rotate: "none|<angle>|[x|y|z|<number>{3}]&&<angle>",
8911 "row-gap": "normal|<length-percentage>",
8912 "ruby-align": "start|center|space-between|space-around",
8913 "ruby-merge": "separate|collapse|auto",
8914 "ruby-position": "over|under|inter-character",
8915 scale: "none|<number>{1,3}",
8916 "scrollbar-color": "auto|dark|light|<color>{2}",
8917 "scrollbar-width": "auto|thin|none",
8918 "scroll-behavior": "auto|smooth",
8919 "scroll-margin": "<length>{1,4}",
8920 "scroll-margin-block": "<length>{1,2}",
8921 "scroll-margin-block-start": "<length>",
8922 "scroll-margin-block-end": "<length>",
8923 "scroll-margin-bottom": "<length>",
8924 "scroll-margin-inline": "<length>{1,2}",
8925 "scroll-margin-inline-start": "<length>",
8926 "scroll-margin-inline-end": "<length>",
8927 "scroll-margin-left": "<length>",
8928 "scroll-margin-right": "<length>",
8929 "scroll-margin-top": "<length>",
8930 "scroll-padding": "[auto|<length-percentage>]{1,4}",
8931 "scroll-padding-block": "[auto|<length-percentage>]{1,2}",
8932 "scroll-padding-block-start": "auto|<length-percentage>",
8933 "scroll-padding-block-end": "auto|<length-percentage>",
8934 "scroll-padding-bottom": "auto|<length-percentage>",
8935 "scroll-padding-inline": "[auto|<length-percentage>]{1,2}",
8936 "scroll-padding-inline-start": "auto|<length-percentage>",
8937 "scroll-padding-inline-end": "auto|<length-percentage>",
8938 "scroll-padding-left": "auto|<length-percentage>",
8939 "scroll-padding-right": "auto|<length-percentage>",
8940 "scroll-padding-top": "auto|<length-percentage>",
8941 "scroll-snap-align": "[none|start|end|center]{1,2}",
8942 "scroll-snap-coordinate": "none|<position>#",
8943 "scroll-snap-destination": "<position>",
8944 "scroll-snap-points-x": "none|repeat( <length-percentage> )",
8945 "scroll-snap-points-y": "none|repeat( <length-percentage> )",
8946 "scroll-snap-stop": "normal|always",
8947 "scroll-snap-type": "none|[x|y|block|inline|both] [mandatory|proximity]?",
8948 "scroll-snap-type-x": "none|mandatory|proximity",
8949 "scroll-snap-type-y": "none|mandatory|proximity",
8950 "shape-image-threshold": "<number>",
8951 "shape-margin": "<length-percentage>",
8952 "shape-outside": "none|<shape-box>||<basic-shape>|<image>",
8953 "tab-size": "<integer>|<length>",
8954 "table-layout": "auto|fixed",
8955 "text-align": "start|end|left|right|center|justify|match-parent",
8956 "text-align-last": "auto|start|end|left|right|center|justify",
8957 "text-combine-upright": "none|all|[digits <integer>?]",
8958 "text-decoration": "<'text-decoration-line'>||<'text-decoration-style'>||<'text-decoration-color'>",
8959 "text-decoration-color": "<color>",
8960 "text-decoration-line": "none|[underline||overline||line-through||blink]",
8961 "text-decoration-skip": "none|[objects||[spaces|[leading-spaces||trailing-spaces]]||edges||box-decoration]",
8962 "text-decoration-skip-ink": "auto|none",
8963 "text-decoration-style": "solid|double|dotted|dashed|wavy",
8964 "text-emphasis": "<'text-emphasis-style'>||<'text-emphasis-color'>",
8965 "text-emphasis-color": "<color>",
8966 "text-emphasis-position": "[over|under]&&[right|left]",
8967 "text-emphasis-style": "none|[[filled|open]||[dot|circle|double-circle|triangle|sesame]]|<string>",
8968 "text-indent": "<length-percentage>&&hanging?&&each-line?",
8969 "text-justify": "auto|inter-character|inter-word|none",
8970 "text-orientation": "mixed|upright|sideways",
8971 "text-overflow": "[clip|ellipsis|<string>]{1,2}",
8972 "text-rendering": "auto|optimizeSpeed|optimizeLegibility|geometricPrecision",
8973 "text-shadow": "none|<shadow-t>#",
8974 "text-size-adjust": "none|auto|<percentage>",
8975 "text-transform": "none|capitalize|uppercase|lowercase|full-width|full-size-kana",
8976 "text-underline-position": "auto|[under||[left|right]]",
8977 top: "<length>|<percentage>|auto",
8978 "touch-action": "auto|none|[[pan-x|pan-left|pan-right]||[pan-y|pan-up|pan-down]||pinch-zoom]|manipulation",
8979 transform: "none|<transform-list>",
8980 "transform-box": "border-box|fill-box|view-box",
8981 "transform-origin": "[<length-percentage>|left|center|right|top|bottom]|[[<length-percentage>|left|center|right]&&[<length-percentage>|top|center|bottom]] <length>?",
8982 "transform-style": "flat|preserve-3d",
8983 transition: "<single-transition>#",
8984 "transition-delay": "<time>#",
8985 "transition-duration": "<time>#",
8986 "transition-property": "none|<single-transition-property>#",
8987 "transition-timing-function": "<timing-function>#",
8988 translate: "none|<length-percentage> [<length-percentage> <length>?]?",
8989 "unicode-bidi": "normal|embed|isolate|bidi-override|isolate-override|plaintext|-moz-isolate|-moz-isolate-override|-moz-plaintext|-webkit-isolate",
8990 "user-select": "auto|text|none|contain|all",
8991 "vertical-align": "baseline|sub|super|text-top|text-bottom|middle|top|bottom|<percentage>|<length>",
8992 visibility: "visible|hidden|collapse",
8993 "white-space": "normal|pre|nowrap|pre-wrap|pre-line",
8994 widows: "<integer>",
8995 width: "[<length>|<percentage>]&&[border-box|content-box]?|available|min-content|max-content|fit-content|auto",
8996 "will-change": "auto|<animateable-feature>#",
8997 "word-break": "normal|break-all|keep-all|break-word",
8998 "word-spacing": "normal|<length-percentage>",
8999 "word-wrap": "normal|break-word",
9000 "writing-mode": "horizontal-tb|vertical-rl|vertical-lr|sideways-rl|sideways-lr|<svg-writing-mode>",
9001 "z-index": "auto|<integer>",
9002 zoom: "normal|reset|<number>|<percentage>",
9003 "-moz-background-clip": "padding|border",
9004 "-moz-border-radius-bottomleft": "<'border-bottom-left-radius'>",
9005 "-moz-border-radius-bottomright": "<'border-bottom-right-radius'>",
9006 "-moz-border-radius-topleft": "<'border-top-left-radius'>",
9007 "-moz-border-radius-topright": "<'border-bottom-right-radius'>",
9008 "-moz-osx-font-smoothing": "auto|grayscale",
9009 "-moz-user-select": "none|text|all|-moz-none",
9010 "-ms-flex-align": "start|end|center|baseline|stretch",
9011 "-ms-flex-item-align": "auto|start|end|center|baseline|stretch",
9012 "-ms-flex-line-pack": "start|end|center|justify|distribute|stretch",
9013 "-ms-flex-negative": "<'flex-shrink'>",
9014 "-ms-flex-pack": "start|end|center|justify|distribute",
9015 "-ms-flex-order": "<integer>",
9016 "-ms-flex-positive": "<'flex-grow'>",
9017 "-ms-flex-preferred-size": "<'flex-basis'>",
9018 "-ms-interpolation-mode": "nearest-neighbor|bicubic",
9019 "-ms-grid-column-align": "start|end|center|stretch",
9020 "-ms-grid-row-align": "start|end|center|stretch",
9021 "-webkit-background-clip": "[<box>|border|padding|content|text]#",
9022 "-webkit-column-break-after": "always|auto|avoid",
9023 "-webkit-column-break-before": "always|auto|avoid",
9024 "-webkit-column-break-inside": "always|auto|avoid",
9025 "-webkit-font-smoothing": "auto|none|antialiased|subpixel-antialiased",
9026 "-webkit-mask-box-image": "[<url>|<gradient>|none] [<length-percentage>{4} <-webkit-mask-box-repeat>{2}]?",
9027 "-webkit-print-color-adjust": "economy|exact",
9028 "-webkit-text-security": "none|circle|disc|square",
9029 "-webkit-user-drag": "none|element|auto",
9030 "-webkit-user-select": "auto|none|text|all",
9031 "alignment-baseline": "auto|baseline|before-edge|text-before-edge|middle|central|after-edge|text-after-edge|ideographic|alphabetic|hanging|mathematical",
9032 "baseline-shift": "baseline|sub|super|<svg-length>",
9033 behavior: "<url>+",
9034 "clip-rule": "nonzero|evenodd",
9035 cue: "<'cue-before'> <'cue-after'>?",
9036 "cue-after": "<url> <decibel>?|none",
9037 "cue-before": "<url> <decibel>?|none",
9038 "dominant-baseline": "auto|use-script|no-change|reset-size|ideographic|alphabetic|hanging|mathematical|central|middle|text-after-edge|text-before-edge",
9039 fill: "<paint>",
9040 "fill-opacity": "<number-zero-one>",
9041 "fill-rule": "nonzero|evenodd",
9042 "glyph-orientation-horizontal": "<angle>",
9043 "glyph-orientation-vertical": "<angle>",
9044 kerning: "auto|<svg-length>",
9045 marker: "none|<url>",
9046 "marker-end": "none|<url>",
9047 "marker-mid": "none|<url>",
9048 "marker-start": "none|<url>",
9049 pause: "<'pause-before'> <'pause-after'>?",
9050 "pause-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
9051 "pause-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
9052 rest: "<'rest-before'> <'rest-after'>?",
9053 "rest-after": "<time>|none|x-weak|weak|medium|strong|x-strong",
9054 "rest-before": "<time>|none|x-weak|weak|medium|strong|x-strong",
9055 "shape-rendering": "auto|optimizeSpeed|crispEdges|geometricPrecision",
9056 src: "[<url> [format( <string># )]?|local( <family-name> )]#",
9057 speak: "auto|none|normal",
9058 "speak-as": "normal|spell-out||digits||[literal-punctuation|no-punctuation]",
9059 stroke: "<paint>",
9060 "stroke-dasharray": "none|[<svg-length>+]#",
9061 "stroke-dashoffset": "<svg-length>",
9062 "stroke-linecap": "butt|round|square",
9063 "stroke-linejoin": "miter|round|bevel",
9064 "stroke-miterlimit": "<number-one-or-greater>",
9065 "stroke-opacity": "<number-zero-one>",
9066 "stroke-width": "<svg-length>",
9067 "text-anchor": "start|middle|end",
9068 "unicode-range": "<urange>#",
9069 "voice-balance": "<number>|left|center|right|leftwards|rightwards",
9070 "voice-duration": "auto|<time>",
9071 "voice-family": "[[<family-name>|<generic-voice>] ,]* [<family-name>|<generic-voice>]|preserve",
9072 "voice-pitch": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
9073 "voice-range": "<frequency>&&absolute|[[x-low|low|medium|high|x-high]||[<frequency>|<semitones>|<percentage>]]",
9074 "voice-rate": "[normal|x-slow|slow|medium|fast|x-fast]||<percentage>",
9075 "voice-stress": "normal|strong|moderate|none|reduced",
9076 "voice-volume": "silent|[[x-soft|soft|medium|loud|x-loud]||<decibel>]"
9077 };
9078 var defaultSyntax = {
9079 generic: generic$1,
9080 types: types,
9081 properties: properties$1
9082 };
9083
9084 var defaultSyntax$1 = /*#__PURE__*/Object.freeze({
9085 __proto__: null,
9086 generic: generic$1,
9087 types: types,
9088 properties: properties$1,
9089 'default': defaultSyntax
9090 });
9091
9092 var cmpChar$3 = tokenizer.cmpChar;
9093 var isDigit$4 = tokenizer.isDigit;
9094 var TYPE$9 = tokenizer.TYPE;
9095
9096 var WHITESPACE$4 = TYPE$9.WhiteSpace;
9097 var COMMENT$3 = TYPE$9.Comment;
9098 var IDENT$3 = TYPE$9.Ident;
9099 var NUMBER$3 = TYPE$9.Number;
9100 var DIMENSION$2 = TYPE$9.Dimension;
9101 var PLUSSIGN$3 = 0x002B; // U+002B PLUS SIGN (+)
9102 var HYPHENMINUS$3 = 0x002D; // U+002D HYPHEN-MINUS (-)
9103 var N$4 = 0x006E; // U+006E LATIN SMALL LETTER N (n)
9104 var DISALLOW_SIGN$1 = true;
9105 var ALLOW_SIGN$1 = false;
9106
9107 function checkInteger$1(offset, disallowSign) {
9108 var pos = this.scanner.tokenStart + offset;
9109 var code = this.scanner.source.charCodeAt(pos);
9110
9111 if (code === PLUSSIGN$3 || code === HYPHENMINUS$3) {
9112 if (disallowSign) {
9113 this.error('Number sign is not allowed');
9114 }
9115 pos++;
9116 }
9117
9118 for (; pos < this.scanner.tokenEnd; pos++) {
9119 if (!isDigit$4(this.scanner.source.charCodeAt(pos))) {
9120 this.error('Integer is expected', pos);
9121 }
9122 }
9123 }
9124
9125 function checkTokenIsInteger(disallowSign) {
9126 return checkInteger$1.call(this, 0, disallowSign);
9127 }
9128
9129 function expectCharCode(offset, code) {
9130 if (!cmpChar$3(this.scanner.source, this.scanner.tokenStart + offset, code)) {
9131 var msg = '';
9132
9133 switch (code) {
9134 case N$4:
9135 msg = 'N is expected';
9136 break;
9137 case HYPHENMINUS$3:
9138 msg = 'HyphenMinus is expected';
9139 break;
9140 }
9141
9142 this.error(msg, this.scanner.tokenStart + offset);
9143 }
9144 }
9145
9146 // ... <signed-integer>
9147 // ... ['+' | '-'] <signless-integer>
9148 function consumeB$1() {
9149 var offset = 0;
9150 var sign = 0;
9151 var type = this.scanner.tokenType;
9152
9153 while (type === WHITESPACE$4 || type === COMMENT$3) {
9154 type = this.scanner.lookupType(++offset);
9155 }
9156
9157 if (type !== NUMBER$3) {
9158 if (this.scanner.isDelim(PLUSSIGN$3, offset) ||
9159 this.scanner.isDelim(HYPHENMINUS$3, offset)) {
9160 sign = this.scanner.isDelim(PLUSSIGN$3, offset) ? PLUSSIGN$3 : HYPHENMINUS$3;
9161
9162 do {
9163 type = this.scanner.lookupType(++offset);
9164 } while (type === WHITESPACE$4 || type === COMMENT$3);
9165
9166 if (type !== NUMBER$3) {
9167 this.scanner.skip(offset);
9168 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
9169 }
9170 } else {
9171 return null;
9172 }
9173 }
9174
9175 if (offset > 0) {
9176 this.scanner.skip(offset);
9177 }
9178
9179 if (sign === 0) {
9180 type = this.scanner.source.charCodeAt(this.scanner.tokenStart);
9181 if (type !== PLUSSIGN$3 && type !== HYPHENMINUS$3) {
9182 this.error('Number sign is expected');
9183 }
9184 }
9185
9186 checkTokenIsInteger.call(this, sign !== 0);
9187 return sign === HYPHENMINUS$3 ? '-' + this.consume(NUMBER$3) : this.consume(NUMBER$3);
9188 }
9189
9190 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
9191 var AnPlusB = {
9192 name: 'AnPlusB',
9193 structure: {
9194 a: [String, null],
9195 b: [String, null]
9196 },
9197 parse: function() {
9198 /* eslint-disable brace-style*/
9199 var start = this.scanner.tokenStart;
9200 var a = null;
9201 var b = null;
9202
9203 // <integer>
9204 if (this.scanner.tokenType === NUMBER$3) {
9205 checkTokenIsInteger.call(this, ALLOW_SIGN$1);
9206 b = this.consume(NUMBER$3);
9207 }
9208
9209 // -n
9210 // -n <signed-integer>
9211 // -n ['+' | '-'] <signless-integer>
9212 // -n- <signless-integer>
9213 // <dashndashdigit-ident>
9214 else if (this.scanner.tokenType === IDENT$3 && cmpChar$3(this.scanner.source, this.scanner.tokenStart, HYPHENMINUS$3)) {
9215 a = '-1';
9216
9217 expectCharCode.call(this, 1, N$4);
9218
9219 switch (this.scanner.getTokenLength()) {
9220 // -n
9221 // -n <signed-integer>
9222 // -n ['+' | '-'] <signless-integer>
9223 case 2:
9224 this.scanner.next();
9225 b = consumeB$1.call(this);
9226 break;
9227
9228 // -n- <signless-integer>
9229 case 3:
9230 expectCharCode.call(this, 2, HYPHENMINUS$3);
9231
9232 this.scanner.next();
9233 this.scanner.skipSC();
9234
9235 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
9236
9237 b = '-' + this.consume(NUMBER$3);
9238 break;
9239
9240 // <dashndashdigit-ident>
9241 default:
9242 expectCharCode.call(this, 2, HYPHENMINUS$3);
9243 checkInteger$1.call(this, 3, DISALLOW_SIGN$1);
9244 this.scanner.next();
9245
9246 b = this.scanner.substrToCursor(start + 2);
9247 }
9248 }
9249
9250 // '+'? n
9251 // '+'? n <signed-integer>
9252 // '+'? n ['+' | '-'] <signless-integer>
9253 // '+'? n- <signless-integer>
9254 // '+'? <ndashdigit-ident>
9255 else if (this.scanner.tokenType === IDENT$3 || (this.scanner.isDelim(PLUSSIGN$3) && this.scanner.lookupType(1) === IDENT$3)) {
9256 var sign = 0;
9257 a = '1';
9258
9259 // just ignore a plus
9260 if (this.scanner.isDelim(PLUSSIGN$3)) {
9261 sign = 1;
9262 this.scanner.next();
9263 }
9264
9265 expectCharCode.call(this, 0, N$4);
9266
9267 switch (this.scanner.getTokenLength()) {
9268 // '+'? n
9269 // '+'? n <signed-integer>
9270 // '+'? n ['+' | '-'] <signless-integer>
9271 case 1:
9272 this.scanner.next();
9273 b = consumeB$1.call(this);
9274 break;
9275
9276 // '+'? n- <signless-integer>
9277 case 2:
9278 expectCharCode.call(this, 1, HYPHENMINUS$3);
9279
9280 this.scanner.next();
9281 this.scanner.skipSC();
9282
9283 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
9284
9285 b = '-' + this.consume(NUMBER$3);
9286 break;
9287
9288 // '+'? <ndashdigit-ident>
9289 default:
9290 expectCharCode.call(this, 1, HYPHENMINUS$3);
9291 checkInteger$1.call(this, 2, DISALLOW_SIGN$1);
9292 this.scanner.next();
9293
9294 b = this.scanner.substrToCursor(start + sign + 1);
9295 }
9296 }
9297
9298 // <ndashdigit-dimension>
9299 // <ndash-dimension> <signless-integer>
9300 // <n-dimension>
9301 // <n-dimension> <signed-integer>
9302 // <n-dimension> ['+' | '-'] <signless-integer>
9303 else if (this.scanner.tokenType === DIMENSION$2) {
9304 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
9305 var sign = code === PLUSSIGN$3 || code === HYPHENMINUS$3;
9306
9307 for (var i = this.scanner.tokenStart + sign; i < this.scanner.tokenEnd; i++) {
9308 if (!isDigit$4(this.scanner.source.charCodeAt(i))) {
9309 break;
9310 }
9311 }
9312
9313 if (i === this.scanner.tokenStart + sign) {
9314 this.error('Integer is expected', this.scanner.tokenStart + sign);
9315 }
9316
9317 expectCharCode.call(this, i - this.scanner.tokenStart, N$4);
9318 a = this.scanner.source.substring(start, i);
9319
9320 // <n-dimension>
9321 // <n-dimension> <signed-integer>
9322 // <n-dimension> ['+' | '-'] <signless-integer>
9323 if (i + 1 === this.scanner.tokenEnd) {
9324 this.scanner.next();
9325 b = consumeB$1.call(this);
9326 } else {
9327 expectCharCode.call(this, i - this.scanner.tokenStart + 1, HYPHENMINUS$3);
9328
9329 // <ndash-dimension> <signless-integer>
9330 if (i + 2 === this.scanner.tokenEnd) {
9331 this.scanner.next();
9332 this.scanner.skipSC();
9333 checkTokenIsInteger.call(this, DISALLOW_SIGN$1);
9334 b = '-' + this.consume(NUMBER$3);
9335 }
9336 // <ndashdigit-dimension>
9337 else {
9338 checkInteger$1.call(this, i - this.scanner.tokenStart + 2, DISALLOW_SIGN$1);
9339 this.scanner.next();
9340 b = this.scanner.substrToCursor(i + 1);
9341 }
9342 }
9343 } else {
9344 this.error();
9345 }
9346
9347 if (a !== null && a.charCodeAt(0) === PLUSSIGN$3) {
9348 a = a.substr(1);
9349 }
9350
9351 if (b !== null && b.charCodeAt(0) === PLUSSIGN$3) {
9352 b = b.substr(1);
9353 }
9354
9355 return {
9356 type: 'AnPlusB',
9357 loc: this.getLocation(start, this.scanner.tokenStart),
9358 a: a,
9359 b: b
9360 };
9361 },
9362 generate: function(node) {
9363 var a = node.a !== null && node.a !== undefined;
9364 var b = node.b !== null && node.b !== undefined;
9365
9366 if (a) {
9367 this.chunk(
9368 node.a === '+1' ? '+n' : // eslint-disable-line operator-linebreak, indent
9369 node.a === '1' ? 'n' : // eslint-disable-line operator-linebreak, indent
9370 node.a === '-1' ? '-n' : // eslint-disable-line operator-linebreak, indent
9371 node.a + 'n' // eslint-disable-line operator-linebreak, indent
9372 );
9373
9374 if (b) {
9375 b = String(node.b);
9376 if (b.charAt(0) === '-' || b.charAt(0) === '+') {
9377 this.chunk(b.charAt(0));
9378 this.chunk(b.substr(1));
9379 } else {
9380 this.chunk('+');
9381 this.chunk(b);
9382 }
9383 }
9384 } else {
9385 this.chunk(String(node.b));
9386 }
9387 }
9388 };
9389
9390 var TYPE$a = tokenizer.TYPE;
9391
9392 var WhiteSpace = TYPE$a.WhiteSpace;
9393 var Semicolon = TYPE$a.Semicolon;
9394 var LeftCurlyBracket = TYPE$a.LeftCurlyBracket;
9395 var Delim = TYPE$a.Delim;
9396 var EXCLAMATIONMARK$1 = 0x0021; // U+0021 EXCLAMATION MARK (!)
9397
9398 function getOffsetExcludeWS() {
9399 if (this.scanner.tokenIndex > 0) {
9400 if (this.scanner.lookupType(-1) === WhiteSpace) {
9401 return this.scanner.tokenIndex > 1
9402 ? this.scanner.getTokenStart(this.scanner.tokenIndex - 1)
9403 : this.scanner.firstCharOffset;
9404 }
9405 }
9406
9407 return this.scanner.tokenStart;
9408 }
9409
9410 // 0, 0, false
9411 function balanceEnd() {
9412 return 0;
9413 }
9414
9415 // LEFTCURLYBRACKET, 0, false
9416 function leftCurlyBracket(tokenType) {
9417 return tokenType === LeftCurlyBracket ? 1 : 0;
9418 }
9419
9420 // LEFTCURLYBRACKET, SEMICOLON, false
9421 function leftCurlyBracketOrSemicolon(tokenType) {
9422 return tokenType === LeftCurlyBracket || tokenType === Semicolon ? 1 : 0;
9423 }
9424
9425 // EXCLAMATIONMARK, SEMICOLON, false
9426 function exclamationMarkOrSemicolon(tokenType, source, offset) {
9427 if (tokenType === Delim && source.charCodeAt(offset) === EXCLAMATIONMARK$1) {
9428 return 1;
9429 }
9430
9431 return tokenType === Semicolon ? 1 : 0;
9432 }
9433
9434 // 0, SEMICOLON, true
9435 function semicolonIncluded(tokenType) {
9436 return tokenType === Semicolon ? 2 : 0;
9437 }
9438
9439 var Raw = {
9440 name: 'Raw',
9441 structure: {
9442 value: String
9443 },
9444 parse: function(startToken, mode, excludeWhiteSpace) {
9445 var startOffset = this.scanner.getTokenStart(startToken);
9446 var endOffset;
9447
9448 this.scanner.skip(
9449 this.scanner.getRawLength(startToken, mode || balanceEnd)
9450 );
9451
9452 if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
9453 endOffset = getOffsetExcludeWS.call(this);
9454 } else {
9455 endOffset = this.scanner.tokenStart;
9456 }
9457
9458 return {
9459 type: 'Raw',
9460 loc: this.getLocation(startOffset, endOffset),
9461 value: this.scanner.source.substring(startOffset, endOffset)
9462 };
9463 },
9464 generate: function(node) {
9465 this.chunk(node.value);
9466 },
9467
9468 mode: {
9469 default: balanceEnd,
9470 leftCurlyBracket: leftCurlyBracket,
9471 leftCurlyBracketOrSemicolon: leftCurlyBracketOrSemicolon,
9472 exclamationMarkOrSemicolon: exclamationMarkOrSemicolon,
9473 semicolonIncluded: semicolonIncluded
9474 }
9475 };
9476
9477 var TYPE$b = tokenizer.TYPE;
9478 var rawMode = Raw.mode;
9479
9480 var ATKEYWORD = TYPE$b.AtKeyword;
9481 var SEMICOLON = TYPE$b.Semicolon;
9482 var LEFTCURLYBRACKET$1 = TYPE$b.LeftCurlyBracket;
9483 var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
9484
9485 function consumeRaw(startToken) {
9486 return this.Raw(startToken, rawMode.leftCurlyBracketOrSemicolon, true);
9487 }
9488
9489 function isDeclarationBlockAtrule() {
9490 for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
9491 if (type === RIGHTCURLYBRACKET$1) {
9492 return true;
9493 }
9494
9495 if (type === LEFTCURLYBRACKET$1 ||
9496 type === ATKEYWORD) {
9497 return false;
9498 }
9499 }
9500
9501 return false;
9502 }
9503
9504 var Atrule = {
9505 name: 'Atrule',
9506 structure: {
9507 name: String,
9508 prelude: ['AtrulePrelude', 'Raw', null],
9509 block: ['Block', null]
9510 },
9511 parse: function() {
9512 var start = this.scanner.tokenStart;
9513 var name;
9514 var nameLowerCase;
9515 var prelude = null;
9516 var block = null;
9517
9518 this.eat(ATKEYWORD);
9519
9520 name = this.scanner.substrToCursor(start + 1);
9521 nameLowerCase = name.toLowerCase();
9522 this.scanner.skipSC();
9523
9524 // parse prelude
9525 if (this.scanner.eof === false &&
9526 this.scanner.tokenType !== LEFTCURLYBRACKET$1 &&
9527 this.scanner.tokenType !== SEMICOLON) {
9528 if (this.parseAtrulePrelude) {
9529 prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
9530
9531 // turn empty AtrulePrelude into null
9532 if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
9533 prelude = null;
9534 }
9535 } else {
9536 prelude = consumeRaw.call(this, this.scanner.tokenIndex);
9537 }
9538
9539 this.scanner.skipSC();
9540 }
9541
9542 switch (this.scanner.tokenType) {
9543 case SEMICOLON:
9544 this.scanner.next();
9545 break;
9546
9547 case LEFTCURLYBRACKET$1:
9548 if (this.atrule.hasOwnProperty(nameLowerCase) &&
9549 typeof this.atrule[nameLowerCase].block === 'function') {
9550 block = this.atrule[nameLowerCase].block.call(this);
9551 } else {
9552 // TODO: should consume block content as Raw?
9553 block = this.Block(isDeclarationBlockAtrule.call(this));
9554 }
9555
9556 break;
9557 }
9558
9559 return {
9560 type: 'Atrule',
9561 loc: this.getLocation(start, this.scanner.tokenStart),
9562 name: name,
9563 prelude: prelude,
9564 block: block
9565 };
9566 },
9567 generate: function(node) {
9568 this.chunk('@');
9569 this.chunk(node.name);
9570
9571 if (node.prelude !== null) {
9572 this.chunk(' ');
9573 this.node(node.prelude);
9574 }
9575
9576 if (node.block) {
9577 this.node(node.block);
9578 } else {
9579 this.chunk(';');
9580 }
9581 },
9582 walkContext: 'atrule'
9583 };
9584
9585 var TYPE$c = tokenizer.TYPE;
9586
9587 var SEMICOLON$1 = TYPE$c.Semicolon;
9588 var LEFTCURLYBRACKET$2 = TYPE$c.LeftCurlyBracket;
9589
9590 var AtrulePrelude = {
9591 name: 'AtrulePrelude',
9592 structure: {
9593 children: [[]]
9594 },
9595 parse: function(name) {
9596 var children = null;
9597
9598 if (name !== null) {
9599 name = name.toLowerCase();
9600 }
9601
9602 this.scanner.skipSC();
9603
9604 if (this.atrule.hasOwnProperty(name) &&
9605 typeof this.atrule[name].prelude === 'function') {
9606 // custom consumer
9607 children = this.atrule[name].prelude.call(this);
9608 } else {
9609 // default consumer
9610 children = this.readSequence(this.scope.AtrulePrelude);
9611 }
9612
9613 this.scanner.skipSC();
9614
9615 if (this.scanner.eof !== true &&
9616 this.scanner.tokenType !== LEFTCURLYBRACKET$2 &&
9617 this.scanner.tokenType !== SEMICOLON$1) {
9618 this.error('Semicolon or block is expected');
9619 }
9620
9621 if (children === null) {
9622 children = this.createList();
9623 }
9624
9625 return {
9626 type: 'AtrulePrelude',
9627 loc: this.getLocationFromList(children),
9628 children: children
9629 };
9630 },
9631 generate: function(node) {
9632 this.children(node);
9633 },
9634 walkContext: 'atrulePrelude'
9635 };
9636
9637 var TYPE$d = tokenizer.TYPE;
9638
9639 var IDENT$4 = TYPE$d.Ident;
9640 var STRING = TYPE$d.String;
9641 var COLON = TYPE$d.Colon;
9642 var LEFTSQUAREBRACKET$1 = TYPE$d.LeftSquareBracket;
9643 var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
9644 var DOLLARSIGN = 0x0024; // U+0024 DOLLAR SIGN ($)
9645 var ASTERISK$1 = 0x002A; // U+002A ASTERISK (*)
9646 var EQUALSSIGN = 0x003D; // U+003D EQUALS SIGN (=)
9647 var CIRCUMFLEXACCENT = 0x005E; // U+005E (^)
9648 var VERTICALLINE$1 = 0x007C; // U+007C VERTICAL LINE (|)
9649 var TILDE = 0x007E; // U+007E TILDE (~)
9650
9651 function getAttributeName() {
9652 if (this.scanner.eof) {
9653 this.error('Unexpected end of input');
9654 }
9655
9656 var start = this.scanner.tokenStart;
9657 var expectIdent = false;
9658 var checkColon = true;
9659
9660 if (this.scanner.isDelim(ASTERISK$1)) {
9661 expectIdent = true;
9662 checkColon = false;
9663 this.scanner.next();
9664 } else if (!this.scanner.isDelim(VERTICALLINE$1)) {
9665 this.eat(IDENT$4);
9666 }
9667
9668 if (this.scanner.isDelim(VERTICALLINE$1)) {
9669 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 1) !== EQUALSSIGN) {
9670 this.scanner.next();
9671 this.eat(IDENT$4);
9672 } else if (expectIdent) {
9673 this.error('Identifier is expected', this.scanner.tokenEnd);
9674 }
9675 } else if (expectIdent) {
9676 this.error('Vertical line is expected');
9677 }
9678
9679 if (checkColon && this.scanner.tokenType === COLON) {
9680 this.scanner.next();
9681 this.eat(IDENT$4);
9682 }
9683
9684 return {
9685 type: 'Identifier',
9686 loc: this.getLocation(start, this.scanner.tokenStart),
9687 name: this.scanner.substrToCursor(start)
9688 };
9689 }
9690
9691 function getOperator() {
9692 var start = this.scanner.tokenStart;
9693 var code = this.scanner.source.charCodeAt(start);
9694
9695 if (code !== EQUALSSIGN && // =
9696 code !== TILDE && // ~=
9697 code !== CIRCUMFLEXACCENT && // ^=
9698 code !== DOLLARSIGN && // $=
9699 code !== ASTERISK$1 && // *=
9700 code !== VERTICALLINE$1 // |=
9701 ) {
9702 this.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
9703 }
9704
9705 this.scanner.next();
9706
9707 if (code !== EQUALSSIGN) {
9708 if (!this.scanner.isDelim(EQUALSSIGN)) {
9709 this.error('Equal sign is expected');
9710 }
9711
9712 this.scanner.next();
9713 }
9714
9715 return this.scanner.substrToCursor(start);
9716 }
9717
9718 // '[' <wq-name> ']'
9719 // '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
9720 var AttributeSelector = {
9721 name: 'AttributeSelector',
9722 structure: {
9723 name: 'Identifier',
9724 matcher: [String, null],
9725 value: ['String', 'Identifier', null],
9726 flags: [String, null]
9727 },
9728 parse: function() {
9729 var start = this.scanner.tokenStart;
9730 var name;
9731 var matcher = null;
9732 var value = null;
9733 var flags = null;
9734
9735 this.eat(LEFTSQUAREBRACKET$1);
9736 this.scanner.skipSC();
9737
9738 name = getAttributeName.call(this);
9739 this.scanner.skipSC();
9740
9741 if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
9742 // avoid case `[name i]`
9743 if (this.scanner.tokenType !== IDENT$4) {
9744 matcher = getOperator.call(this);
9745
9746 this.scanner.skipSC();
9747
9748 value = this.scanner.tokenType === STRING
9749 ? this.String()
9750 : this.Identifier();
9751
9752 this.scanner.skipSC();
9753 }
9754
9755 // attribute flags
9756 if (this.scanner.tokenType === IDENT$4) {
9757 flags = this.scanner.getTokenValue();
9758 this.scanner.next();
9759
9760 this.scanner.skipSC();
9761 }
9762 }
9763
9764 this.eat(RIGHTSQUAREBRACKET$1);
9765
9766 return {
9767 type: 'AttributeSelector',
9768 loc: this.getLocation(start, this.scanner.tokenStart),
9769 name: name,
9770 matcher: matcher,
9771 value: value,
9772 flags: flags
9773 };
9774 },
9775 generate: function(node) {
9776 var flagsPrefix = ' ';
9777
9778 this.chunk('[');
9779 this.node(node.name);
9780
9781 if (node.matcher !== null) {
9782 this.chunk(node.matcher);
9783
9784 if (node.value !== null) {
9785 this.node(node.value);
9786
9787 // space between string and flags is not required
9788 if (node.value.type === 'String') {
9789 flagsPrefix = '';
9790 }
9791 }
9792 }
9793
9794 if (node.flags !== null) {
9795 this.chunk(flagsPrefix);
9796 this.chunk(node.flags);
9797 }
9798
9799 this.chunk(']');
9800 }
9801 };
9802
9803 var TYPE$e = tokenizer.TYPE;
9804 var rawMode$1 = Raw.mode;
9805
9806 var WHITESPACE$5 = TYPE$e.WhiteSpace;
9807 var COMMENT$4 = TYPE$e.Comment;
9808 var SEMICOLON$2 = TYPE$e.Semicolon;
9809 var ATKEYWORD$1 = TYPE$e.AtKeyword;
9810 var LEFTCURLYBRACKET$3 = TYPE$e.LeftCurlyBracket;
9811 var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
9812
9813 function consumeRaw$1(startToken) {
9814 return this.Raw(startToken, null, true);
9815 }
9816 function consumeRule() {
9817 return this.parseWithFallback(this.Rule, consumeRaw$1);
9818 }
9819 function consumeRawDeclaration(startToken) {
9820 return this.Raw(startToken, rawMode$1.semicolonIncluded, true);
9821 }
9822 function consumeDeclaration() {
9823 if (this.scanner.tokenType === SEMICOLON$2) {
9824 return consumeRawDeclaration.call(this, this.scanner.tokenIndex);
9825 }
9826
9827 var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
9828
9829 if (this.scanner.tokenType === SEMICOLON$2) {
9830 this.scanner.next();
9831 }
9832
9833 return node;
9834 }
9835
9836 var Block = {
9837 name: 'Block',
9838 structure: {
9839 children: [[
9840 'Atrule',
9841 'Rule',
9842 'Declaration'
9843 ]]
9844 },
9845 parse: function(isDeclaration) {
9846 var consumer = isDeclaration ? consumeDeclaration : consumeRule;
9847
9848 var start = this.scanner.tokenStart;
9849 var children = this.createList();
9850
9851 this.eat(LEFTCURLYBRACKET$3);
9852
9853 scan:
9854 while (!this.scanner.eof) {
9855 switch (this.scanner.tokenType) {
9856 case RIGHTCURLYBRACKET$2:
9857 break scan;
9858
9859 case WHITESPACE$5:
9860 case COMMENT$4:
9861 this.scanner.next();
9862 break;
9863
9864 case ATKEYWORD$1:
9865 children.push(this.parseWithFallback(this.Atrule, consumeRaw$1));
9866 break;
9867
9868 default:
9869 children.push(consumer.call(this));
9870 }
9871 }
9872
9873 if (!this.scanner.eof) {
9874 this.eat(RIGHTCURLYBRACKET$2);
9875 }
9876
9877 return {
9878 type: 'Block',
9879 loc: this.getLocation(start, this.scanner.tokenStart),
9880 children: children
9881 };
9882 },
9883 generate: function(node) {
9884 this.chunk('{');
9885 this.children(node, function(prev) {
9886 if (prev.type === 'Declaration') {
9887 this.chunk(';');
9888 }
9889 });
9890 this.chunk('}');
9891 },
9892 walkContext: 'block'
9893 };
9894
9895 var TYPE$f = tokenizer.TYPE;
9896
9897 var LEFTSQUAREBRACKET$2 = TYPE$f.LeftSquareBracket;
9898 var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
9899
9900 var Brackets = {
9901 name: 'Brackets',
9902 structure: {
9903 children: [[]]
9904 },
9905 parse: function(readSequence, recognizer) {
9906 var start = this.scanner.tokenStart;
9907 var children = null;
9908
9909 this.eat(LEFTSQUAREBRACKET$2);
9910
9911 children = readSequence.call(this, recognizer);
9912
9913 if (!this.scanner.eof) {
9914 this.eat(RIGHTSQUAREBRACKET$2);
9915 }
9916
9917 return {
9918 type: 'Brackets',
9919 loc: this.getLocation(start, this.scanner.tokenStart),
9920 children: children
9921 };
9922 },
9923 generate: function(node) {
9924 this.chunk('[');
9925 this.children(node);
9926 this.chunk(']');
9927 }
9928 };
9929
9930 var CDC = tokenizer.TYPE.CDC;
9931
9932 var CDC_1 = {
9933 name: 'CDC',
9934 structure: [],
9935 parse: function() {
9936 var start = this.scanner.tokenStart;
9937
9938 this.eat(CDC); // -->
9939
9940 return {
9941 type: 'CDC',
9942 loc: this.getLocation(start, this.scanner.tokenStart)
9943 };
9944 },
9945 generate: function() {
9946 this.chunk('-->');
9947 }
9948 };
9949
9950 var CDO = tokenizer.TYPE.CDO;
9951
9952 var CDO_1 = {
9953 name: 'CDO',
9954 structure: [],
9955 parse: function() {
9956 var start = this.scanner.tokenStart;
9957
9958 this.eat(CDO); // <!--
9959
9960 return {
9961 type: 'CDO',
9962 loc: this.getLocation(start, this.scanner.tokenStart)
9963 };
9964 },
9965 generate: function() {
9966 this.chunk('<!--');
9967 }
9968 };
9969
9970 var TYPE$g = tokenizer.TYPE;
9971
9972 var IDENT$5 = TYPE$g.Ident;
9973 var FULLSTOP = 0x002E; // U+002E FULL STOP (.)
9974
9975 // '.' ident
9976 var ClassSelector = {
9977 name: 'ClassSelector',
9978 structure: {
9979 name: String
9980 },
9981 parse: function() {
9982 if (!this.scanner.isDelim(FULLSTOP)) {
9983 this.error('Full stop is expected');
9984 }
9985
9986 this.scanner.next();
9987
9988 return {
9989 type: 'ClassSelector',
9990 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
9991 name: this.consume(IDENT$5)
9992 };
9993 },
9994 generate: function(node) {
9995 this.chunk('.');
9996 this.chunk(node.name);
9997 }
9998 };
9999
10000 var TYPE$h = tokenizer.TYPE;
10001
10002 var IDENT$6 = TYPE$h.Ident;
10003 var PLUSSIGN$4 = 0x002B; // U+002B PLUS SIGN (+)
10004 var SOLIDUS = 0x002F; // U+002F SOLIDUS (/)
10005 var GREATERTHANSIGN$1 = 0x003E; // U+003E GREATER-THAN SIGN (>)
10006 var TILDE$1 = 0x007E; // U+007E TILDE (~)
10007
10008 // + | > | ~ | /deep/
10009 var Combinator = {
10010 name: 'Combinator',
10011 structure: {
10012 name: String
10013 },
10014 parse: function() {
10015 var start = this.scanner.tokenStart;
10016 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
10017
10018 switch (code) {
10019 case GREATERTHANSIGN$1:
10020 case PLUSSIGN$4:
10021 case TILDE$1:
10022 this.scanner.next();
10023 break;
10024
10025 case SOLIDUS:
10026 this.scanner.next();
10027
10028 if (this.scanner.tokenType !== IDENT$6 || this.scanner.lookupValue(0, 'deep') === false) {
10029 this.error('Identifier `deep` is expected');
10030 }
10031
10032 this.scanner.next();
10033
10034 if (!this.scanner.isDelim(SOLIDUS)) {
10035 this.error('Solidus is expected');
10036 }
10037
10038 this.scanner.next();
10039 break;
10040
10041 default:
10042 this.error('Combinator is expected');
10043 }
10044
10045 return {
10046 type: 'Combinator',
10047 loc: this.getLocation(start, this.scanner.tokenStart),
10048 name: this.scanner.substrToCursor(start)
10049 };
10050 },
10051 generate: function(node) {
10052 this.chunk(node.name);
10053 }
10054 };
10055
10056 var TYPE$i = tokenizer.TYPE;
10057
10058 var COMMENT$5 = TYPE$i.Comment;
10059 var ASTERISK$2 = 0x002A; // U+002A ASTERISK (*)
10060 var SOLIDUS$1 = 0x002F; // U+002F SOLIDUS (/)
10061
10062 // '/*' .* '*/'
10063 var Comment = {
10064 name: 'Comment',
10065 structure: {
10066 value: String
10067 },
10068 parse: function() {
10069 var start = this.scanner.tokenStart;
10070 var end = this.scanner.tokenEnd;
10071
10072 this.eat(COMMENT$5);
10073
10074 if ((end - start + 2) >= 2 &&
10075 this.scanner.source.charCodeAt(end - 2) === ASTERISK$2 &&
10076 this.scanner.source.charCodeAt(end - 1) === SOLIDUS$1) {
10077 end -= 2;
10078 }
10079
10080 return {
10081 type: 'Comment',
10082 loc: this.getLocation(start, this.scanner.tokenStart),
10083 value: this.scanner.source.substring(start + 2, end)
10084 };
10085 },
10086 generate: function(node) {
10087 this.chunk('/*');
10088 this.chunk(node.value);
10089 this.chunk('*/');
10090 }
10091 };
10092
10093 var isCustomProperty$1 = names.isCustomProperty;
10094 var TYPE$j = tokenizer.TYPE;
10095 var rawMode$2 = Raw.mode;
10096
10097 var IDENT$7 = TYPE$j.Ident;
10098 var HASH$1 = TYPE$j.Hash;
10099 var COLON$1 = TYPE$j.Colon;
10100 var SEMICOLON$3 = TYPE$j.Semicolon;
10101 var DELIM$2 = TYPE$j.Delim;
10102 var EXCLAMATIONMARK$2 = 0x0021; // U+0021 EXCLAMATION MARK (!)
10103 var NUMBERSIGN$2 = 0x0023; // U+0023 NUMBER SIGN (#)
10104 var DOLLARSIGN$1 = 0x0024; // U+0024 DOLLAR SIGN ($)
10105 var AMPERSAND$1 = 0x0026; // U+0026 ANPERSAND (&)
10106 var ASTERISK$3 = 0x002A; // U+002A ASTERISK (*)
10107 var PLUSSIGN$5 = 0x002B; // U+002B PLUS SIGN (+)
10108 var SOLIDUS$2 = 0x002F; // U+002F SOLIDUS (/)
10109
10110 function consumeValueRaw(startToken) {
10111 return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, true);
10112 }
10113
10114 function consumeCustomPropertyRaw(startToken) {
10115 return this.Raw(startToken, rawMode$2.exclamationMarkOrSemicolon, false);
10116 }
10117
10118 function consumeValue() {
10119 var startValueToken = this.scanner.tokenIndex;
10120 var value = this.Value();
10121
10122 if (value.type !== 'Raw' &&
10123 this.scanner.eof === false &&
10124 this.scanner.tokenType !== SEMICOLON$3 &&
10125 this.scanner.isDelim(EXCLAMATIONMARK$2) === false &&
10126 this.scanner.isBalanceEdge(startValueToken) === false) {
10127 this.error();
10128 }
10129
10130 return value;
10131 }
10132
10133 var Declaration = {
10134 name: 'Declaration',
10135 structure: {
10136 important: [Boolean, String],
10137 property: String,
10138 value: ['Value', 'Raw']
10139 },
10140 parse: function() {
10141 var start = this.scanner.tokenStart;
10142 var startToken = this.scanner.tokenIndex;
10143 var property = readProperty$1.call(this);
10144 var customProperty = isCustomProperty$1(property);
10145 var parseValue = customProperty ? this.parseCustomProperty : this.parseValue;
10146 var consumeRaw = customProperty ? consumeCustomPropertyRaw : consumeValueRaw;
10147 var important = false;
10148 var value;
10149
10150 this.scanner.skipSC();
10151 this.eat(COLON$1);
10152
10153 if (!customProperty) {
10154 this.scanner.skipSC();
10155 }
10156
10157 if (parseValue) {
10158 value = this.parseWithFallback(consumeValue, consumeRaw);
10159 } else {
10160 value = consumeRaw.call(this, this.scanner.tokenIndex);
10161 }
10162
10163 if (this.scanner.isDelim(EXCLAMATIONMARK$2)) {
10164 important = getImportant.call(this);
10165 this.scanner.skipSC();
10166 }
10167
10168 // Do not include semicolon to range per spec
10169 // https://drafts.csswg.org/css-syntax/#declaration-diagram
10170
10171 if (this.scanner.eof === false &&
10172 this.scanner.tokenType !== SEMICOLON$3 &&
10173 this.scanner.isBalanceEdge(startToken) === false) {
10174 this.error();
10175 }
10176
10177 return {
10178 type: 'Declaration',
10179 loc: this.getLocation(start, this.scanner.tokenStart),
10180 important: important,
10181 property: property,
10182 value: value
10183 };
10184 },
10185 generate: function(node) {
10186 this.chunk(node.property);
10187 this.chunk(':');
10188 this.node(node.value);
10189
10190 if (node.important) {
10191 this.chunk(node.important === true ? '!important' : '!' + node.important);
10192 }
10193 },
10194 walkContext: 'declaration'
10195 };
10196
10197 function readProperty$1() {
10198 var start = this.scanner.tokenStart;
10199
10200 // hacks
10201 if (this.scanner.tokenType === DELIM$2) {
10202 switch (this.scanner.source.charCodeAt(this.scanner.tokenStart)) {
10203 case ASTERISK$3:
10204 case DOLLARSIGN$1:
10205 case PLUSSIGN$5:
10206 case NUMBERSIGN$2:
10207 case AMPERSAND$1:
10208 this.scanner.next();
10209 break;
10210
10211 // TODO: not sure we should support this hack
10212 case SOLIDUS$2:
10213 this.scanner.next();
10214 if (this.scanner.isDelim(SOLIDUS$2)) {
10215 this.scanner.next();
10216 }
10217 break;
10218 }
10219 }
10220
10221 if (this.scanner.tokenType === HASH$1) {
10222 this.eat(HASH$1);
10223 } else {
10224 this.eat(IDENT$7);
10225 }
10226
10227 return this.scanner.substrToCursor(start);
10228 }
10229
10230 // ! ws* important
10231 function getImportant() {
10232 this.eat(DELIM$2);
10233 this.scanner.skipSC();
10234
10235 var important = this.consume(IDENT$7);
10236
10237 // store original value in case it differ from `important`
10238 // for better original source restoring and hacks like `!ie` support
10239 return important === 'important' ? true : important;
10240 }
10241
10242 var TYPE$k = tokenizer.TYPE;
10243 var rawMode$3 = Raw.mode;
10244
10245 var WHITESPACE$6 = TYPE$k.WhiteSpace;
10246 var COMMENT$6 = TYPE$k.Comment;
10247 var SEMICOLON$4 = TYPE$k.Semicolon;
10248
10249 function consumeRaw$2(startToken) {
10250 return this.Raw(startToken, rawMode$3.semicolonIncluded, true);
10251 }
10252
10253 var DeclarationList = {
10254 name: 'DeclarationList',
10255 structure: {
10256 children: [[
10257 'Declaration'
10258 ]]
10259 },
10260 parse: function() {
10261 var children = this.createList();
10262
10263 scan:
10264 while (!this.scanner.eof) {
10265 switch (this.scanner.tokenType) {
10266 case WHITESPACE$6:
10267 case COMMENT$6:
10268 case SEMICOLON$4:
10269 this.scanner.next();
10270 break;
10271
10272 default:
10273 children.push(this.parseWithFallback(this.Declaration, consumeRaw$2));
10274 }
10275 }
10276
10277 return {
10278 type: 'DeclarationList',
10279 loc: this.getLocationFromList(children),
10280 children: children
10281 };
10282 },
10283 generate: function(node) {
10284 this.children(node, function(prev) {
10285 if (prev.type === 'Declaration') {
10286 this.chunk(';');
10287 }
10288 });
10289 }
10290 };
10291
10292 var consumeNumber$3 = utils.consumeNumber;
10293 var TYPE$l = tokenizer.TYPE;
10294
10295 var DIMENSION$3 = TYPE$l.Dimension;
10296
10297 var Dimension = {
10298 name: 'Dimension',
10299 structure: {
10300 value: String,
10301 unit: String
10302 },
10303 parse: function() {
10304 var start = this.scanner.tokenStart;
10305 var numberEnd = consumeNumber$3(this.scanner.source, start);
10306
10307 this.eat(DIMENSION$3);
10308
10309 return {
10310 type: 'Dimension',
10311 loc: this.getLocation(start, this.scanner.tokenStart),
10312 value: this.scanner.source.substring(start, numberEnd),
10313 unit: this.scanner.source.substring(numberEnd, this.scanner.tokenStart)
10314 };
10315 },
10316 generate: function(node) {
10317 this.chunk(node.value);
10318 this.chunk(node.unit);
10319 }
10320 };
10321
10322 var TYPE$m = tokenizer.TYPE;
10323
10324 var RIGHTPARENTHESIS$2 = TYPE$m.RightParenthesis;
10325
10326 // <function-token> <sequence> )
10327 var _Function = {
10328 name: 'Function',
10329 structure: {
10330 name: String,
10331 children: [[]]
10332 },
10333 parse: function(readSequence, recognizer) {
10334 var start = this.scanner.tokenStart;
10335 var name = this.consumeFunctionName();
10336 var nameLowerCase = name.toLowerCase();
10337 var children;
10338
10339 children = recognizer.hasOwnProperty(nameLowerCase)
10340 ? recognizer[nameLowerCase].call(this, recognizer)
10341 : readSequence.call(this, recognizer);
10342
10343 if (!this.scanner.eof) {
10344 this.eat(RIGHTPARENTHESIS$2);
10345 }
10346
10347 return {
10348 type: 'Function',
10349 loc: this.getLocation(start, this.scanner.tokenStart),
10350 name: name,
10351 children: children
10352 };
10353 },
10354 generate: function(node) {
10355 this.chunk(node.name);
10356 this.chunk('(');
10357 this.children(node);
10358 this.chunk(')');
10359 },
10360 walkContext: 'function'
10361 };
10362
10363 var TYPE$n = tokenizer.TYPE;
10364
10365 var HASH$2 = TYPE$n.Hash;
10366
10367 // '#' ident
10368 var HexColor = {
10369 name: 'HexColor',
10370 structure: {
10371 value: String
10372 },
10373 parse: function() {
10374 var start = this.scanner.tokenStart;
10375
10376 this.eat(HASH$2);
10377
10378 return {
10379 type: 'HexColor',
10380 loc: this.getLocation(start, this.scanner.tokenStart),
10381 value: this.scanner.substrToCursor(start + 1)
10382 };
10383 },
10384 generate: function(node) {
10385 this.chunk('#');
10386 this.chunk(node.value);
10387 }
10388 };
10389
10390 var TYPE$o = tokenizer.TYPE;
10391
10392 var IDENT$8 = TYPE$o.Ident;
10393
10394 var Identifier = {
10395 name: 'Identifier',
10396 structure: {
10397 name: String
10398 },
10399 parse: function() {
10400 return {
10401 type: 'Identifier',
10402 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
10403 name: this.consume(IDENT$8)
10404 };
10405 },
10406 generate: function(node) {
10407 this.chunk(node.name);
10408 }
10409 };
10410
10411 var TYPE$p = tokenizer.TYPE;
10412
10413 var HASH$3 = TYPE$p.Hash;
10414
10415 // <hash-token>
10416 var IdSelector = {
10417 name: 'IdSelector',
10418 structure: {
10419 name: String
10420 },
10421 parse: function() {
10422 var start = this.scanner.tokenStart;
10423
10424 // TODO: check value is an ident
10425 this.eat(HASH$3);
10426
10427 return {
10428 type: 'IdSelector',
10429 loc: this.getLocation(start, this.scanner.tokenStart),
10430 name: this.scanner.substrToCursor(start + 1)
10431 };
10432 },
10433 generate: function(node) {
10434 this.chunk('#');
10435 this.chunk(node.name);
10436 }
10437 };
10438
10439 var TYPE$q = tokenizer.TYPE;
10440
10441 var IDENT$9 = TYPE$q.Ident;
10442 var NUMBER$4 = TYPE$q.Number;
10443 var DIMENSION$4 = TYPE$q.Dimension;
10444 var LEFTPARENTHESIS$2 = TYPE$q.LeftParenthesis;
10445 var RIGHTPARENTHESIS$3 = TYPE$q.RightParenthesis;
10446 var COLON$2 = TYPE$q.Colon;
10447 var DELIM$3 = TYPE$q.Delim;
10448
10449 var MediaFeature = {
10450 name: 'MediaFeature',
10451 structure: {
10452 name: String,
10453 value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
10454 },
10455 parse: function() {
10456 var start = this.scanner.tokenStart;
10457 var name;
10458 var value = null;
10459
10460 this.eat(LEFTPARENTHESIS$2);
10461 this.scanner.skipSC();
10462
10463 name = this.consume(IDENT$9);
10464 this.scanner.skipSC();
10465
10466 if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
10467 this.eat(COLON$2);
10468 this.scanner.skipSC();
10469
10470 switch (this.scanner.tokenType) {
10471 case NUMBER$4:
10472 if (this.lookupNonWSType(1) === DELIM$3) {
10473 value = this.Ratio();
10474 } else {
10475 value = this.Number();
10476 }
10477
10478 break;
10479
10480 case DIMENSION$4:
10481 value = this.Dimension();
10482 break;
10483
10484 case IDENT$9:
10485 value = this.Identifier();
10486
10487 break;
10488
10489 default:
10490 this.error('Number, dimension, ratio or identifier is expected');
10491 }
10492
10493 this.scanner.skipSC();
10494 }
10495
10496 this.eat(RIGHTPARENTHESIS$3);
10497
10498 return {
10499 type: 'MediaFeature',
10500 loc: this.getLocation(start, this.scanner.tokenStart),
10501 name: name,
10502 value: value
10503 };
10504 },
10505 generate: function(node) {
10506 this.chunk('(');
10507 this.chunk(node.name);
10508 if (node.value !== null) {
10509 this.chunk(':');
10510 this.node(node.value);
10511 }
10512 this.chunk(')');
10513 }
10514 };
10515
10516 var TYPE$r = tokenizer.TYPE;
10517
10518 var WHITESPACE$7 = TYPE$r.WhiteSpace;
10519 var COMMENT$7 = TYPE$r.Comment;
10520 var IDENT$a = TYPE$r.Ident;
10521 var LEFTPARENTHESIS$3 = TYPE$r.LeftParenthesis;
10522
10523 var MediaQuery = {
10524 name: 'MediaQuery',
10525 structure: {
10526 children: [[
10527 'Identifier',
10528 'MediaFeature',
10529 'WhiteSpace'
10530 ]]
10531 },
10532 parse: function() {
10533 this.scanner.skipSC();
10534
10535 var children = this.createList();
10536 var child = null;
10537 var space = null;
10538
10539 scan:
10540 while (!this.scanner.eof) {
10541 switch (this.scanner.tokenType) {
10542 case COMMENT$7:
10543 this.scanner.next();
10544 continue;
10545
10546 case WHITESPACE$7:
10547 space = this.WhiteSpace();
10548 continue;
10549
10550 case IDENT$a:
10551 child = this.Identifier();
10552 break;
10553
10554 case LEFTPARENTHESIS$3:
10555 child = this.MediaFeature();
10556 break;
10557
10558 default:
10559 break scan;
10560 }
10561
10562 if (space !== null) {
10563 children.push(space);
10564 space = null;
10565 }
10566
10567 children.push(child);
10568 }
10569
10570 if (child === null) {
10571 this.error('Identifier or parenthesis is expected');
10572 }
10573
10574 return {
10575 type: 'MediaQuery',
10576 loc: this.getLocationFromList(children),
10577 children: children
10578 };
10579 },
10580 generate: function(node) {
10581 this.children(node);
10582 }
10583 };
10584
10585 var COMMA$1 = tokenizer.TYPE.Comma;
10586
10587 var MediaQueryList = {
10588 name: 'MediaQueryList',
10589 structure: {
10590 children: [[
10591 'MediaQuery'
10592 ]]
10593 },
10594 parse: function(relative) {
10595 var children = this.createList();
10596
10597 this.scanner.skipSC();
10598
10599 while (!this.scanner.eof) {
10600 children.push(this.MediaQuery(relative));
10601
10602 if (this.scanner.tokenType !== COMMA$1) {
10603 break;
10604 }
10605
10606 this.scanner.next();
10607 }
10608
10609 return {
10610 type: 'MediaQueryList',
10611 loc: this.getLocationFromList(children),
10612 children: children
10613 };
10614 },
10615 generate: function(node) {
10616 this.children(node, function() {
10617 this.chunk(',');
10618 });
10619 }
10620 };
10621
10622 var Nth = {
10623 name: 'Nth',
10624 structure: {
10625 nth: ['AnPlusB', 'Identifier'],
10626 selector: ['SelectorList', null]
10627 },
10628 parse: function(allowOfClause) {
10629 this.scanner.skipSC();
10630
10631 var start = this.scanner.tokenStart;
10632 var end = start;
10633 var selector = null;
10634 var query;
10635
10636 if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
10637 query = this.Identifier();
10638 } else {
10639 query = this.AnPlusB();
10640 }
10641
10642 this.scanner.skipSC();
10643
10644 if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
10645 this.scanner.next();
10646
10647 selector = this.SelectorList();
10648
10649 if (this.needPositions) {
10650 end = this.getLastListNode(selector.children).loc.end.offset;
10651 }
10652 } else {
10653 if (this.needPositions) {
10654 end = query.loc.end.offset;
10655 }
10656 }
10657
10658 return {
10659 type: 'Nth',
10660 loc: this.getLocation(start, end),
10661 nth: query,
10662 selector: selector
10663 };
10664 },
10665 generate: function(node) {
10666 this.node(node.nth);
10667 if (node.selector !== null) {
10668 this.chunk(' of ');
10669 this.node(node.selector);
10670 }
10671 }
10672 };
10673
10674 var NUMBER$5 = tokenizer.TYPE.Number;
10675
10676 var _Number = {
10677 name: 'Number',
10678 structure: {
10679 value: String
10680 },
10681 parse: function() {
10682 return {
10683 type: 'Number',
10684 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
10685 value: this.consume(NUMBER$5)
10686 };
10687 },
10688 generate: function(node) {
10689 this.chunk(node.value);
10690 }
10691 };
10692
10693 // '/' | '*' | ',' | ':' | '+' | '-'
10694 var Operator = {
10695 name: 'Operator',
10696 structure: {
10697 value: String
10698 },
10699 parse: function() {
10700 var start = this.scanner.tokenStart;
10701
10702 this.scanner.next();
10703
10704 return {
10705 type: 'Operator',
10706 loc: this.getLocation(start, this.scanner.tokenStart),
10707 value: this.scanner.substrToCursor(start)
10708 };
10709 },
10710 generate: function(node) {
10711 this.chunk(node.value);
10712 }
10713 };
10714
10715 var TYPE$s = tokenizer.TYPE;
10716
10717 var LEFTPARENTHESIS$4 = TYPE$s.LeftParenthesis;
10718 var RIGHTPARENTHESIS$4 = TYPE$s.RightParenthesis;
10719
10720 var Parentheses = {
10721 name: 'Parentheses',
10722 structure: {
10723 children: [[]]
10724 },
10725 parse: function(readSequence, recognizer) {
10726 var start = this.scanner.tokenStart;
10727 var children = null;
10728
10729 this.eat(LEFTPARENTHESIS$4);
10730
10731 children = readSequence.call(this, recognizer);
10732
10733 if (!this.scanner.eof) {
10734 this.eat(RIGHTPARENTHESIS$4);
10735 }
10736
10737 return {
10738 type: 'Parentheses',
10739 loc: this.getLocation(start, this.scanner.tokenStart),
10740 children: children
10741 };
10742 },
10743 generate: function(node) {
10744 this.chunk('(');
10745 this.children(node);
10746 this.chunk(')');
10747 }
10748 };
10749
10750 var consumeNumber$4 = utils.consumeNumber;
10751 var TYPE$t = tokenizer.TYPE;
10752
10753 var PERCENTAGE$1 = TYPE$t.Percentage;
10754
10755 var Percentage = {
10756 name: 'Percentage',
10757 structure: {
10758 value: String
10759 },
10760 parse: function() {
10761 var start = this.scanner.tokenStart;
10762 var numberEnd = consumeNumber$4(this.scanner.source, start);
10763
10764 this.eat(PERCENTAGE$1);
10765
10766 return {
10767 type: 'Percentage',
10768 loc: this.getLocation(start, this.scanner.tokenStart),
10769 value: this.scanner.source.substring(start, numberEnd)
10770 };
10771 },
10772 generate: function(node) {
10773 this.chunk(node.value);
10774 this.chunk('%');
10775 }
10776 };
10777
10778 var TYPE$u = tokenizer.TYPE;
10779
10780 var IDENT$b = TYPE$u.Ident;
10781 var FUNCTION$1 = TYPE$u.Function;
10782 var COLON$3 = TYPE$u.Colon;
10783 var RIGHTPARENTHESIS$5 = TYPE$u.RightParenthesis;
10784
10785 // : [ <ident> | <function-token> <any-value>? ) ]
10786 var PseudoClassSelector = {
10787 name: 'PseudoClassSelector',
10788 structure: {
10789 name: String,
10790 children: [['Raw'], null]
10791 },
10792 parse: function() {
10793 var start = this.scanner.tokenStart;
10794 var children = null;
10795 var name;
10796 var nameLowerCase;
10797
10798 this.eat(COLON$3);
10799
10800 if (this.scanner.tokenType === FUNCTION$1) {
10801 name = this.consumeFunctionName();
10802 nameLowerCase = name.toLowerCase();
10803
10804 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
10805 this.scanner.skipSC();
10806 children = this.pseudo[nameLowerCase].call(this);
10807 this.scanner.skipSC();
10808 } else {
10809 children = this.createList();
10810 children.push(
10811 this.Raw(this.scanner.tokenIndex, null, false)
10812 );
10813 }
10814
10815 this.eat(RIGHTPARENTHESIS$5);
10816 } else {
10817 name = this.consume(IDENT$b);
10818 }
10819
10820 return {
10821 type: 'PseudoClassSelector',
10822 loc: this.getLocation(start, this.scanner.tokenStart),
10823 name: name,
10824 children: children
10825 };
10826 },
10827 generate: function(node) {
10828 this.chunk(':');
10829 this.chunk(node.name);
10830
10831 if (node.children !== null) {
10832 this.chunk('(');
10833 this.children(node);
10834 this.chunk(')');
10835 }
10836 },
10837 walkContext: 'function'
10838 };
10839
10840 var TYPE$v = tokenizer.TYPE;
10841
10842 var IDENT$c = TYPE$v.Ident;
10843 var FUNCTION$2 = TYPE$v.Function;
10844 var COLON$4 = TYPE$v.Colon;
10845 var RIGHTPARENTHESIS$6 = TYPE$v.RightParenthesis;
10846
10847 // :: [ <ident> | <function-token> <any-value>? ) ]
10848 var PseudoElementSelector = {
10849 name: 'PseudoElementSelector',
10850 structure: {
10851 name: String,
10852 children: [['Raw'], null]
10853 },
10854 parse: function() {
10855 var start = this.scanner.tokenStart;
10856 var children = null;
10857 var name;
10858 var nameLowerCase;
10859
10860 this.eat(COLON$4);
10861 this.eat(COLON$4);
10862
10863 if (this.scanner.tokenType === FUNCTION$2) {
10864 name = this.consumeFunctionName();
10865 nameLowerCase = name.toLowerCase();
10866
10867 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
10868 this.scanner.skipSC();
10869 children = this.pseudo[nameLowerCase].call(this);
10870 this.scanner.skipSC();
10871 } else {
10872 children = this.createList();
10873 children.push(
10874 this.Raw(this.scanner.tokenIndex, null, false)
10875 );
10876 }
10877
10878 this.eat(RIGHTPARENTHESIS$6);
10879 } else {
10880 name = this.consume(IDENT$c);
10881 }
10882
10883 return {
10884 type: 'PseudoElementSelector',
10885 loc: this.getLocation(start, this.scanner.tokenStart),
10886 name: name,
10887 children: children
10888 };
10889 },
10890 generate: function(node) {
10891 this.chunk('::');
10892 this.chunk(node.name);
10893
10894 if (node.children !== null) {
10895 this.chunk('(');
10896 this.children(node);
10897 this.chunk(')');
10898 }
10899 },
10900 walkContext: 'function'
10901 };
10902
10903 var isDigit$5 = tokenizer.isDigit;
10904 var TYPE$w = tokenizer.TYPE;
10905
10906 var NUMBER$6 = TYPE$w.Number;
10907 var DELIM$4 = TYPE$w.Delim;
10908 var SOLIDUS$3 = 0x002F; // U+002F SOLIDUS (/)
10909 var FULLSTOP$1 = 0x002E; // U+002E FULL STOP (.)
10910
10911 // Terms of <ratio> should be a positive numbers (not zero or negative)
10912 // (see https://drafts.csswg.org/mediaqueries-3/#values)
10913 // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
10914 // and this is using by various sites. Therefore we relax checking on parse
10915 // to test a term is unsigned number without an exponent part.
10916 // Additional checking may be applied on lexer validation.
10917 function consumeNumber$5() {
10918 this.scanner.skipWS();
10919
10920 var value = this.consume(NUMBER$6);
10921
10922 for (var i = 0; i < value.length; i++) {
10923 var code = value.charCodeAt(i);
10924 if (!isDigit$5(code) && code !== FULLSTOP$1) {
10925 this.error('Unsigned number is expected', this.scanner.tokenStart - value.length + i);
10926 }
10927 }
10928
10929 if (Number(value) === 0) {
10930 this.error('Zero number is not allowed', this.scanner.tokenStart - value.length);
10931 }
10932
10933 return value;
10934 }
10935
10936 // <positive-integer> S* '/' S* <positive-integer>
10937 var Ratio = {
10938 name: 'Ratio',
10939 structure: {
10940 left: String,
10941 right: String
10942 },
10943 parse: function() {
10944 var start = this.scanner.tokenStart;
10945 var left = consumeNumber$5.call(this);
10946 var right;
10947
10948 this.scanner.skipWS();
10949
10950 if (!this.scanner.isDelim(SOLIDUS$3)) {
10951 this.error('Solidus is expected');
10952 }
10953 this.eat(DELIM$4);
10954 right = consumeNumber$5.call(this);
10955
10956 return {
10957 type: 'Ratio',
10958 loc: this.getLocation(start, this.scanner.tokenStart),
10959 left: left,
10960 right: right
10961 };
10962 },
10963 generate: function(node) {
10964 this.chunk(node.left);
10965 this.chunk('/');
10966 this.chunk(node.right);
10967 }
10968 };
10969
10970 var TYPE$x = tokenizer.TYPE;
10971 var rawMode$4 = Raw.mode;
10972
10973 var LEFTCURLYBRACKET$4 = TYPE$x.LeftCurlyBracket;
10974
10975 function consumeRaw$3(startToken) {
10976 return this.Raw(startToken, rawMode$4.leftCurlyBracket, true);
10977 }
10978
10979 function consumePrelude() {
10980 var prelude = this.SelectorList();
10981
10982 if (prelude.type !== 'Raw' &&
10983 this.scanner.eof === false &&
10984 this.scanner.tokenType !== LEFTCURLYBRACKET$4) {
10985 this.error();
10986 }
10987
10988 return prelude;
10989 }
10990
10991 var Rule = {
10992 name: 'Rule',
10993 structure: {
10994 prelude: ['SelectorList', 'Raw'],
10995 block: ['Block']
10996 },
10997 parse: function() {
10998 var startToken = this.scanner.tokenIndex;
10999 var startOffset = this.scanner.tokenStart;
11000 var prelude;
11001 var block;
11002
11003 if (this.parseRulePrelude) {
11004 prelude = this.parseWithFallback(consumePrelude, consumeRaw$3);
11005 } else {
11006 prelude = consumeRaw$3.call(this, startToken);
11007 }
11008
11009 block = this.Block(true);
11010
11011 return {
11012 type: 'Rule',
11013 loc: this.getLocation(startOffset, this.scanner.tokenStart),
11014 prelude: prelude,
11015 block: block
11016 };
11017 },
11018 generate: function(node) {
11019 this.node(node.prelude);
11020 this.node(node.block);
11021 },
11022 walkContext: 'rule'
11023 };
11024
11025 var Selector = {
11026 name: 'Selector',
11027 structure: {
11028 children: [[
11029 'TypeSelector',
11030 'IdSelector',
11031 'ClassSelector',
11032 'AttributeSelector',
11033 'PseudoClassSelector',
11034 'PseudoElementSelector',
11035 'Combinator',
11036 'WhiteSpace'
11037 ]]
11038 },
11039 parse: function() {
11040 var children = this.readSequence(this.scope.Selector);
11041
11042 // nothing were consumed
11043 if (this.getFirstListNode(children) === null) {
11044 this.error('Selector is expected');
11045 }
11046
11047 return {
11048 type: 'Selector',
11049 loc: this.getLocationFromList(children),
11050 children: children
11051 };
11052 },
11053 generate: function(node) {
11054 this.children(node);
11055 }
11056 };
11057
11058 var TYPE$y = tokenizer.TYPE;
11059
11060 var COMMA$2 = TYPE$y.Comma;
11061
11062 var SelectorList = {
11063 name: 'SelectorList',
11064 structure: {
11065 children: [[
11066 'Selector',
11067 'Raw'
11068 ]]
11069 },
11070 parse: function() {
11071 var children = this.createList();
11072
11073 while (!this.scanner.eof) {
11074 children.push(this.Selector());
11075
11076 if (this.scanner.tokenType === COMMA$2) {
11077 this.scanner.next();
11078 continue;
11079 }
11080
11081 break;
11082 }
11083
11084 return {
11085 type: 'SelectorList',
11086 loc: this.getLocationFromList(children),
11087 children: children
11088 };
11089 },
11090 generate: function(node) {
11091 this.children(node, function() {
11092 this.chunk(',');
11093 });
11094 },
11095 walkContext: 'selector'
11096 };
11097
11098 var STRING$1 = tokenizer.TYPE.String;
11099
11100 var _String = {
11101 name: 'String',
11102 structure: {
11103 value: String
11104 },
11105 parse: function() {
11106 return {
11107 type: 'String',
11108 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
11109 value: this.consume(STRING$1)
11110 };
11111 },
11112 generate: function(node) {
11113 this.chunk(node.value);
11114 }
11115 };
11116
11117 var TYPE$z = tokenizer.TYPE;
11118
11119 var WHITESPACE$8 = TYPE$z.WhiteSpace;
11120 var COMMENT$8 = TYPE$z.Comment;
11121 var ATKEYWORD$2 = TYPE$z.AtKeyword;
11122 var CDO$1 = TYPE$z.CDO;
11123 var CDC$1 = TYPE$z.CDC;
11124 var EXCLAMATIONMARK$3 = 0x0021; // U+0021 EXCLAMATION MARK (!)
11125
11126 function consumeRaw$4(startToken) {
11127 return this.Raw(startToken, null, false);
11128 }
11129
11130 var StyleSheet = {
11131 name: 'StyleSheet',
11132 structure: {
11133 children: [[
11134 'Comment',
11135 'CDO',
11136 'CDC',
11137 'Atrule',
11138 'Rule',
11139 'Raw'
11140 ]]
11141 },
11142 parse: function() {
11143 var start = this.scanner.tokenStart;
11144 var children = this.createList();
11145 var child;
11146
11147 scan:
11148 while (!this.scanner.eof) {
11149 switch (this.scanner.tokenType) {
11150 case WHITESPACE$8:
11151 this.scanner.next();
11152 continue;
11153
11154 case COMMENT$8:
11155 // ignore comments except exclamation comments (i.e. /*! .. */) on top level
11156 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
11157 this.scanner.next();
11158 continue;
11159 }
11160
11161 child = this.Comment();
11162 break;
11163
11164 case CDO$1: // <!--
11165 child = this.CDO();
11166 break;
11167
11168 case CDC$1: // -->
11169 child = this.CDC();
11170 break;
11171
11172 // CSS Syntax Module Level 3
11173 // §2.2 Error handling
11174 // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
11175 case ATKEYWORD$2:
11176 child = this.parseWithFallback(this.Atrule, consumeRaw$4);
11177 break;
11178
11179 // Anything else starts a qualified rule ...
11180 default:
11181 child = this.parseWithFallback(this.Rule, consumeRaw$4);
11182 }
11183
11184 children.push(child);
11185 }
11186
11187 return {
11188 type: 'StyleSheet',
11189 loc: this.getLocation(start, this.scanner.tokenStart),
11190 children: children
11191 };
11192 },
11193 generate: function(node) {
11194 this.children(node);
11195 },
11196 walkContext: 'stylesheet'
11197 };
11198
11199 var TYPE$A = tokenizer.TYPE;
11200
11201 var IDENT$d = TYPE$A.Ident;
11202 var ASTERISK$4 = 0x002A; // U+002A ASTERISK (*)
11203 var VERTICALLINE$2 = 0x007C; // U+007C VERTICAL LINE (|)
11204
11205 function eatIdentifierOrAsterisk() {
11206 if (this.scanner.tokenType !== IDENT$d &&
11207 this.scanner.isDelim(ASTERISK$4) === false) {
11208 this.error('Identifier or asterisk is expected');
11209 }
11210
11211 this.scanner.next();
11212 }
11213
11214 // ident
11215 // ident|ident
11216 // ident|*
11217 // *
11218 // *|ident
11219 // *|*
11220 // |ident
11221 // |*
11222 var TypeSelector = {
11223 name: 'TypeSelector',
11224 structure: {
11225 name: String
11226 },
11227 parse: function() {
11228 var start = this.scanner.tokenStart;
11229
11230 if (this.scanner.isDelim(VERTICALLINE$2)) {
11231 this.scanner.next();
11232 eatIdentifierOrAsterisk.call(this);
11233 } else {
11234 eatIdentifierOrAsterisk.call(this);
11235
11236 if (this.scanner.isDelim(VERTICALLINE$2)) {
11237 this.scanner.next();
11238 eatIdentifierOrAsterisk.call(this);
11239 }
11240 }
11241
11242 return {
11243 type: 'TypeSelector',
11244 loc: this.getLocation(start, this.scanner.tokenStart),
11245 name: this.scanner.substrToCursor(start)
11246 };
11247 },
11248 generate: function(node) {
11249 this.chunk(node.name);
11250 }
11251 };
11252
11253 var isHexDigit$4 = tokenizer.isHexDigit;
11254 var cmpChar$4 = tokenizer.cmpChar;
11255 var TYPE$B = tokenizer.TYPE;
11256 var NAME$3 = tokenizer.NAME;
11257
11258 var IDENT$e = TYPE$B.Ident;
11259 var NUMBER$7 = TYPE$B.Number;
11260 var DIMENSION$5 = TYPE$B.Dimension;
11261 var PLUSSIGN$6 = 0x002B; // U+002B PLUS SIGN (+)
11262 var HYPHENMINUS$4 = 0x002D; // U+002D HYPHEN-MINUS (-)
11263 var QUESTIONMARK$2 = 0x003F; // U+003F QUESTION MARK (?)
11264 var U$1 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
11265
11266 function eatHexSequence(offset, allowDash) {
11267 for (var pos = this.scanner.tokenStart + offset, len = 0; pos < this.scanner.tokenEnd; pos++) {
11268 var code = this.scanner.source.charCodeAt(pos);
11269
11270 if (code === HYPHENMINUS$4 && allowDash && len !== 0) {
11271 if (eatHexSequence.call(this, offset + len + 1, false) === 0) {
11272 this.error();
11273 }
11274
11275 return -1;
11276 }
11277
11278 if (!isHexDigit$4(code)) {
11279 this.error(
11280 allowDash && len !== 0
11281 ? 'HyphenMinus' + (len < 6 ? ' or hex digit' : '') + ' is expected'
11282 : (len < 6 ? 'Hex digit is expected' : 'Unexpected input'),
11283 pos
11284 );
11285 }
11286
11287 if (++len > 6) {
11288 this.error('Too many hex digits', pos);
11289 } }
11290
11291 this.scanner.next();
11292 return len;
11293 }
11294
11295 function eatQuestionMarkSequence(max) {
11296 var count = 0;
11297
11298 while (this.scanner.isDelim(QUESTIONMARK$2)) {
11299 if (++count > max) {
11300 this.error('Too many question marks');
11301 }
11302
11303 this.scanner.next();
11304 }
11305 }
11306
11307 function startsWith$1(code) {
11308 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== code) {
11309 this.error(NAME$3[code] + ' is expected');
11310 }
11311 }
11312
11313 // https://drafts.csswg.org/css-syntax/#urange
11314 // Informally, the <urange> production has three forms:
11315 // U+0001
11316 // Defines a range consisting of a single code point, in this case the code point "1".
11317 // U+0001-00ff
11318 // Defines a range of codepoints between the first and the second value, in this case
11319 // the range between "1" and "ff" (255 in decimal) inclusive.
11320 // U+00??
11321 // Defines a range of codepoints where the "?" characters range over all hex digits,
11322 // in this case defining the same as the value U+0000-00ff.
11323 // In each form, a maximum of 6 digits is allowed for each hexadecimal number (if you treat "?" as a hexadecimal digit).
11324 //
11325 // <urange> =
11326 // u '+' <ident-token> '?'* |
11327 // u <dimension-token> '?'* |
11328 // u <number-token> '?'* |
11329 // u <number-token> <dimension-token> |
11330 // u <number-token> <number-token> |
11331 // u '+' '?'+
11332 function scanUnicodeRange() {
11333 var hexLength = 0;
11334
11335 // u '+' <ident-token> '?'*
11336 // u '+' '?'+
11337 if (this.scanner.isDelim(PLUSSIGN$6)) {
11338 this.scanner.next();
11339
11340 if (this.scanner.tokenType === IDENT$e) {
11341 hexLength = eatHexSequence.call(this, 0, true);
11342 if (hexLength > 0) {
11343 eatQuestionMarkSequence.call(this, 6 - hexLength);
11344 }
11345 return;
11346 }
11347
11348 if (this.scanner.isDelim(QUESTIONMARK$2)) {
11349 this.scanner.next();
11350 eatQuestionMarkSequence.call(this, 5);
11351 return;
11352 }
11353
11354 this.error('Hex digit or question mark is expected');
11355 return;
11356 }
11357
11358 // u <number-token> '?'*
11359 // u <number-token> <dimension-token>
11360 // u <number-token> <number-token>
11361 if (this.scanner.tokenType === NUMBER$7) {
11362 startsWith$1.call(this, PLUSSIGN$6);
11363 hexLength = eatHexSequence.call(this, 1, true);
11364
11365 if (this.scanner.isDelim(QUESTIONMARK$2)) {
11366 eatQuestionMarkSequence.call(this, 6 - hexLength);
11367 return;
11368 }
11369
11370 if (this.scanner.tokenType === DIMENSION$5 ||
11371 this.scanner.tokenType === NUMBER$7) {
11372 startsWith$1.call(this, HYPHENMINUS$4);
11373 eatHexSequence.call(this, 1, false);
11374 return;
11375 }
11376
11377 return;
11378 }
11379
11380 // u <dimension-token> '?'*
11381 if (this.scanner.tokenType === DIMENSION$5) {
11382 startsWith$1.call(this, PLUSSIGN$6);
11383 hexLength = eatHexSequence.call(this, 1, true);
11384
11385 if (hexLength > 0) {
11386 eatQuestionMarkSequence.call(this, 6 - hexLength);
11387 }
11388
11389 return;
11390 }
11391
11392 this.error();
11393 }
11394
11395 var UnicodeRange = {
11396 name: 'UnicodeRange',
11397 structure: {
11398 value: String
11399 },
11400 parse: function() {
11401 var start = this.scanner.tokenStart;
11402
11403 // U or u
11404 if (!cmpChar$4(this.scanner.source, start, U$1)) {
11405 this.error('U is expected');
11406 }
11407
11408 if (!cmpChar$4(this.scanner.source, start + 1, PLUSSIGN$6)) {
11409 this.error('Plus sign is expected');
11410 }
11411
11412 this.scanner.next();
11413 scanUnicodeRange.call(this);
11414
11415 return {
11416 type: 'UnicodeRange',
11417 loc: this.getLocation(start, this.scanner.tokenStart),
11418 value: this.scanner.substrToCursor(start)
11419 };
11420 },
11421 generate: function(node) {
11422 this.chunk(node.value);
11423 }
11424 };
11425
11426 var isWhiteSpace$2 = tokenizer.isWhiteSpace;
11427 var cmpStr$4 = tokenizer.cmpStr;
11428 var TYPE$C = tokenizer.TYPE;
11429
11430 var FUNCTION$3 = TYPE$C.Function;
11431 var URL$1 = TYPE$C.Url;
11432 var RIGHTPARENTHESIS$7 = TYPE$C.RightParenthesis;
11433
11434 // <url-token> | <function-token> <string> )
11435 var Url = {
11436 name: 'Url',
11437 structure: {
11438 value: ['String', 'Raw']
11439 },
11440 parse: function() {
11441 var start = this.scanner.tokenStart;
11442 var value;
11443
11444 switch (this.scanner.tokenType) {
11445 case URL$1:
11446 var rawStart = start + 4;
11447 var rawEnd = this.scanner.tokenEnd - 1;
11448
11449 while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawStart))) {
11450 rawStart++;
11451 }
11452
11453 while (rawStart < rawEnd && isWhiteSpace$2(this.scanner.source.charCodeAt(rawEnd - 1))) {
11454 rawEnd--;
11455 }
11456
11457 value = {
11458 type: 'Raw',
11459 loc: this.getLocation(rawStart, rawEnd),
11460 value: this.scanner.source.substring(rawStart, rawEnd)
11461 };
11462
11463 this.eat(URL$1);
11464 break;
11465
11466 case FUNCTION$3:
11467 if (!cmpStr$4(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')) {
11468 this.error('Function name must be `url`');
11469 }
11470
11471 this.eat(FUNCTION$3);
11472 this.scanner.skipSC();
11473 value = this.String();
11474 this.scanner.skipSC();
11475 this.eat(RIGHTPARENTHESIS$7);
11476 break;
11477
11478 default:
11479 this.error('Url or Function is expected');
11480 }
11481
11482 return {
11483 type: 'Url',
11484 loc: this.getLocation(start, this.scanner.tokenStart),
11485 value: value
11486 };
11487 },
11488 generate: function(node) {
11489 this.chunk('url');
11490 this.chunk('(');
11491 this.node(node.value);
11492 this.chunk(')');
11493 }
11494 };
11495
11496 var Value = {
11497 name: 'Value',
11498 structure: {
11499 children: [[]]
11500 },
11501 parse: function() {
11502 var start = this.scanner.tokenStart;
11503 var children = this.readSequence(this.scope.Value);
11504
11505 return {
11506 type: 'Value',
11507 loc: this.getLocation(start, this.scanner.tokenStart),
11508 children: children
11509 };
11510 },
11511 generate: function(node) {
11512 this.children(node);
11513 }
11514 };
11515
11516 var WHITESPACE$9 = tokenizer.TYPE.WhiteSpace;
11517 var SPACE$2 = Object.freeze({
11518 type: 'WhiteSpace',
11519 loc: null,
11520 value: ' '
11521 });
11522
11523 var WhiteSpace$1 = {
11524 name: 'WhiteSpace',
11525 structure: {
11526 value: String
11527 },
11528 parse: function() {
11529 this.eat(WHITESPACE$9);
11530 return SPACE$2;
11531
11532 // return {
11533 // type: 'WhiteSpace',
11534 // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
11535 // value: this.consume(WHITESPACE)
11536 // };
11537 },
11538 generate: function(node) {
11539 this.chunk(node.value);
11540 }
11541 };
11542
11543 var node = {
11544 AnPlusB: AnPlusB,
11545 Atrule: Atrule,
11546 AtrulePrelude: AtrulePrelude,
11547 AttributeSelector: AttributeSelector,
11548 Block: Block,
11549 Brackets: Brackets,
11550 CDC: CDC_1,
11551 CDO: CDO_1,
11552 ClassSelector: ClassSelector,
11553 Combinator: Combinator,
11554 Comment: Comment,
11555 Declaration: Declaration,
11556 DeclarationList: DeclarationList,
11557 Dimension: Dimension,
11558 Function: _Function,
11559 HexColor: HexColor,
11560 Identifier: Identifier,
11561 IdSelector: IdSelector,
11562 MediaFeature: MediaFeature,
11563 MediaQuery: MediaQuery,
11564 MediaQueryList: MediaQueryList,
11565 Nth: Nth,
11566 Number: _Number,
11567 Operator: Operator,
11568 Parentheses: Parentheses,
11569 Percentage: Percentage,
11570 PseudoClassSelector: PseudoClassSelector,
11571 PseudoElementSelector: PseudoElementSelector,
11572 Ratio: Ratio,
11573 Raw: Raw,
11574 Rule: Rule,
11575 Selector: Selector,
11576 SelectorList: SelectorList,
11577 String: _String,
11578 StyleSheet: StyleSheet,
11579 TypeSelector: TypeSelector,
11580 UnicodeRange: UnicodeRange,
11581 Url: Url,
11582 Value: Value,
11583 WhiteSpace: WhiteSpace$1
11584 };
11585
11586 var data = getCjsExportFromNamespace(defaultSyntax$1);
11587
11588 var lexer = {
11589 generic: true,
11590 types: data.types,
11591 properties: data.properties,
11592 node: node
11593 };
11594
11595 var cmpChar$5 = tokenizer.cmpChar;
11596 var cmpStr$5 = tokenizer.cmpStr;
11597 var TYPE$D = tokenizer.TYPE;
11598
11599 var IDENT$f = TYPE$D.Ident;
11600 var STRING$2 = TYPE$D.String;
11601 var NUMBER$8 = TYPE$D.Number;
11602 var FUNCTION$4 = TYPE$D.Function;
11603 var URL$2 = TYPE$D.Url;
11604 var HASH$4 = TYPE$D.Hash;
11605 var DIMENSION$6 = TYPE$D.Dimension;
11606 var PERCENTAGE$2 = TYPE$D.Percentage;
11607 var LEFTPARENTHESIS$5 = TYPE$D.LeftParenthesis;
11608 var LEFTSQUAREBRACKET$3 = TYPE$D.LeftSquareBracket;
11609 var COMMA$3 = TYPE$D.Comma;
11610 var DELIM$5 = TYPE$D.Delim;
11611 var NUMBERSIGN$3 = 0x0023; // U+0023 NUMBER SIGN (#)
11612 var ASTERISK$5 = 0x002A; // U+002A ASTERISK (*)
11613 var PLUSSIGN$7 = 0x002B; // U+002B PLUS SIGN (+)
11614 var HYPHENMINUS$5 = 0x002D; // U+002D HYPHEN-MINUS (-)
11615 var SOLIDUS$4 = 0x002F; // U+002F SOLIDUS (/)
11616 var U$2 = 0x0075; // U+0075 LATIN SMALL LETTER U (u)
11617
11618 var _default = function defaultRecognizer(context) {
11619 switch (this.scanner.tokenType) {
11620 case HASH$4:
11621 return this.HexColor();
11622
11623 case COMMA$3:
11624 context.space = null;
11625 context.ignoreWSAfter = true;
11626 return this.Operator();
11627
11628 case LEFTPARENTHESIS$5:
11629 return this.Parentheses(this.readSequence, context.recognizer);
11630
11631 case LEFTSQUAREBRACKET$3:
11632 return this.Brackets(this.readSequence, context.recognizer);
11633
11634 case STRING$2:
11635 return this.String();
11636
11637 case DIMENSION$6:
11638 return this.Dimension();
11639
11640 case PERCENTAGE$2:
11641 return this.Percentage();
11642
11643 case NUMBER$8:
11644 return this.Number();
11645
11646 case FUNCTION$4:
11647 return cmpStr$5(this.scanner.source, this.scanner.tokenStart, this.scanner.tokenEnd, 'url(')
11648 ? this.Url()
11649 : this.Function(this.readSequence, context.recognizer);
11650
11651 case URL$2:
11652 return this.Url();
11653
11654 case IDENT$f:
11655 // check for unicode range, it should start with u+ or U+
11656 if (cmpChar$5(this.scanner.source, this.scanner.tokenStart, U$2) &&
11657 cmpChar$5(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$7)) {
11658 return this.UnicodeRange();
11659 } else {
11660 return this.Identifier();
11661 }
11662
11663 case DELIM$5:
11664 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
11665
11666 if (code === SOLIDUS$4 ||
11667 code === ASTERISK$5 ||
11668 code === PLUSSIGN$7 ||
11669 code === HYPHENMINUS$5) {
11670 return this.Operator(); // TODO: replace with Delim
11671 }
11672
11673 // TODO: produce a node with Delim node type
11674
11675 if (code === NUMBERSIGN$3) {
11676 this.error('Hex or identifier is expected', this.scanner.tokenStart + 1);
11677 }
11678
11679 break;
11680 }
11681 };
11682
11683 var atrulePrelude = {
11684 getNode: _default
11685 };
11686
11687 var TYPE$E = tokenizer.TYPE;
11688
11689 var DELIM$6 = TYPE$E.Delim;
11690 var IDENT$g = TYPE$E.Ident;
11691 var DIMENSION$7 = TYPE$E.Dimension;
11692 var PERCENTAGE$3 = TYPE$E.Percentage;
11693 var NUMBER$9 = TYPE$E.Number;
11694 var HASH$5 = TYPE$E.Hash;
11695 var COLON$5 = TYPE$E.Colon;
11696 var LEFTSQUAREBRACKET$4 = TYPE$E.LeftSquareBracket;
11697 var NUMBERSIGN$4 = 0x0023; // U+0023 NUMBER SIGN (#)
11698 var ASTERISK$6 = 0x002A; // U+002A ASTERISK (*)
11699 var PLUSSIGN$8 = 0x002B; // U+002B PLUS SIGN (+)
11700 var SOLIDUS$5 = 0x002F; // U+002F SOLIDUS (/)
11701 var FULLSTOP$2 = 0x002E; // U+002E FULL STOP (.)
11702 var GREATERTHANSIGN$2 = 0x003E; // U+003E GREATER-THAN SIGN (>)
11703 var VERTICALLINE$3 = 0x007C; // U+007C VERTICAL LINE (|)
11704 var TILDE$2 = 0x007E; // U+007E TILDE (~)
11705
11706 function getNode(context) {
11707 switch (this.scanner.tokenType) {
11708 case LEFTSQUAREBRACKET$4:
11709 return this.AttributeSelector();
11710
11711 case HASH$5:
11712 return this.IdSelector();
11713
11714 case COLON$5:
11715 if (this.scanner.lookupType(1) === COLON$5) {
11716 return this.PseudoElementSelector();
11717 } else {
11718 return this.PseudoClassSelector();
11719 }
11720
11721 case IDENT$g:
11722 return this.TypeSelector();
11723
11724 case NUMBER$9:
11725 case PERCENTAGE$3:
11726 return this.Percentage();
11727
11728 case DIMENSION$7:
11729 // throws when .123ident
11730 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) === FULLSTOP$2) {
11731 this.error('Identifier is expected', this.scanner.tokenStart + 1);
11732 }
11733 break;
11734
11735 case DELIM$6:
11736 var code = this.scanner.source.charCodeAt(this.scanner.tokenStart);
11737
11738 switch (code) {
11739 case PLUSSIGN$8:
11740 case GREATERTHANSIGN$2:
11741 case TILDE$2:
11742 context.space = null;
11743 context.ignoreWSAfter = true;
11744 return this.Combinator();
11745
11746 case SOLIDUS$5: // /deep/
11747 return this.Combinator();
11748
11749 case FULLSTOP$2:
11750 return this.ClassSelector();
11751
11752 case ASTERISK$6:
11753 case VERTICALLINE$3:
11754 return this.TypeSelector();
11755
11756 case NUMBERSIGN$4:
11757 return this.IdSelector();
11758 }
11759
11760 break;
11761 }
11762 }
11763 var selector = {
11764 getNode: getNode
11765 };
11766
11767 // https://drafts.csswg.org/css-images-4/#element-notation
11768 // https://developer.mozilla.org/en-US/docs/Web/CSS/element
11769 var element = function() {
11770 this.scanner.skipSC();
11771
11772 var children = this.createSingleNodeList(
11773 this.IdSelector()
11774 );
11775
11776 this.scanner.skipSC();
11777
11778 return children;
11779 };
11780
11781 // legacy IE function
11782 // expression( <any-value> )
11783 var expression = function() {
11784 return this.createSingleNodeList(
11785 this.Raw(this.scanner.tokenIndex, null, false)
11786 );
11787 };
11788
11789 var TYPE$F = tokenizer.TYPE;
11790 var rawMode$5 = Raw.mode;
11791
11792 var COMMA$4 = TYPE$F.Comma;
11793
11794 // var( <ident> , <value>? )
11795 var _var = function() {
11796 var children = this.createList();
11797
11798 this.scanner.skipSC();
11799
11800 // NOTE: Don't check more than a first argument is an ident, rest checks are for lexer
11801 children.push(this.Identifier());
11802
11803 this.scanner.skipSC();
11804
11805 if (this.scanner.tokenType === COMMA$4) {
11806 children.push(this.Operator());
11807 children.push(this.parseCustomProperty
11808 ? this.Value(null)
11809 : this.Raw(this.scanner.tokenIndex, rawMode$5.exclamationMarkOrSemicolon, false)
11810 );
11811 }
11812
11813 return children;
11814 };
11815
11816 var value = {
11817 getNode: _default,
11818 '-moz-element': element,
11819 'element': element,
11820 'expression': expression,
11821 'var': _var
11822 };
11823
11824 var scope = {
11825 AtrulePrelude: atrulePrelude,
11826 Selector: selector,
11827 Value: value
11828 };
11829
11830 var fontFace = {
11831 parse: {
11832 prelude: null,
11833 block: function() {
11834 return this.Block(true);
11835 }
11836 }
11837 };
11838
11839 var TYPE$G = tokenizer.TYPE;
11840
11841 var STRING$3 = TYPE$G.String;
11842 var IDENT$h = TYPE$G.Ident;
11843 var URL$3 = TYPE$G.Url;
11844 var FUNCTION$5 = TYPE$G.Function;
11845 var LEFTPARENTHESIS$6 = TYPE$G.LeftParenthesis;
11846
11847 var _import = {
11848 parse: {
11849 prelude: function() {
11850 var children = this.createList();
11851
11852 this.scanner.skipSC();
11853
11854 switch (this.scanner.tokenType) {
11855 case STRING$3:
11856 children.push(this.String());
11857 break;
11858
11859 case URL$3:
11860 case FUNCTION$5:
11861 children.push(this.Url());
11862 break;
11863
11864 default:
11865 this.error('String or url() is expected');
11866 }
11867
11868 if (this.lookupNonWSType(0) === IDENT$h ||
11869 this.lookupNonWSType(0) === LEFTPARENTHESIS$6) {
11870 children.push(this.WhiteSpace());
11871 children.push(this.MediaQueryList());
11872 }
11873
11874 return children;
11875 },
11876 block: null
11877 }
11878 };
11879
11880 var media = {
11881 parse: {
11882 prelude: function() {
11883 return this.createSingleNodeList(
11884 this.MediaQueryList()
11885 );
11886 },
11887 block: function() {
11888 return this.Block(false);
11889 }
11890 }
11891 };
11892
11893 var page = {
11894 parse: {
11895 prelude: function() {
11896 return this.createSingleNodeList(
11897 this.SelectorList()
11898 );
11899 },
11900 block: function() {
11901 return this.Block(true);
11902 }
11903 }
11904 };
11905
11906 var TYPE$H = tokenizer.TYPE;
11907
11908 var WHITESPACE$a = TYPE$H.WhiteSpace;
11909 var COMMENT$9 = TYPE$H.Comment;
11910 var IDENT$i = TYPE$H.Ident;
11911 var FUNCTION$6 = TYPE$H.Function;
11912 var COLON$6 = TYPE$H.Colon;
11913 var LEFTPARENTHESIS$7 = TYPE$H.LeftParenthesis;
11914
11915 function consumeRaw$5() {
11916 return this.createSingleNodeList(
11917 this.Raw(this.scanner.tokenIndex, null, false)
11918 );
11919 }
11920
11921 function parentheses() {
11922 this.scanner.skipSC();
11923
11924 if (this.scanner.tokenType === IDENT$i &&
11925 this.lookupNonWSType(1) === COLON$6) {
11926 return this.createSingleNodeList(
11927 this.Declaration()
11928 );
11929 }
11930
11931 return readSequence.call(this);
11932 }
11933
11934 function readSequence() {
11935 var children = this.createList();
11936 var space = null;
11937 var child;
11938
11939 this.scanner.skipSC();
11940
11941 scan:
11942 while (!this.scanner.eof) {
11943 switch (this.scanner.tokenType) {
11944 case WHITESPACE$a:
11945 space = this.WhiteSpace();
11946 continue;
11947
11948 case COMMENT$9:
11949 this.scanner.next();
11950 continue;
11951
11952 case FUNCTION$6:
11953 child = this.Function(consumeRaw$5, this.scope.AtrulePrelude);
11954 break;
11955
11956 case IDENT$i:
11957 child = this.Identifier();
11958 break;
11959
11960 case LEFTPARENTHESIS$7:
11961 child = this.Parentheses(parentheses, this.scope.AtrulePrelude);
11962 break;
11963
11964 default:
11965 break scan;
11966 }
11967
11968 if (space !== null) {
11969 children.push(space);
11970 space = null;
11971 }
11972
11973 children.push(child);
11974 }
11975
11976 return children;
11977 }
11978
11979 var supports = {
11980 parse: {
11981 prelude: function() {
11982 var children = readSequence.call(this);
11983
11984 if (this.getFirstListNode(children) === null) {
11985 this.error('Condition is expected');
11986 }
11987
11988 return children;
11989 },
11990 block: function() {
11991 return this.Block(false);
11992 }
11993 }
11994 };
11995
11996 var atrule = {
11997 'font-face': fontFace,
11998 'import': _import,
11999 'media': media,
12000 'page': page,
12001 'supports': supports
12002 };
12003
12004 var dir = {
12005 parse: function() {
12006 return this.createSingleNodeList(
12007 this.Identifier()
12008 );
12009 }
12010 };
12011
12012 var has$1 = {
12013 parse: function() {
12014 return this.createSingleNodeList(
12015 this.SelectorList()
12016 );
12017 }
12018 };
12019
12020 var lang = {
12021 parse: function() {
12022 return this.createSingleNodeList(
12023 this.Identifier()
12024 );
12025 }
12026 };
12027
12028 var selectorList = {
12029 parse: function selectorList() {
12030 return this.createSingleNodeList(
12031 this.SelectorList()
12032 );
12033 }
12034 };
12035
12036 var matches = selectorList;
12037
12038 var not = selectorList;
12039
12040 var ALLOW_OF_CLAUSE = true;
12041
12042 var nthWithOfClause = {
12043 parse: function nthWithOfClause() {
12044 return this.createSingleNodeList(
12045 this.Nth(ALLOW_OF_CLAUSE)
12046 );
12047 }
12048 };
12049
12050 var nthChild = nthWithOfClause;
12051
12052 var nthLastChild = nthWithOfClause;
12053
12054 var DISALLOW_OF_CLAUSE = false;
12055
12056 var nth = {
12057 parse: function nth() {
12058 return this.createSingleNodeList(
12059 this.Nth(DISALLOW_OF_CLAUSE)
12060 );
12061 }
12062 };
12063
12064 var nthLastOfType = nth;
12065
12066 var nthOfType = nth;
12067
12068 var slotted = {
12069 parse: function compoundSelector() {
12070 return this.createSingleNodeList(
12071 this.Selector()
12072 );
12073 }
12074 };
12075
12076 var pseudo = {
12077 'dir': dir,
12078 'has': has$1,
12079 'lang': lang,
12080 'matches': matches,
12081 'not': not,
12082 'nth-child': nthChild,
12083 'nth-last-child': nthLastChild,
12084 'nth-last-of-type': nthLastOfType,
12085 'nth-of-type': nthOfType,
12086 'slotted': slotted
12087 };
12088
12089 var parser = {
12090 parseContext: {
12091 default: 'StyleSheet',
12092 stylesheet: 'StyleSheet',
12093 atrule: 'Atrule',
12094 atrulePrelude: function(options) {
12095 return this.AtrulePrelude(options.atrule ? String(options.atrule) : null);
12096 },
12097 mediaQueryList: 'MediaQueryList',
12098 mediaQuery: 'MediaQuery',
12099 rule: 'Rule',
12100 selectorList: 'SelectorList',
12101 selector: 'Selector',
12102 block: function() {
12103 return this.Block(true);
12104 },
12105 declarationList: 'DeclarationList',
12106 declaration: 'Declaration',
12107 value: 'Value'
12108 },
12109 scope: scope,
12110 atrule: atrule,
12111 pseudo: pseudo,
12112 node: node
12113 };
12114
12115 var walker = {
12116 node: node
12117 };
12118
12119 function merge() {
12120 var dest = {};
12121
12122 for (var i = 0; i < arguments.length; i++) {
12123 var src = arguments[i];
12124 for (var key in src) {
12125 dest[key] = src[key];
12126 }
12127 }
12128
12129 return dest;
12130 }
12131
12132 var syntax = create$4.create(
12133 merge(
12134 lexer,
12135 parser,
12136 walker
12137 )
12138 );
12139
12140 var lib = syntax;
12141
12142 return lib;
12143
12144}));