UNPKG

831 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (global = global || self, factory(global.svelte = {}));
5}(this, function (exports) { 'use strict';
6
7 function assign(tar, src) {
8 // @ts-ignore
9 for (const k in src)
10 tar[k] = src[k];
11 return tar;
12 }
13
14 const now = (typeof process !== 'undefined' && process.hrtime)
15 ? () => {
16 const t = process.hrtime();
17 return t[0] * 1e3 + t[1] / 1e6;
18 }
19 : () => self.performance.now();
20 function collapse_timings(timings) {
21 const result = {};
22 timings.forEach(timing => {
23 result[timing.label] = Object.assign({
24 total: timing.end - timing.start
25 }, timing.children && collapse_timings(timing.children));
26 });
27 return result;
28 }
29 class Stats {
30 constructor() {
31 this.start_time = now();
32 this.stack = [];
33 this.current_children = this.timings = [];
34 }
35 start(label) {
36 const timing = {
37 label,
38 start: now(),
39 end: null,
40 children: []
41 };
42 this.current_children.push(timing);
43 this.stack.push(timing);
44 this.current_timing = timing;
45 this.current_children = timing.children;
46 }
47 stop(label) {
48 if (label !== this.current_timing.label) {
49 throw new Error(`Mismatched timing labels (expected ${this.current_timing.label}, got ${label})`);
50 }
51 this.current_timing.end = now();
52 this.stack.pop();
53 this.current_timing = this.stack[this.stack.length - 1];
54 this.current_children = this.current_timing ? this.current_timing.children : this.timings;
55 }
56 render() {
57 const timings = Object.assign({
58 total: now() - this.start_time
59 }, collapse_timings(this.timings));
60 return {
61 timings
62 };
63 }
64 }
65
66 // Reserved word lists for various dialects of the language
67
68 var reservedWords = {
69 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
70 5: "class enum extends super const export import",
71 6: "enum",
72 strict: "implements interface let package private protected public static yield",
73 strictBind: "eval arguments"
74 };
75
76 // And the keywords
77
78 var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
79
80 var keywords = {
81 5: ecma5AndLessKeywords,
82 6: ecma5AndLessKeywords + " const class extends export import super"
83 };
84
85 var keywordRelationalOperator = /^in(stanceof)?$/;
86
87 // ## Character categories
88
89 // Big ugly regular expressions that match characters in the
90 // whitespace, identifier, and identifier-start categories. These
91 // are only applied when a character is found to actually have a
92 // code point above 128.
93 // Generated by `bin/generate-identifier-regex.js`.
94
95 var nonASCIIidentifierStartChars = "aab5bac0-d6d8-f6f8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7c6\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab67\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
96 var nonASCIIidentifierChars = "\u200c\u200db7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
97
98 var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
99 var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
100
101 nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
102
103 // These are a run-length and offset encoded representation of the
104 // >0xffff code points that are a valid part of identifiers. The
105 // offset starts at 0x10000, and each pair of numbers represents an
106 // offset to the next range, and then a size of the range. They were
107 // generated by bin/generate-identifier-regex.js
108
109 // eslint-disable-next-line comma-spacing
110 var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,155,22,13,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,21,0,33,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,0,161,7,3,38,17,0,2,0,29,0,11,39,8,0,22,0,12,45,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,74,6,0,67,12,65,1,2,0,29,6135,9,754,9486,286,50,2,18,3,9,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,2357,44,11,6,17,0,370,43,1301,196,60,67,8,0,1205,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541];
111
112 // eslint-disable-next-line comma-spacing
113 var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,232,6,3,6,4,0,29,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1014,0,2,54,8,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,262,6,10,9,419,13,1495,6,110,6,6,9,792487,239];
114
115 // This has a complexity linear to the value of the code. The
116 // assumption is that looking up astral identifier characters is
117 // rare.
118 function isInAstralSet(code, set) {
119 var pos = 0x10000;
120 for (var i = 0; i < set.length; i += 2) {
121 pos += set[i];
122 if (pos > code) { return false }
123 pos += set[i + 1];
124 if (pos >= code) { return true }
125 }
126 }
127
128 // Test whether a given character code starts an identifier.
129
130 function isIdentifierStart(code, astral) {
131 if (code < 65) { return code === 36 }
132 if (code < 91) { return true }
133 if (code < 97) { return code === 95 }
134 if (code < 123) { return true }
135 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
136 if (astral === false) { return false }
137 return isInAstralSet(code, astralIdentifierStartCodes)
138 }
139
140 // Test whether a given character is part of an identifier.
141
142 function isIdentifierChar(code, astral) {
143 if (code < 48) { return code === 36 }
144 if (code < 58) { return true }
145 if (code < 65) { return false }
146 if (code < 91) { return true }
147 if (code < 97) { return code === 95 }
148 if (code < 123) { return true }
149 if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
150 if (astral === false) { return false }
151 return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
152 }
153
154 // ## Token types
155
156 // The assignment of fine-grained, information-carrying type objects
157 // allows the tokenizer to store the information it has about a
158 // token in a way that is very cheap for the parser to look up.
159
160 // All token type variables start with an underscore, to make them
161 // easy to recognize.
162
163 // The `beforeExpr` property is used to disambiguate between regular
164 // expressions and divisions. It is set on all token types that can
165 // be followed by an expression (thus, a slash after them would be a
166 // regular expression).
167 //
168 // The `startsExpr` property is used to check if the token ends a
169 // `yield` expression. It is set on all token types that either can
170 // directly start an expression (like a quotation mark) or can
171 // continue an expression (like the body of a string).
172 //
173 // `isLoop` marks a keyword as starting a loop, which is important
174 // to know when parsing a label, in order to allow or disallow
175 // continue jumps to that label.
176
177 var TokenType = function TokenType(label, conf) {
178 if ( conf === void 0 ) conf = {};
179
180 this.label = label;
181 this.keyword = conf.keyword;
182 this.beforeExpr = !!conf.beforeExpr;
183 this.startsExpr = !!conf.startsExpr;
184 this.isLoop = !!conf.isLoop;
185 this.isAssign = !!conf.isAssign;
186 this.prefix = !!conf.prefix;
187 this.postfix = !!conf.postfix;
188 this.binop = conf.binop || null;
189 this.updateContext = null;
190 };
191
192 function binop(name, prec) {
193 return new TokenType(name, {beforeExpr: true, binop: prec})
194 }
195 var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
196
197 // Map keyword names to token types.
198
199 var keywords$1 = {};
200
201 // Succinct definitions of keyword token types
202 function kw(name, options) {
203 if ( options === void 0 ) options = {};
204
205 options.keyword = name;
206 return keywords$1[name] = new TokenType(name, options)
207 }
208
209 var types = {
210 num: new TokenType("num", startsExpr),
211 regexp: new TokenType("regexp", startsExpr),
212 string: new TokenType("string", startsExpr),
213 name: new TokenType("name", startsExpr),
214 eof: new TokenType("eof"),
215
216 // Punctuation token types.
217 bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
218 bracketR: new TokenType("]"),
219 braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
220 braceR: new TokenType("}"),
221 parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
222 parenR: new TokenType(")"),
223 comma: new TokenType(",", beforeExpr),
224 semi: new TokenType(";", beforeExpr),
225 colon: new TokenType(":", beforeExpr),
226 dot: new TokenType("."),
227 question: new TokenType("?", beforeExpr),
228 arrow: new TokenType("=>", beforeExpr),
229 template: new TokenType("template"),
230 invalidTemplate: new TokenType("invalidTemplate"),
231 ellipsis: new TokenType("...", beforeExpr),
232 backQuote: new TokenType("`", startsExpr),
233 dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
234
235 // Operators. These carry several kinds of properties to help the
236 // parser use them properly (the presence of these properties is
237 // what categorizes them as operators).
238 //
239 // `binop`, when present, specifies that this operator is a binary
240 // operator, and will refer to its precedence.
241 //
242 // `prefix` and `postfix` mark the operator as a prefix or postfix
243 // unary operator.
244 //
245 // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
246 // binary operators with a very low precedence, that should result
247 // in AssignmentExpression nodes.
248
249 eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
250 assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
251 incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
252 prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
253 logicalOR: binop("||", 1),
254 logicalAND: binop("&&", 2),
255 bitwiseOR: binop("|", 3),
256 bitwiseXOR: binop("^", 4),
257 bitwiseAND: binop("&", 5),
258 equality: binop("==/!=/===/!==", 6),
259 relational: binop("</>/<=/>=", 7),
260 bitShift: binop("<</>>/>>>", 8),
261 plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
262 modulo: binop("%", 10),
263 star: binop("*", 10),
264 slash: binop("/", 10),
265 starstar: new TokenType("**", {beforeExpr: true}),
266
267 // Keyword token types.
268 _break: kw("break"),
269 _case: kw("case", beforeExpr),
270 _catch: kw("catch"),
271 _continue: kw("continue"),
272 _debugger: kw("debugger"),
273 _default: kw("default", beforeExpr),
274 _do: kw("do", {isLoop: true, beforeExpr: true}),
275 _else: kw("else", beforeExpr),
276 _finally: kw("finally"),
277 _for: kw("for", {isLoop: true}),
278 _function: kw("function", startsExpr),
279 _if: kw("if"),
280 _return: kw("return", beforeExpr),
281 _switch: kw("switch"),
282 _throw: kw("throw", beforeExpr),
283 _try: kw("try"),
284 _var: kw("var"),
285 _const: kw("const"),
286 _while: kw("while", {isLoop: true}),
287 _with: kw("with"),
288 _new: kw("new", {beforeExpr: true, startsExpr: true}),
289 _this: kw("this", startsExpr),
290 _super: kw("super", startsExpr),
291 _class: kw("class", startsExpr),
292 _extends: kw("extends", beforeExpr),
293 _export: kw("export"),
294 _import: kw("import", startsExpr),
295 _null: kw("null", startsExpr),
296 _true: kw("true", startsExpr),
297 _false: kw("false", startsExpr),
298 _in: kw("in", {beforeExpr: true, binop: 7}),
299 _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
300 _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
301 _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
302 _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
303 };
304
305 // Matches a whole line break (where CRLF is considered a single
306 // line break). Used to count lines.
307
308 var lineBreak = /\r\n?|\n|\u2028|\u2029/;
309 var lineBreakG = new RegExp(lineBreak.source, "g");
310
311 function isNewLine(code, ecma2019String) {
312 return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))
313 }
314
315 var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
316
317 var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
318
319 var ref = Object.prototype;
320 var hasOwnProperty = ref.hasOwnProperty;
321 var toString = ref.toString;
322
323 // Checks if an object has a property.
324
325 function has(obj, propName) {
326 return hasOwnProperty.call(obj, propName)
327 }
328
329 var isArray = Array.isArray || (function (obj) { return (
330 toString.call(obj) === "[object Array]"
331 ); });
332
333 function wordsRegexp(words) {
334 return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
335 }
336
337 // These are used when `options.locations` is on, for the
338 // `startLoc` and `endLoc` properties.
339
340 var Position = function Position(line, col) {
341 this.line = line;
342 this.column = col;
343 };
344
345 Position.prototype.offset = function offset (n) {
346 return new Position(this.line, this.column + n)
347 };
348
349 var SourceLocation = function SourceLocation(p, start, end) {
350 this.start = start;
351 this.end = end;
352 if (p.sourceFile !== null) { this.source = p.sourceFile; }
353 };
354
355 // The `getLineInfo` function is mostly useful when the
356 // `locations` option is off (for performance reasons) and you
357 // want to find the line/column position for a given character
358 // offset. `input` should be the code string that the offset refers
359 // into.
360
361 function getLineInfo(input, offset) {
362 for (var line = 1, cur = 0;;) {
363 lineBreakG.lastIndex = cur;
364 var match = lineBreakG.exec(input);
365 if (match && match.index < offset) {
366 ++line;
367 cur = match.index + match[0].length;
368 } else {
369 return new Position(line, offset - cur)
370 }
371 }
372 }
373
374 // A second optional argument can be given to further configure
375 // the parser process. These options are recognized:
376
377 var defaultOptions = {
378 // `ecmaVersion` indicates the ECMAScript version to parse. Must be
379 // either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10
380 // (2019). This influences support for strict mode, the set of
381 // reserved words, and support for new syntax features. The default
382 // is 9.
383 ecmaVersion: 9,
384 // `sourceType` indicates the mode the code should be parsed in.
385 // Can be either `"script"` or `"module"`. This influences global
386 // strict mode and parsing of `import` and `export` declarations.
387 sourceType: "script",
388 // `onInsertedSemicolon` can be a callback that will be called
389 // when a semicolon is automatically inserted. It will be passed
390 // the position of the comma as an offset, and if `locations` is
391 // enabled, it is given the location as a `{line, column}` object
392 // as second argument.
393 onInsertedSemicolon: null,
394 // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
395 // trailing commas.
396 onTrailingComma: null,
397 // By default, reserved words are only enforced if ecmaVersion >= 5.
398 // Set `allowReserved` to a boolean value to explicitly turn this on
399 // an off. When this option has the value "never", reserved words
400 // and keywords can also not be used as property names.
401 allowReserved: null,
402 // When enabled, a return at the top level is not considered an
403 // error.
404 allowReturnOutsideFunction: false,
405 // When enabled, import/export statements are not constrained to
406 // appearing at the top of the program.
407 allowImportExportEverywhere: false,
408 // When enabled, await identifiers are allowed to appear at the top-level scope,
409 // but they are still not allowed in non-async functions.
410 allowAwaitOutsideFunction: false,
411 // When enabled, hashbang directive in the beginning of file
412 // is allowed and treated as a line comment.
413 allowHashBang: false,
414 // When `locations` is on, `loc` properties holding objects with
415 // `start` and `end` properties in `{line, column}` form (with
416 // line being 1-based and column 0-based) will be attached to the
417 // nodes.
418 locations: false,
419 // A function can be passed as `onToken` option, which will
420 // cause Acorn to call that function with object in the same
421 // format as tokens returned from `tokenizer().getToken()`. Note
422 // that you are not allowed to call the parser from the
423 // callback—that will corrupt its internal state.
424 onToken: null,
425 // A function can be passed as `onComment` option, which will
426 // cause Acorn to call that function with `(block, text, start,
427 // end)` parameters whenever a comment is skipped. `block` is a
428 // boolean indicating whether this is a block (`/* */`) comment,
429 // `text` is the content of the comment, and `start` and `end` are
430 // character offsets that denote the start and end of the comment.
431 // When the `locations` option is on, two more parameters are
432 // passed, the full `{line, column}` locations of the start and
433 // end of the comments. Note that you are not allowed to call the
434 // parser from the callback—that will corrupt its internal state.
435 onComment: null,
436 // Nodes have their start and end characters offsets recorded in
437 // `start` and `end` properties (directly on the node, rather than
438 // the `loc` object, which holds line/column data. To also add a
439 // [semi-standardized][range] `range` property holding a `[start,
440 // end]` array with the same numbers, set the `ranges` option to
441 // `true`.
442 //
443 // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
444 ranges: false,
445 // It is possible to parse multiple files into a single AST by
446 // passing the tree produced by parsing the first file as
447 // `program` option in subsequent parses. This will add the
448 // toplevel forms of the parsed file to the `Program` (top) node
449 // of an existing parse tree.
450 program: null,
451 // When `locations` is on, you can pass this to record the source
452 // file in every node's `loc` object.
453 sourceFile: null,
454 // This value, if given, is stored in every node, whether
455 // `locations` is on or off.
456 directSourceFile: null,
457 // When enabled, parenthesized expressions are represented by
458 // (non-standard) ParenthesizedExpression nodes
459 preserveParens: false
460 };
461
462 // Interpret and default an options object
463
464 function getOptions(opts) {
465 var options = {};
466
467 for (var opt in defaultOptions)
468 { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
469
470 if (options.ecmaVersion >= 2015)
471 { options.ecmaVersion -= 2009; }
472
473 if (options.allowReserved == null)
474 { options.allowReserved = options.ecmaVersion < 5; }
475
476 if (isArray(options.onToken)) {
477 var tokens = options.onToken;
478 options.onToken = function (token) { return tokens.push(token); };
479 }
480 if (isArray(options.onComment))
481 { options.onComment = pushComment(options, options.onComment); }
482
483 return options
484 }
485
486 function pushComment(options, array) {
487 return function(block, text, start, end, startLoc, endLoc) {
488 var comment = {
489 type: block ? "Block" : "Line",
490 value: text,
491 start: start,
492 end: end
493 };
494 if (options.locations)
495 { comment.loc = new SourceLocation(this, startLoc, endLoc); }
496 if (options.ranges)
497 { comment.range = [start, end]; }
498 array.push(comment);
499 }
500 }
501
502 // Each scope gets a bitset that may contain these flags
503 var
504 SCOPE_TOP = 1,
505 SCOPE_FUNCTION = 2,
506 SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION,
507 SCOPE_ASYNC = 4,
508 SCOPE_GENERATOR = 8,
509 SCOPE_ARROW = 16,
510 SCOPE_SIMPLE_CATCH = 32,
511 SCOPE_SUPER = 64,
512 SCOPE_DIRECT_SUPER = 128;
513
514 function functionFlags(async, generator) {
515 return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
516 }
517
518 // Used in checkLVal and declareName to determine the type of a binding
519 var
520 BIND_NONE = 0, // Not a binding
521 BIND_VAR = 1, // Var-style binding
522 BIND_LEXICAL = 2, // Let- or const-style binding
523 BIND_FUNCTION = 3, // Function declaration
524 BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
525 BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
526
527 var Parser = function Parser(options, input, startPos) {
528 this.options = options = getOptions(options);
529 this.sourceFile = options.sourceFile;
530 this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);
531 var reserved = "";
532 if (!options.allowReserved) {
533 for (var v = options.ecmaVersion;; v--)
534 { if (reserved = reservedWords[v]) { break } }
535 if (options.sourceType === "module") { reserved += " await"; }
536 }
537 this.reservedWords = wordsRegexp(reserved);
538 var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
539 this.reservedWordsStrict = wordsRegexp(reservedStrict);
540 this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
541 this.input = String(input);
542
543 // Used to signal to callers of `readWord1` whether the word
544 // contained any escape sequences. This is needed because words with
545 // escape sequences must not be interpreted as keywords.
546 this.containsEsc = false;
547
548 // Set up token state
549
550 // The current position of the tokenizer in the input.
551 if (startPos) {
552 this.pos = startPos;
553 this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
554 this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
555 } else {
556 this.pos = this.lineStart = 0;
557 this.curLine = 1;
558 }
559
560 // Properties of the current token:
561 // Its type
562 this.type = types.eof;
563 // For tokens that include more information than their type, the value
564 this.value = null;
565 // Its start and end offset
566 this.start = this.end = this.pos;
567 // And, if locations are used, the {line, column} object
568 // corresponding to those offsets
569 this.startLoc = this.endLoc = this.curPosition();
570
571 // Position information for the previous token
572 this.lastTokEndLoc = this.lastTokStartLoc = null;
573 this.lastTokStart = this.lastTokEnd = this.pos;
574
575 // The context stack is used to superficially track syntactic
576 // context to predict whether a regular expression is allowed in a
577 // given position.
578 this.context = this.initialContext();
579 this.exprAllowed = true;
580
581 // Figure out if it's a module code.
582 this.inModule = options.sourceType === "module";
583 this.strict = this.inModule || this.strictDirective(this.pos);
584
585 // Used to signify the start of a potential arrow function
586 this.potentialArrowAt = -1;
587
588 // Positions to delayed-check that yield/await does not exist in default parameters.
589 this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
590 // Labels in scope.
591 this.labels = [];
592 // Thus-far undefined exports.
593 this.undefinedExports = {};
594
595 // If enabled, skip leading hashbang line.
596 if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
597 { this.skipLineComment(2); }
598
599 // Scope tracking for duplicate variable names (see scope.js)
600 this.scopeStack = [];
601 this.enterScope(SCOPE_TOP);
602
603 // For RegExp validation
604 this.regexpState = null;
605 };
606
607 var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } };
608
609 Parser.prototype.parse = function parse () {
610 var node = this.options.program || this.startNode();
611 this.nextToken();
612 return this.parseTopLevel(node)
613 };
614
615 prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
616 prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
617 prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
618 prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
619 prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
620 prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
621
622 // Switch to a getter for 7.0.0.
623 Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
624
625 Parser.extend = function extend () {
626 var plugins = [], len = arguments.length;
627 while ( len-- ) plugins[ len ] = arguments[ len ];
628
629 var cls = this;
630 for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
631 return cls
632 };
633
634 Parser.parse = function parse (input, options) {
635 return new this(options, input).parse()
636 };
637
638 Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
639 var parser = new this(options, input, pos);
640 parser.nextToken();
641 return parser.parseExpression()
642 };
643
644 Parser.tokenizer = function tokenizer (input, options) {
645 return new this(options, input)
646 };
647
648 Object.defineProperties( Parser.prototype, prototypeAccessors );
649
650 var pp = Parser.prototype;
651
652 // ## Parser utilities
653
654 var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)")/;
655 pp.strictDirective = function(start) {
656 for (;;) {
657 // Try to find string literal.
658 skipWhiteSpace.lastIndex = start;
659 start += skipWhiteSpace.exec(this.input)[0].length;
660 var match = literal.exec(this.input.slice(start));
661 if (!match) { return false }
662 if ((match[1] || match[2]) === "use strict") { return true }
663 start += match[0].length;
664
665 // Skip semicolon, if any.
666 skipWhiteSpace.lastIndex = start;
667 start += skipWhiteSpace.exec(this.input)[0].length;
668 if (this.input[start] === ";")
669 { start++; }
670 }
671 };
672
673 // Predicate that tests whether the next token is of the given
674 // type, and if yes, consumes it as a side effect.
675
676 pp.eat = function(type) {
677 if (this.type === type) {
678 this.next();
679 return true
680 } else {
681 return false
682 }
683 };
684
685 // Tests whether parsed token is a contextual keyword.
686
687 pp.isContextual = function(name) {
688 return this.type === types.name && this.value === name && !this.containsEsc
689 };
690
691 // Consumes contextual keyword if possible.
692
693 pp.eatContextual = function(name) {
694 if (!this.isContextual(name)) { return false }
695 this.next();
696 return true
697 };
698
699 // Asserts that following token is given contextual keyword.
700
701 pp.expectContextual = function(name) {
702 if (!this.eatContextual(name)) { this.unexpected(); }
703 };
704
705 // Test whether a semicolon can be inserted at the current position.
706
707 pp.canInsertSemicolon = function() {
708 return this.type === types.eof ||
709 this.type === types.braceR ||
710 lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
711 };
712
713 pp.insertSemicolon = function() {
714 if (this.canInsertSemicolon()) {
715 if (this.options.onInsertedSemicolon)
716 { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
717 return true
718 }
719 };
720
721 // Consume a semicolon, or, failing that, see if we are allowed to
722 // pretend that there is a semicolon at this position.
723
724 pp.semicolon = function() {
725 if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
726 };
727
728 pp.afterTrailingComma = function(tokType, notNext) {
729 if (this.type === tokType) {
730 if (this.options.onTrailingComma)
731 { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
732 if (!notNext)
733 { this.next(); }
734 return true
735 }
736 };
737
738 // Expect a token of a given type. If found, consume it, otherwise,
739 // raise an unexpected token error.
740
741 pp.expect = function(type) {
742 this.eat(type) || this.unexpected();
743 };
744
745 // Raise an unexpected token error.
746
747 pp.unexpected = function(pos) {
748 this.raise(pos != null ? pos : this.start, "Unexpected token");
749 };
750
751 function DestructuringErrors() {
752 this.shorthandAssign =
753 this.trailingComma =
754 this.parenthesizedAssign =
755 this.parenthesizedBind =
756 this.doubleProto =
757 -1;
758 }
759
760 pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
761 if (!refDestructuringErrors) { return }
762 if (refDestructuringErrors.trailingComma > -1)
763 { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
764 var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
765 if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
766 };
767
768 pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
769 if (!refDestructuringErrors) { return false }
770 var shorthandAssign = refDestructuringErrors.shorthandAssign;
771 var doubleProto = refDestructuringErrors.doubleProto;
772 if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
773 if (shorthandAssign >= 0)
774 { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
775 if (doubleProto >= 0)
776 { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
777 };
778
779 pp.checkYieldAwaitInDefaultParams = function() {
780 if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
781 { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
782 if (this.awaitPos)
783 { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
784 };
785
786 pp.isSimpleAssignTarget = function(expr) {
787 if (expr.type === "ParenthesizedExpression")
788 { return this.isSimpleAssignTarget(expr.expression) }
789 return expr.type === "Identifier" || expr.type === "MemberExpression"
790 };
791
792 var pp$1 = Parser.prototype;
793
794 // ### Statement parsing
795
796 // Parse a program. Initializes the parser, reads any number of
797 // statements, and wraps them in a Program node. Optionally takes a
798 // `program` argument. If present, the statements will be appended
799 // to its body instead of creating a new node.
800
801 pp$1.parseTopLevel = function(node) {
802 var exports = {};
803 if (!node.body) { node.body = []; }
804 while (this.type !== types.eof) {
805 var stmt = this.parseStatement(null, true, exports);
806 node.body.push(stmt);
807 }
808 if (this.inModule)
809 { for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
810 {
811 var name = list[i];
812
813 this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
814 } }
815 this.adaptDirectivePrologue(node.body);
816 this.next();
817 if (this.options.ecmaVersion >= 6) {
818 node.sourceType = this.options.sourceType;
819 }
820 return this.finishNode(node, "Program")
821 };
822
823 var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
824
825 pp$1.isLet = function(context) {
826 if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
827 skipWhiteSpace.lastIndex = this.pos;
828 var skip = skipWhiteSpace.exec(this.input);
829 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
830 // For ambiguous cases, determine if a LexicalDeclaration (or only a
831 // Statement) is allowed here. If context is not empty then only a Statement
832 // is allowed. However, `let [` is an explicit negative lookahead for
833 // ExpressionStatement, so special-case it first.
834 if (nextCh === 91) { return true } // '['
835 if (context) { return false }
836
837 if (nextCh === 123) { return true } // '{'
838 if (isIdentifierStart(nextCh, true)) {
839 var pos = next + 1;
840 while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
841 var ident = this.input.slice(next, pos);
842 if (!keywordRelationalOperator.test(ident)) { return true }
843 }
844 return false
845 };
846
847 // check 'async [no LineTerminator here] function'
848 // - 'async /*foo*/ function' is OK.
849 // - 'async /*\n*/ function' is invalid.
850 pp$1.isAsyncFunction = function() {
851 if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
852 { return false }
853
854 skipWhiteSpace.lastIndex = this.pos;
855 var skip = skipWhiteSpace.exec(this.input);
856 var next = this.pos + skip[0].length;
857 return !lineBreak.test(this.input.slice(this.pos, next)) &&
858 this.input.slice(next, next + 8) === "function" &&
859 (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
860 };
861
862 // Parse a single statement.
863 //
864 // If expecting a statement and finding a slash operator, parse a
865 // regular expression literal. This is to handle cases like
866 // `if (foo) /blah/.exec(foo)`, where looking at the previous token
867 // does not help.
868
869 pp$1.parseStatement = function(context, topLevel, exports) {
870 var starttype = this.type, node = this.startNode(), kind;
871
872 if (this.isLet(context)) {
873 starttype = types._var;
874 kind = "let";
875 }
876
877 // Most types of statements are recognized by the keyword they
878 // start with. Many are trivial to parse, some require a bit of
879 // complexity.
880
881 switch (starttype) {
882 case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
883 case types._debugger: return this.parseDebuggerStatement(node)
884 case types._do: return this.parseDoStatement(node)
885 case types._for: return this.parseForStatement(node)
886 case types._function:
887 // Function as sole body of either an if statement or a labeled statement
888 // works, but not when it is part of a labeled statement that is the sole
889 // body of an if statement.
890 if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
891 return this.parseFunctionStatement(node, false, !context)
892 case types._class:
893 if (context) { this.unexpected(); }
894 return this.parseClass(node, true)
895 case types._if: return this.parseIfStatement(node)
896 case types._return: return this.parseReturnStatement(node)
897 case types._switch: return this.parseSwitchStatement(node)
898 case types._throw: return this.parseThrowStatement(node)
899 case types._try: return this.parseTryStatement(node)
900 case types._const: case types._var:
901 kind = kind || this.value;
902 if (context && kind !== "var") { this.unexpected(); }
903 return this.parseVarStatement(node, kind)
904 case types._while: return this.parseWhileStatement(node)
905 case types._with: return this.parseWithStatement(node)
906 case types.braceL: return this.parseBlock(true, node)
907 case types.semi: return this.parseEmptyStatement(node)
908 case types._export:
909 case types._import:
910 if (this.options.ecmaVersion > 10 && starttype === types._import) {
911 skipWhiteSpace.lastIndex = this.pos;
912 var skip = skipWhiteSpace.exec(this.input);
913 var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
914 if (nextCh === 40) // '('
915 { return this.parseExpressionStatement(node, this.parseExpression()) }
916 }
917
918 if (!this.options.allowImportExportEverywhere) {
919 if (!topLevel)
920 { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
921 if (!this.inModule)
922 { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
923 }
924 return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
925
926 // If the statement does not start with a statement keyword or a
927 // brace, it's an ExpressionStatement or LabeledStatement. We
928 // simply start parsing an expression, and afterwards, if the
929 // next token is a colon and the expression was a simple
930 // Identifier node, we switch to interpreting it as a label.
931 default:
932 if (this.isAsyncFunction()) {
933 if (context) { this.unexpected(); }
934 this.next();
935 return this.parseFunctionStatement(node, true, !context)
936 }
937
938 var maybeName = this.value, expr = this.parseExpression();
939 if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
940 { return this.parseLabeledStatement(node, maybeName, expr, context) }
941 else { return this.parseExpressionStatement(node, expr) }
942 }
943 };
944
945 pp$1.parseBreakContinueStatement = function(node, keyword) {
946 var isBreak = keyword === "break";
947 this.next();
948 if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
949 else if (this.type !== types.name) { this.unexpected(); }
950 else {
951 node.label = this.parseIdent();
952 this.semicolon();
953 }
954
955 // Verify that there is an actual destination to break or
956 // continue to.
957 var i = 0;
958 for (; i < this.labels.length; ++i) {
959 var lab = this.labels[i];
960 if (node.label == null || lab.name === node.label.name) {
961 if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
962 if (node.label && isBreak) { break }
963 }
964 }
965 if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
966 return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
967 };
968
969 pp$1.parseDebuggerStatement = function(node) {
970 this.next();
971 this.semicolon();
972 return this.finishNode(node, "DebuggerStatement")
973 };
974
975 pp$1.parseDoStatement = function(node) {
976 this.next();
977 this.labels.push(loopLabel);
978 node.body = this.parseStatement("do");
979 this.labels.pop();
980 this.expect(types._while);
981 node.test = this.parseParenExpression();
982 if (this.options.ecmaVersion >= 6)
983 { this.eat(types.semi); }
984 else
985 { this.semicolon(); }
986 return this.finishNode(node, "DoWhileStatement")
987 };
988
989 // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
990 // loop is non-trivial. Basically, we have to parse the init `var`
991 // statement or expression, disallowing the `in` operator (see
992 // the second parameter to `parseExpression`), and then check
993 // whether the next token is `in` or `of`. When there is no init
994 // part (semicolon immediately after the opening parenthesis), it
995 // is a regular `for` loop.
996
997 pp$1.parseForStatement = function(node) {
998 this.next();
999 var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
1000 this.labels.push(loopLabel);
1001 this.enterScope(0);
1002 this.expect(types.parenL);
1003 if (this.type === types.semi) {
1004 if (awaitAt > -1) { this.unexpected(awaitAt); }
1005 return this.parseFor(node, null)
1006 }
1007 var isLet = this.isLet();
1008 if (this.type === types._var || this.type === types._const || isLet) {
1009 var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
1010 this.next();
1011 this.parseVar(init$1, true, kind);
1012 this.finishNode(init$1, "VariableDeclaration");
1013 if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
1014 if (this.options.ecmaVersion >= 9) {
1015 if (this.type === types._in) {
1016 if (awaitAt > -1) { this.unexpected(awaitAt); }
1017 } else { node.await = awaitAt > -1; }
1018 }
1019 return this.parseForIn(node, init$1)
1020 }
1021 if (awaitAt > -1) { this.unexpected(awaitAt); }
1022 return this.parseFor(node, init$1)
1023 }
1024 var refDestructuringErrors = new DestructuringErrors;
1025 var init = this.parseExpression(true, refDestructuringErrors);
1026 if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
1027 if (this.options.ecmaVersion >= 9) {
1028 if (this.type === types._in) {
1029 if (awaitAt > -1) { this.unexpected(awaitAt); }
1030 } else { node.await = awaitAt > -1; }
1031 }
1032 this.toAssignable(init, false, refDestructuringErrors);
1033 this.checkLVal(init);
1034 return this.parseForIn(node, init)
1035 } else {
1036 this.checkExpressionErrors(refDestructuringErrors, true);
1037 }
1038 if (awaitAt > -1) { this.unexpected(awaitAt); }
1039 return this.parseFor(node, init)
1040 };
1041
1042 pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) {
1043 this.next();
1044 return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
1045 };
1046
1047 pp$1.parseIfStatement = function(node) {
1048 this.next();
1049 node.test = this.parseParenExpression();
1050 // allow function declarations in branches, but only in non-strict mode
1051 node.consequent = this.parseStatement("if");
1052 node.alternate = this.eat(types._else) ? this.parseStatement("if") : null;
1053 return this.finishNode(node, "IfStatement")
1054 };
1055
1056 pp$1.parseReturnStatement = function(node) {
1057 if (!this.inFunction && !this.options.allowReturnOutsideFunction)
1058 { this.raise(this.start, "'return' outside of function"); }
1059 this.next();
1060
1061 // In `return` (and `break`/`continue`), the keywords with
1062 // optional arguments, we eagerly look for a semicolon or the
1063 // possibility to insert one.
1064
1065 if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
1066 else { node.argument = this.parseExpression(); this.semicolon(); }
1067 return this.finishNode(node, "ReturnStatement")
1068 };
1069
1070 pp$1.parseSwitchStatement = function(node) {
1071 this.next();
1072 node.discriminant = this.parseParenExpression();
1073 node.cases = [];
1074 this.expect(types.braceL);
1075 this.labels.push(switchLabel);
1076 this.enterScope(0);
1077
1078 // Statements under must be grouped (by label) in SwitchCase
1079 // nodes. `cur` is used to keep the node that we are currently
1080 // adding statements to.
1081
1082 var cur;
1083 for (var sawDefault = false; this.type !== types.braceR;) {
1084 if (this.type === types._case || this.type === types._default) {
1085 var isCase = this.type === types._case;
1086 if (cur) { this.finishNode(cur, "SwitchCase"); }
1087 node.cases.push(cur = this.startNode());
1088 cur.consequent = [];
1089 this.next();
1090 if (isCase) {
1091 cur.test = this.parseExpression();
1092 } else {
1093 if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
1094 sawDefault = true;
1095 cur.test = null;
1096 }
1097 this.expect(types.colon);
1098 } else {
1099 if (!cur) { this.unexpected(); }
1100 cur.consequent.push(this.parseStatement(null));
1101 }
1102 }
1103 this.exitScope();
1104 if (cur) { this.finishNode(cur, "SwitchCase"); }
1105 this.next(); // Closing brace
1106 this.labels.pop();
1107 return this.finishNode(node, "SwitchStatement")
1108 };
1109
1110 pp$1.parseThrowStatement = function(node) {
1111 this.next();
1112 if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
1113 { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
1114 node.argument = this.parseExpression();
1115 this.semicolon();
1116 return this.finishNode(node, "ThrowStatement")
1117 };
1118
1119 // Reused empty array added for node fields that are always empty.
1120
1121 var empty = [];
1122
1123 pp$1.parseTryStatement = function(node) {
1124 this.next();
1125 node.block = this.parseBlock();
1126 node.handler = null;
1127 if (this.type === types._catch) {
1128 var clause = this.startNode();
1129 this.next();
1130 if (this.eat(types.parenL)) {
1131 clause.param = this.parseBindingAtom();
1132 var simple = clause.param.type === "Identifier";
1133 this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
1134 this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
1135 this.expect(types.parenR);
1136 } else {
1137 if (this.options.ecmaVersion < 10) { this.unexpected(); }
1138 clause.param = null;
1139 this.enterScope(0);
1140 }
1141 clause.body = this.parseBlock(false);
1142 this.exitScope();
1143 node.handler = this.finishNode(clause, "CatchClause");
1144 }
1145 node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
1146 if (!node.handler && !node.finalizer)
1147 { this.raise(node.start, "Missing catch or finally clause"); }
1148 return this.finishNode(node, "TryStatement")
1149 };
1150
1151 pp$1.parseVarStatement = function(node, kind) {
1152 this.next();
1153 this.parseVar(node, false, kind);
1154 this.semicolon();
1155 return this.finishNode(node, "VariableDeclaration")
1156 };
1157
1158 pp$1.parseWhileStatement = function(node) {
1159 this.next();
1160 node.test = this.parseParenExpression();
1161 this.labels.push(loopLabel);
1162 node.body = this.parseStatement("while");
1163 this.labels.pop();
1164 return this.finishNode(node, "WhileStatement")
1165 };
1166
1167 pp$1.parseWithStatement = function(node) {
1168 if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
1169 this.next();
1170 node.object = this.parseParenExpression();
1171 node.body = this.parseStatement("with");
1172 return this.finishNode(node, "WithStatement")
1173 };
1174
1175 pp$1.parseEmptyStatement = function(node) {
1176 this.next();
1177 return this.finishNode(node, "EmptyStatement")
1178 };
1179
1180 pp$1.parseLabeledStatement = function(node, maybeName, expr, context) {
1181 for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
1182 {
1183 var label = list[i$1];
1184
1185 if (label.name === maybeName)
1186 { this.raise(expr.start, "Label '" + maybeName + "' is already declared");
1187 } }
1188 var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
1189 for (var i = this.labels.length - 1; i >= 0; i--) {
1190 var label$1 = this.labels[i];
1191 if (label$1.statementStart === node.start) {
1192 // Update information about previous labels on this node
1193 label$1.statementStart = this.start;
1194 label$1.kind = kind;
1195 } else { break }
1196 }
1197 this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
1198 node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
1199 this.labels.pop();
1200 node.label = expr;
1201 return this.finishNode(node, "LabeledStatement")
1202 };
1203
1204 pp$1.parseExpressionStatement = function(node, expr) {
1205 node.expression = expr;
1206 this.semicolon();
1207 return this.finishNode(node, "ExpressionStatement")
1208 };
1209
1210 // Parse a semicolon-enclosed block of statements, handling `"use
1211 // strict"` declarations when `allowStrict` is true (used for
1212 // function bodies).
1213
1214 pp$1.parseBlock = function(createNewLexicalScope, node) {
1215 if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
1216 if ( node === void 0 ) node = this.startNode();
1217
1218 node.body = [];
1219 this.expect(types.braceL);
1220 if (createNewLexicalScope) { this.enterScope(0); }
1221 while (!this.eat(types.braceR)) {
1222 var stmt = this.parseStatement(null);
1223 node.body.push(stmt);
1224 }
1225 if (createNewLexicalScope) { this.exitScope(); }
1226 return this.finishNode(node, "BlockStatement")
1227 };
1228
1229 // Parse a regular `for` loop. The disambiguation code in
1230 // `parseStatement` will already have parsed the init statement or
1231 // expression.
1232
1233 pp$1.parseFor = function(node, init) {
1234 node.init = init;
1235 this.expect(types.semi);
1236 node.test = this.type === types.semi ? null : this.parseExpression();
1237 this.expect(types.semi);
1238 node.update = this.type === types.parenR ? null : this.parseExpression();
1239 this.expect(types.parenR);
1240 node.body = this.parseStatement("for");
1241 this.exitScope();
1242 this.labels.pop();
1243 return this.finishNode(node, "ForStatement")
1244 };
1245
1246 // Parse a `for`/`in` and `for`/`of` loop, which are almost
1247 // same from parser's perspective.
1248
1249 pp$1.parseForIn = function(node, init) {
1250 var isForIn = this.type === types._in;
1251 this.next();
1252
1253 if (
1254 init.type === "VariableDeclaration" &&
1255 init.declarations[0].init != null &&
1256 (
1257 !isForIn ||
1258 this.options.ecmaVersion < 8 ||
1259 this.strict ||
1260 init.kind !== "var" ||
1261 init.declarations[0].id.type !== "Identifier"
1262 )
1263 ) {
1264 this.raise(
1265 init.start,
1266 ((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
1267 );
1268 } else if (init.type === "AssignmentPattern") {
1269 this.raise(init.start, "Invalid left-hand side in for-loop");
1270 }
1271 node.left = init;
1272 node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
1273 this.expect(types.parenR);
1274 node.body = this.parseStatement("for");
1275 this.exitScope();
1276 this.labels.pop();
1277 return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
1278 };
1279
1280 // Parse a list of variable declarations.
1281
1282 pp$1.parseVar = function(node, isFor, kind) {
1283 node.declarations = [];
1284 node.kind = kind;
1285 for (;;) {
1286 var decl = this.startNode();
1287 this.parseVarId(decl, kind);
1288 if (this.eat(types.eq)) {
1289 decl.init = this.parseMaybeAssign(isFor);
1290 } else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
1291 this.unexpected();
1292 } else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) {
1293 this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
1294 } else {
1295 decl.init = null;
1296 }
1297 node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
1298 if (!this.eat(types.comma)) { break }
1299 }
1300 return node
1301 };
1302
1303 pp$1.parseVarId = function(decl, kind) {
1304 decl.id = this.parseBindingAtom();
1305 this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
1306 };
1307
1308 var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
1309
1310 // Parse a function declaration or literal (depending on the
1311 // `statement & FUNC_STATEMENT`).
1312
1313 // Remove `allowExpressionBody` for 7.0.0, as it is only called with false
1314 pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) {
1315 this.initFunction(node);
1316 if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
1317 if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT))
1318 { this.unexpected(); }
1319 node.generator = this.eat(types.star);
1320 }
1321 if (this.options.ecmaVersion >= 8)
1322 { node.async = !!isAsync; }
1323
1324 if (statement & FUNC_STATEMENT) {
1325 node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent();
1326 if (node.id && !(statement & FUNC_HANGING_STATEMENT))
1327 // If it is a regular function declaration in sloppy mode, then it is
1328 // subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
1329 // mode depends on properties of the current scope (see
1330 // treatFunctionsAsVar).
1331 { this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
1332 }
1333
1334 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
1335 this.yieldPos = 0;
1336 this.awaitPos = 0;
1337 this.awaitIdentPos = 0;
1338 this.enterScope(functionFlags(node.async, node.generator));
1339
1340 if (!(statement & FUNC_STATEMENT))
1341 { node.id = this.type === types.name ? this.parseIdent() : null; }
1342
1343 this.parseFunctionParams(node);
1344 this.parseFunctionBody(node, allowExpressionBody, false);
1345
1346 this.yieldPos = oldYieldPos;
1347 this.awaitPos = oldAwaitPos;
1348 this.awaitIdentPos = oldAwaitIdentPos;
1349 return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
1350 };
1351
1352 pp$1.parseFunctionParams = function(node) {
1353 this.expect(types.parenL);
1354 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
1355 this.checkYieldAwaitInDefaultParams();
1356 };
1357
1358 // Parse a class declaration or literal (depending on the
1359 // `isStatement` parameter).
1360
1361 pp$1.parseClass = function(node, isStatement) {
1362 this.next();
1363
1364 // ecma-262 14.6 Class Definitions
1365 // A class definition is always strict mode code.
1366 var oldStrict = this.strict;
1367 this.strict = true;
1368
1369 this.parseClassId(node, isStatement);
1370 this.parseClassSuper(node);
1371 var classBody = this.startNode();
1372 var hadConstructor = false;
1373 classBody.body = [];
1374 this.expect(types.braceL);
1375 while (!this.eat(types.braceR)) {
1376 var element = this.parseClassElement(node.superClass !== null);
1377 if (element) {
1378 classBody.body.push(element);
1379 if (element.type === "MethodDefinition" && element.kind === "constructor") {
1380 if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
1381 hadConstructor = true;
1382 }
1383 }
1384 }
1385 node.body = this.finishNode(classBody, "ClassBody");
1386 this.strict = oldStrict;
1387 return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
1388 };
1389
1390 pp$1.parseClassElement = function(constructorAllowsSuper) {
1391 var this$1 = this;
1392
1393 if (this.eat(types.semi)) { return null }
1394
1395 var method = this.startNode();
1396 var tryContextual = function (k, noLineBreak) {
1397 if ( noLineBreak === void 0 ) noLineBreak = false;
1398
1399 var start = this$1.start, startLoc = this$1.startLoc;
1400 if (!this$1.eatContextual(k)) { return false }
1401 if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
1402 if (method.key) { this$1.unexpected(); }
1403 method.computed = false;
1404 method.key = this$1.startNodeAt(start, startLoc);
1405 method.key.name = k;
1406 this$1.finishNode(method.key, "Identifier");
1407 return false
1408 };
1409
1410 method.kind = "method";
1411 method.static = tryContextual("static");
1412 var isGenerator = this.eat(types.star);
1413 var isAsync = false;
1414 if (!isGenerator) {
1415 if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
1416 isAsync = true;
1417 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
1418 } else if (tryContextual("get")) {
1419 method.kind = "get";
1420 } else if (tryContextual("set")) {
1421 method.kind = "set";
1422 }
1423 }
1424 if (!method.key) { this.parsePropertyName(method); }
1425 var key = method.key;
1426 var allowsDirectSuper = false;
1427 if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
1428 key.type === "Literal" && key.value === "constructor")) {
1429 if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
1430 if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
1431 if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
1432 method.kind = "constructor";
1433 allowsDirectSuper = constructorAllowsSuper;
1434 } else if (method.static && key.type === "Identifier" && key.name === "prototype") {
1435 this.raise(key.start, "Classes may not have a static property named prototype");
1436 }
1437 this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
1438 if (method.kind === "get" && method.value.params.length !== 0)
1439 { this.raiseRecoverable(method.value.start, "getter should have no params"); }
1440 if (method.kind === "set" && method.value.params.length !== 1)
1441 { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
1442 if (method.kind === "set" && method.value.params[0].type === "RestElement")
1443 { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
1444 return method
1445 };
1446
1447 pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
1448 method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
1449 return this.finishNode(method, "MethodDefinition")
1450 };
1451
1452 pp$1.parseClassId = function(node, isStatement) {
1453 if (this.type === types.name) {
1454 node.id = this.parseIdent();
1455 if (isStatement)
1456 { this.checkLVal(node.id, BIND_LEXICAL, false); }
1457 } else {
1458 if (isStatement === true)
1459 { this.unexpected(); }
1460 node.id = null;
1461 }
1462 };
1463
1464 pp$1.parseClassSuper = function(node) {
1465 node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
1466 };
1467
1468 // Parses module export declaration.
1469
1470 pp$1.parseExport = function(node, exports) {
1471 this.next();
1472 // export * from '...'
1473 if (this.eat(types.star)) {
1474 this.expectContextual("from");
1475 if (this.type !== types.string) { this.unexpected(); }
1476 node.source = this.parseExprAtom();
1477 this.semicolon();
1478 return this.finishNode(node, "ExportAllDeclaration")
1479 }
1480 if (this.eat(types._default)) { // export default ...
1481 this.checkExport(exports, "default", this.lastTokStart);
1482 var isAsync;
1483 if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
1484 var fNode = this.startNode();
1485 this.next();
1486 if (isAsync) { this.next(); }
1487 node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
1488 } else if (this.type === types._class) {
1489 var cNode = this.startNode();
1490 node.declaration = this.parseClass(cNode, "nullableID");
1491 } else {
1492 node.declaration = this.parseMaybeAssign();
1493 this.semicolon();
1494 }
1495 return this.finishNode(node, "ExportDefaultDeclaration")
1496 }
1497 // export var|const|let|function|class ...
1498 if (this.shouldParseExportStatement()) {
1499 node.declaration = this.parseStatement(null);
1500 if (node.declaration.type === "VariableDeclaration")
1501 { this.checkVariableExport(exports, node.declaration.declarations); }
1502 else
1503 { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
1504 node.specifiers = [];
1505 node.source = null;
1506 } else { // export { x, y as z } [from '...']
1507 node.declaration = null;
1508 node.specifiers = this.parseExportSpecifiers(exports);
1509 if (this.eatContextual("from")) {
1510 if (this.type !== types.string) { this.unexpected(); }
1511 node.source = this.parseExprAtom();
1512 } else {
1513 for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
1514 // check for keywords used as local names
1515 var spec = list[i];
1516
1517 this.checkUnreserved(spec.local);
1518 // check if export is defined
1519 this.checkLocalExport(spec.local);
1520 }
1521
1522 node.source = null;
1523 }
1524 this.semicolon();
1525 }
1526 return this.finishNode(node, "ExportNamedDeclaration")
1527 };
1528
1529 pp$1.checkExport = function(exports, name, pos) {
1530 if (!exports) { return }
1531 if (has(exports, name))
1532 { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
1533 exports[name] = true;
1534 };
1535
1536 pp$1.checkPatternExport = function(exports, pat) {
1537 var type = pat.type;
1538 if (type === "Identifier")
1539 { this.checkExport(exports, pat.name, pat.start); }
1540 else if (type === "ObjectPattern")
1541 { for (var i = 0, list = pat.properties; i < list.length; i += 1)
1542 {
1543 var prop = list[i];
1544
1545 this.checkPatternExport(exports, prop);
1546 } }
1547 else if (type === "ArrayPattern")
1548 { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
1549 var elt = list$1[i$1];
1550
1551 if (elt) { this.checkPatternExport(exports, elt); }
1552 } }
1553 else if (type === "Property")
1554 { this.checkPatternExport(exports, pat.value); }
1555 else if (type === "AssignmentPattern")
1556 { this.checkPatternExport(exports, pat.left); }
1557 else if (type === "RestElement")
1558 { this.checkPatternExport(exports, pat.argument); }
1559 else if (type === "ParenthesizedExpression")
1560 { this.checkPatternExport(exports, pat.expression); }
1561 };
1562
1563 pp$1.checkVariableExport = function(exports, decls) {
1564 if (!exports) { return }
1565 for (var i = 0, list = decls; i < list.length; i += 1)
1566 {
1567 var decl = list[i];
1568
1569 this.checkPatternExport(exports, decl.id);
1570 }
1571 };
1572
1573 pp$1.shouldParseExportStatement = function() {
1574 return this.type.keyword === "var" ||
1575 this.type.keyword === "const" ||
1576 this.type.keyword === "class" ||
1577 this.type.keyword === "function" ||
1578 this.isLet() ||
1579 this.isAsyncFunction()
1580 };
1581
1582 // Parses a comma-separated list of module exports.
1583
1584 pp$1.parseExportSpecifiers = function(exports) {
1585 var nodes = [], first = true;
1586 // export { x, y as z } [from '...']
1587 this.expect(types.braceL);
1588 while (!this.eat(types.braceR)) {
1589 if (!first) {
1590 this.expect(types.comma);
1591 if (this.afterTrailingComma(types.braceR)) { break }
1592 } else { first = false; }
1593
1594 var node = this.startNode();
1595 node.local = this.parseIdent(true);
1596 node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
1597 this.checkExport(exports, node.exported.name, node.exported.start);
1598 nodes.push(this.finishNode(node, "ExportSpecifier"));
1599 }
1600 return nodes
1601 };
1602
1603 // Parses import declaration.
1604
1605 pp$1.parseImport = function(node) {
1606 this.next();
1607 // import '...'
1608 if (this.type === types.string) {
1609 node.specifiers = empty;
1610 node.source = this.parseExprAtom();
1611 } else {
1612 node.specifiers = this.parseImportSpecifiers();
1613 this.expectContextual("from");
1614 node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
1615 }
1616 this.semicolon();
1617 return this.finishNode(node, "ImportDeclaration")
1618 };
1619
1620 // Parses a comma-separated list of module imports.
1621
1622 pp$1.parseImportSpecifiers = function() {
1623 var nodes = [], first = true;
1624 if (this.type === types.name) {
1625 // import defaultObj, { x, y as z } from '...'
1626 var node = this.startNode();
1627 node.local = this.parseIdent();
1628 this.checkLVal(node.local, BIND_LEXICAL);
1629 nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
1630 if (!this.eat(types.comma)) { return nodes }
1631 }
1632 if (this.type === types.star) {
1633 var node$1 = this.startNode();
1634 this.next();
1635 this.expectContextual("as");
1636 node$1.local = this.parseIdent();
1637 this.checkLVal(node$1.local, BIND_LEXICAL);
1638 nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
1639 return nodes
1640 }
1641 this.expect(types.braceL);
1642 while (!this.eat(types.braceR)) {
1643 if (!first) {
1644 this.expect(types.comma);
1645 if (this.afterTrailingComma(types.braceR)) { break }
1646 } else { first = false; }
1647
1648 var node$2 = this.startNode();
1649 node$2.imported = this.parseIdent(true);
1650 if (this.eatContextual("as")) {
1651 node$2.local = this.parseIdent();
1652 } else {
1653 this.checkUnreserved(node$2.imported);
1654 node$2.local = node$2.imported;
1655 }
1656 this.checkLVal(node$2.local, BIND_LEXICAL);
1657 nodes.push(this.finishNode(node$2, "ImportSpecifier"));
1658 }
1659 return nodes
1660 };
1661
1662 // Set `ExpressionStatement#directive` property for directive prologues.
1663 pp$1.adaptDirectivePrologue = function(statements) {
1664 for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
1665 statements[i].directive = statements[i].expression.raw.slice(1, -1);
1666 }
1667 };
1668 pp$1.isDirectiveCandidate = function(statement) {
1669 return (
1670 statement.type === "ExpressionStatement" &&
1671 statement.expression.type === "Literal" &&
1672 typeof statement.expression.value === "string" &&
1673 // Reject parenthesized strings.
1674 (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
1675 )
1676 };
1677
1678 var pp$2 = Parser.prototype;
1679
1680 // Convert existing expression atom to assignable pattern
1681 // if possible.
1682
1683 pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {
1684 if (this.options.ecmaVersion >= 6 && node) {
1685 switch (node.type) {
1686 case "Identifier":
1687 if (this.inAsync && node.name === "await")
1688 { this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
1689 break
1690
1691 case "ObjectPattern":
1692 case "ArrayPattern":
1693 case "RestElement":
1694 break
1695
1696 case "ObjectExpression":
1697 node.type = "ObjectPattern";
1698 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1699 for (var i = 0, list = node.properties; i < list.length; i += 1) {
1700 var prop = list[i];
1701
1702 this.toAssignable(prop, isBinding);
1703 // Early error:
1704 // AssignmentRestProperty[Yield, Await] :
1705 // `...` DestructuringAssignmentTarget[Yield, Await]
1706 //
1707 // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
1708 if (
1709 prop.type === "RestElement" &&
1710 (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
1711 ) {
1712 this.raise(prop.argument.start, "Unexpected token");
1713 }
1714 }
1715 break
1716
1717 case "Property":
1718 // AssignmentProperty has type === "Property"
1719 if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
1720 this.toAssignable(node.value, isBinding);
1721 break
1722
1723 case "ArrayExpression":
1724 node.type = "ArrayPattern";
1725 if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1726 this.toAssignableList(node.elements, isBinding);
1727 break
1728
1729 case "SpreadElement":
1730 node.type = "RestElement";
1731 this.toAssignable(node.argument, isBinding);
1732 if (node.argument.type === "AssignmentPattern")
1733 { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
1734 break
1735
1736 case "AssignmentExpression":
1737 if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
1738 node.type = "AssignmentPattern";
1739 delete node.operator;
1740 this.toAssignable(node.left, isBinding);
1741 // falls through to AssignmentPattern
1742
1743 case "AssignmentPattern":
1744 break
1745
1746 case "ParenthesizedExpression":
1747 this.toAssignable(node.expression, isBinding, refDestructuringErrors);
1748 break
1749
1750 case "MemberExpression":
1751 if (!isBinding) { break }
1752
1753 default:
1754 this.raise(node.start, "Assigning to rvalue");
1755 }
1756 } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
1757 return node
1758 };
1759
1760 // Convert list of expression atoms to binding list.
1761
1762 pp$2.toAssignableList = function(exprList, isBinding) {
1763 var end = exprList.length;
1764 for (var i = 0; i < end; i++) {
1765 var elt = exprList[i];
1766 if (elt) { this.toAssignable(elt, isBinding); }
1767 }
1768 if (end) {
1769 var last = exprList[end - 1];
1770 if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
1771 { this.unexpected(last.argument.start); }
1772 }
1773 return exprList
1774 };
1775
1776 // Parses spread element.
1777
1778 pp$2.parseSpread = function(refDestructuringErrors) {
1779 var node = this.startNode();
1780 this.next();
1781 node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
1782 return this.finishNode(node, "SpreadElement")
1783 };
1784
1785 pp$2.parseRestBinding = function() {
1786 var node = this.startNode();
1787 this.next();
1788
1789 // RestElement inside of a function parameter must be an identifier
1790 if (this.options.ecmaVersion === 6 && this.type !== types.name)
1791 { this.unexpected(); }
1792
1793 node.argument = this.parseBindingAtom();
1794
1795 return this.finishNode(node, "RestElement")
1796 };
1797
1798 // Parses lvalue (assignable) atom.
1799
1800 pp$2.parseBindingAtom = function() {
1801 if (this.options.ecmaVersion >= 6) {
1802 switch (this.type) {
1803 case types.bracketL:
1804 var node = this.startNode();
1805 this.next();
1806 node.elements = this.parseBindingList(types.bracketR, true, true);
1807 return this.finishNode(node, "ArrayPattern")
1808
1809 case types.braceL:
1810 return this.parseObj(true)
1811 }
1812 }
1813 return this.parseIdent()
1814 };
1815
1816 pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
1817 var elts = [], first = true;
1818 while (!this.eat(close)) {
1819 if (first) { first = false; }
1820 else { this.expect(types.comma); }
1821 if (allowEmpty && this.type === types.comma) {
1822 elts.push(null);
1823 } else if (allowTrailingComma && this.afterTrailingComma(close)) {
1824 break
1825 } else if (this.type === types.ellipsis) {
1826 var rest = this.parseRestBinding();
1827 this.parseBindingListItem(rest);
1828 elts.push(rest);
1829 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
1830 this.expect(close);
1831 break
1832 } else {
1833 var elem = this.parseMaybeDefault(this.start, this.startLoc);
1834 this.parseBindingListItem(elem);
1835 elts.push(elem);
1836 }
1837 }
1838 return elts
1839 };
1840
1841 pp$2.parseBindingListItem = function(param) {
1842 return param
1843 };
1844
1845 // Parses assignment pattern around given atom if possible.
1846
1847 pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
1848 left = left || this.parseBindingAtom();
1849 if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
1850 var node = this.startNodeAt(startPos, startLoc);
1851 node.left = left;
1852 node.right = this.parseMaybeAssign();
1853 return this.finishNode(node, "AssignmentPattern")
1854 };
1855
1856 // Verify that a node is an lval — something that can be assigned
1857 // to.
1858 // bindingType can be either:
1859 // 'var' indicating that the lval creates a 'var' binding
1860 // 'let' indicating that the lval creates a lexical ('let' or 'const') binding
1861 // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
1862
1863 pp$2.checkLVal = function(expr, bindingType, checkClashes) {
1864 if ( bindingType === void 0 ) bindingType = BIND_NONE;
1865
1866 switch (expr.type) {
1867 case "Identifier":
1868 if (bindingType === BIND_LEXICAL && expr.name === "let")
1869 { this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
1870 if (this.strict && this.reservedWordsStrictBind.test(expr.name))
1871 { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
1872 if (checkClashes) {
1873 if (has(checkClashes, expr.name))
1874 { this.raiseRecoverable(expr.start, "Argument name clash"); }
1875 checkClashes[expr.name] = true;
1876 }
1877 if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
1878 break
1879
1880 case "MemberExpression":
1881 if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); }
1882 break
1883
1884 case "ObjectPattern":
1885 for (var i = 0, list = expr.properties; i < list.length; i += 1)
1886 {
1887 var prop = list[i];
1888
1889 this.checkLVal(prop, bindingType, checkClashes);
1890 }
1891 break
1892
1893 case "Property":
1894 // AssignmentProperty has type === "Property"
1895 this.checkLVal(expr.value, bindingType, checkClashes);
1896 break
1897
1898 case "ArrayPattern":
1899 for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
1900 var elem = list$1[i$1];
1901
1902 if (elem) { this.checkLVal(elem, bindingType, checkClashes); }
1903 }
1904 break
1905
1906 case "AssignmentPattern":
1907 this.checkLVal(expr.left, bindingType, checkClashes);
1908 break
1909
1910 case "RestElement":
1911 this.checkLVal(expr.argument, bindingType, checkClashes);
1912 break
1913
1914 case "ParenthesizedExpression":
1915 this.checkLVal(expr.expression, bindingType, checkClashes);
1916 break
1917
1918 default:
1919 this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
1920 }
1921 };
1922
1923 // A recursive descent parser operates by defining functions for all
1924
1925 var pp$3 = Parser.prototype;
1926
1927 // Check if property name clashes with already added.
1928 // Object/class getters and setters are not allowed to clash —
1929 // either with each other or with an init property — and in
1930 // strict mode, init properties are also not allowed to be repeated.
1931
1932 pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
1933 if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
1934 { return }
1935 if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
1936 { return }
1937 var key = prop.key;
1938 var name;
1939 switch (key.type) {
1940 case "Identifier": name = key.name; break
1941 case "Literal": name = String(key.value); break
1942 default: return
1943 }
1944 var kind = prop.kind;
1945 if (this.options.ecmaVersion >= 6) {
1946 if (name === "__proto__" && kind === "init") {
1947 if (propHash.proto) {
1948 if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }
1949 // Backwards-compat kludge. Can be removed in version 6.0
1950 else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
1951 }
1952 propHash.proto = true;
1953 }
1954 return
1955 }
1956 name = "$" + name;
1957 var other = propHash[name];
1958 if (other) {
1959 var redefinition;
1960 if (kind === "init") {
1961 redefinition = this.strict && other.init || other.get || other.set;
1962 } else {
1963 redefinition = other.init || other[kind];
1964 }
1965 if (redefinition)
1966 { this.raiseRecoverable(key.start, "Redefinition of property"); }
1967 } else {
1968 other = propHash[name] = {
1969 init: false,
1970 get: false,
1971 set: false
1972 };
1973 }
1974 other[kind] = true;
1975 };
1976
1977 // ### Expression parsing
1978
1979 // These nest, from the most general expression type at the top to
1980 // 'atomic', nondivisible expression types at the bottom. Most of
1981 // the functions will simply let the function(s) below them parse,
1982 // and, *if* the syntactic construct they handle is present, wrap
1983 // the AST node that the inner parser gave them in another node.
1984
1985 // Parse a full expression. The optional arguments are used to
1986 // forbid the `in` operator (in for loops initalization expressions)
1987 // and provide reference for storing '=' operator inside shorthand
1988 // property assignment in contexts where both object expression
1989 // and object pattern might appear (so it's possible to raise
1990 // delayed syntax error at correct position).
1991
1992 pp$3.parseExpression = function(noIn, refDestructuringErrors) {
1993 var startPos = this.start, startLoc = this.startLoc;
1994 var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
1995 if (this.type === types.comma) {
1996 var node = this.startNodeAt(startPos, startLoc);
1997 node.expressions = [expr];
1998 while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
1999 return this.finishNode(node, "SequenceExpression")
2000 }
2001 return expr
2002 };
2003
2004 // Parse an assignment expression. This includes applications of
2005 // operators like `+=`.
2006
2007 pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
2008 if (this.isContextual("yield")) {
2009 if (this.inGenerator) { return this.parseYield(noIn) }
2010 // The tokenizer will assume an expression is allowed after
2011 // `yield`, but this isn't that kind of yield
2012 else { this.exprAllowed = false; }
2013 }
2014
2015 var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldShorthandAssign = -1;
2016 if (refDestructuringErrors) {
2017 oldParenAssign = refDestructuringErrors.parenthesizedAssign;
2018 oldTrailingComma = refDestructuringErrors.trailingComma;
2019 oldShorthandAssign = refDestructuringErrors.shorthandAssign;
2020 refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.shorthandAssign = -1;
2021 } else {
2022 refDestructuringErrors = new DestructuringErrors;
2023 ownDestructuringErrors = true;
2024 }
2025
2026 var startPos = this.start, startLoc = this.startLoc;
2027 if (this.type === types.parenL || this.type === types.name)
2028 { this.potentialArrowAt = this.start; }
2029 var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
2030 if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
2031 if (this.type.isAssign) {
2032 var node = this.startNodeAt(startPos, startLoc);
2033 node.operator = this.value;
2034 node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
2035 if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }
2036 refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly
2037 this.checkLVal(left);
2038 this.next();
2039 node.right = this.parseMaybeAssign(noIn);
2040 return this.finishNode(node, "AssignmentExpression")
2041 } else {
2042 if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
2043 }
2044 if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
2045 if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
2046 if (oldShorthandAssign > -1) { refDestructuringErrors.shorthandAssign = oldShorthandAssign; }
2047 return left
2048 };
2049
2050 // Parse a ternary conditional (`?:`) operator.
2051
2052 pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
2053 var startPos = this.start, startLoc = this.startLoc;
2054 var expr = this.parseExprOps(noIn, refDestructuringErrors);
2055 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2056 if (this.eat(types.question)) {
2057 var node = this.startNodeAt(startPos, startLoc);
2058 node.test = expr;
2059 node.consequent = this.parseMaybeAssign();
2060 this.expect(types.colon);
2061 node.alternate = this.parseMaybeAssign(noIn);
2062 return this.finishNode(node, "ConditionalExpression")
2063 }
2064 return expr
2065 };
2066
2067 // Start the precedence parser.
2068
2069 pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
2070 var startPos = this.start, startLoc = this.startLoc;
2071 var expr = this.parseMaybeUnary(refDestructuringErrors, false);
2072 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2073 return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
2074 };
2075
2076 // Parse binary operators with the operator precedence parsing
2077 // algorithm. `left` is the left-hand side of the operator.
2078 // `minPrec` provides context that allows the function to stop and
2079 // defer further parser to one of its callers when it encounters an
2080 // operator that has a lower precedence than the set it is parsing.
2081
2082 pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
2083 var prec = this.type.binop;
2084 if (prec != null && (!noIn || this.type !== types._in)) {
2085 if (prec > minPrec) {
2086 var logical = this.type === types.logicalOR || this.type === types.logicalAND;
2087 var op = this.value;
2088 this.next();
2089 var startPos = this.start, startLoc = this.startLoc;
2090 var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
2091 var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);
2092 return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
2093 }
2094 }
2095 return left
2096 };
2097
2098 pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
2099 var node = this.startNodeAt(startPos, startLoc);
2100 node.left = left;
2101 node.operator = op;
2102 node.right = right;
2103 return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
2104 };
2105
2106 // Parse unary operators, both prefix and postfix.
2107
2108 pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
2109 var startPos = this.start, startLoc = this.startLoc, expr;
2110 if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
2111 expr = this.parseAwait();
2112 sawUnary = true;
2113 } else if (this.type.prefix) {
2114 var node = this.startNode(), update = this.type === types.incDec;
2115 node.operator = this.value;
2116 node.prefix = true;
2117 this.next();
2118 node.argument = this.parseMaybeUnary(null, true);
2119 this.checkExpressionErrors(refDestructuringErrors, true);
2120 if (update) { this.checkLVal(node.argument); }
2121 else if (this.strict && node.operator === "delete" &&
2122 node.argument.type === "Identifier")
2123 { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
2124 else { sawUnary = true; }
2125 expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
2126 } else {
2127 expr = this.parseExprSubscripts(refDestructuringErrors);
2128 if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
2129 while (this.type.postfix && !this.canInsertSemicolon()) {
2130 var node$1 = this.startNodeAt(startPos, startLoc);
2131 node$1.operator = this.value;
2132 node$1.prefix = false;
2133 node$1.argument = expr;
2134 this.checkLVal(expr);
2135 this.next();
2136 expr = this.finishNode(node$1, "UpdateExpression");
2137 }
2138 }
2139
2140 if (!sawUnary && this.eat(types.starstar))
2141 { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
2142 else
2143 { return expr }
2144 };
2145
2146 // Parse call, dot, and `[]`-subscript expressions.
2147
2148 pp$3.parseExprSubscripts = function(refDestructuringErrors) {
2149 var startPos = this.start, startLoc = this.startLoc;
2150 var expr = this.parseExprAtom(refDestructuringErrors);
2151 var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
2152 if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }
2153 var result = this.parseSubscripts(expr, startPos, startLoc);
2154 if (refDestructuringErrors && result.type === "MemberExpression") {
2155 if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
2156 if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
2157 }
2158 return result
2159 };
2160
2161 pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
2162 var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
2163 this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async";
2164 while (true) {
2165 var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow);
2166 if (element === base || element.type === "ArrowFunctionExpression") { return element }
2167 base = element;
2168 }
2169 };
2170
2171 pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow) {
2172 var computed = this.eat(types.bracketL);
2173 if (computed || this.eat(types.dot)) {
2174 var node = this.startNodeAt(startPos, startLoc);
2175 node.object = base;
2176 node.property = computed ? this.parseExpression() : this.parseIdent(true);
2177 node.computed = !!computed;
2178 if (computed) { this.expect(types.bracketR); }
2179 base = this.finishNode(node, "MemberExpression");
2180 } else if (!noCalls && this.eat(types.parenL)) {
2181 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2182 this.yieldPos = 0;
2183 this.awaitPos = 0;
2184 this.awaitIdentPos = 0;
2185 var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8 && base.type !== "Import", false, refDestructuringErrors);
2186 if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2187 this.checkPatternErrors(refDestructuringErrors, false);
2188 this.checkYieldAwaitInDefaultParams();
2189 if (this.awaitIdentPos > 0)
2190 { this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
2191 this.yieldPos = oldYieldPos;
2192 this.awaitPos = oldAwaitPos;
2193 this.awaitIdentPos = oldAwaitIdentPos;
2194 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true)
2195 }
2196 this.checkExpressionErrors(refDestructuringErrors, true);
2197 this.yieldPos = oldYieldPos || this.yieldPos;
2198 this.awaitPos = oldAwaitPos || this.awaitPos;
2199 this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
2200 var node$1 = this.startNodeAt(startPos, startLoc);
2201 node$1.callee = base;
2202 node$1.arguments = exprList;
2203 if (node$1.callee.type === "Import") {
2204 if (node$1.arguments.length !== 1) {
2205 this.raise(node$1.start, "import() requires exactly one argument");
2206 }
2207
2208 var importArg = node$1.arguments[0];
2209 if (importArg && importArg.type === "SpreadElement") {
2210 this.raise(importArg.start, "... is not allowed in import()");
2211 }
2212 }
2213 base = this.finishNode(node$1, "CallExpression");
2214 } else if (this.type === types.backQuote) {
2215 var node$2 = this.startNodeAt(startPos, startLoc);
2216 node$2.tag = base;
2217 node$2.quasi = this.parseTemplate({isTagged: true});
2218 base = this.finishNode(node$2, "TaggedTemplateExpression");
2219 }
2220 return base
2221 };
2222
2223 // Parse an atomic expression — either a single token that is an
2224 // expression, an expression started by a keyword like `function` or
2225 // `new`, or an expression wrapped in punctuation like `()`, `[]`,
2226 // or `{}`.
2227
2228 pp$3.parseExprAtom = function(refDestructuringErrors) {
2229 // If a division operator appears in an expression position, the
2230 // tokenizer got confused, and we force it to read a regexp instead.
2231 if (this.type === types.slash) { this.readRegexp(); }
2232
2233 var node, canBeArrow = this.potentialArrowAt === this.start;
2234 switch (this.type) {
2235 case types._super:
2236 if (!this.allowSuper)
2237 { this.raise(this.start, "'super' keyword outside a method"); }
2238 node = this.startNode();
2239 this.next();
2240 if (this.type === types.parenL && !this.allowDirectSuper)
2241 { this.raise(node.start, "super() call outside constructor of a subclass"); }
2242 // The `super` keyword can appear at below:
2243 // SuperProperty:
2244 // super [ Expression ]
2245 // super . IdentifierName
2246 // SuperCall:
2247 // super Arguments
2248 if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
2249 { this.unexpected(); }
2250 return this.finishNode(node, "Super")
2251
2252 case types._this:
2253 node = this.startNode();
2254 this.next();
2255 return this.finishNode(node, "ThisExpression")
2256
2257 case types.name:
2258 var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
2259 var id = this.parseIdent(false);
2260 if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
2261 { return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) }
2262 if (canBeArrow && !this.canInsertSemicolon()) {
2263 if (this.eat(types.arrow))
2264 { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
2265 if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
2266 id = this.parseIdent(false);
2267 if (this.canInsertSemicolon() || !this.eat(types.arrow))
2268 { this.unexpected(); }
2269 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
2270 }
2271 }
2272 return id
2273
2274 case types.regexp:
2275 var value = this.value;
2276 node = this.parseLiteral(value.value);
2277 node.regex = {pattern: value.pattern, flags: value.flags};
2278 return node
2279
2280 case types.num: case types.string:
2281 return this.parseLiteral(this.value)
2282
2283 case types._null: case types._true: case types._false:
2284 node = this.startNode();
2285 node.value = this.type === types._null ? null : this.type === types._true;
2286 node.raw = this.type.keyword;
2287 this.next();
2288 return this.finishNode(node, "Literal")
2289
2290 case types.parenL:
2291 var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
2292 if (refDestructuringErrors) {
2293 if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
2294 { refDestructuringErrors.parenthesizedAssign = start; }
2295 if (refDestructuringErrors.parenthesizedBind < 0)
2296 { refDestructuringErrors.parenthesizedBind = start; }
2297 }
2298 return expr
2299
2300 case types.bracketL:
2301 node = this.startNode();
2302 this.next();
2303 node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
2304 return this.finishNode(node, "ArrayExpression")
2305
2306 case types.braceL:
2307 return this.parseObj(false, refDestructuringErrors)
2308
2309 case types._function:
2310 node = this.startNode();
2311 this.next();
2312 return this.parseFunction(node, 0)
2313
2314 case types._class:
2315 return this.parseClass(this.startNode(), false)
2316
2317 case types._new:
2318 return this.parseNew()
2319
2320 case types.backQuote:
2321 return this.parseTemplate()
2322
2323 case types._import:
2324 if (this.options.ecmaVersion > 10) {
2325 return this.parseDynamicImport()
2326 } else {
2327 return this.unexpected()
2328 }
2329
2330 default:
2331 this.unexpected();
2332 }
2333 };
2334
2335 pp$3.parseDynamicImport = function() {
2336 var node = this.startNode();
2337 this.next();
2338 if (this.type !== types.parenL) {
2339 this.unexpected();
2340 }
2341 return this.finishNode(node, "Import")
2342 };
2343
2344 pp$3.parseLiteral = function(value) {
2345 var node = this.startNode();
2346 node.value = value;
2347 node.raw = this.input.slice(this.start, this.end);
2348 if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1); }
2349 this.next();
2350 return this.finishNode(node, "Literal")
2351 };
2352
2353 pp$3.parseParenExpression = function() {
2354 this.expect(types.parenL);
2355 var val = this.parseExpression();
2356 this.expect(types.parenR);
2357 return val
2358 };
2359
2360 pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
2361 var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
2362 if (this.options.ecmaVersion >= 6) {
2363 this.next();
2364
2365 var innerStartPos = this.start, innerStartLoc = this.startLoc;
2366 var exprList = [], first = true, lastIsComma = false;
2367 var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
2368 this.yieldPos = 0;
2369 this.awaitPos = 0;
2370 // Do not save awaitIdentPos to allow checking awaits nested in parameters
2371 while (this.type !== types.parenR) {
2372 first ? first = false : this.expect(types.comma);
2373 if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) {
2374 lastIsComma = true;
2375 break
2376 } else if (this.type === types.ellipsis) {
2377 spreadStart = this.start;
2378 exprList.push(this.parseParenItem(this.parseRestBinding()));
2379 if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
2380 break
2381 } else {
2382 exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
2383 }
2384 }
2385 var innerEndPos = this.start, innerEndLoc = this.startLoc;
2386 this.expect(types.parenR);
2387
2388 if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
2389 this.checkPatternErrors(refDestructuringErrors, false);
2390 this.checkYieldAwaitInDefaultParams();
2391 this.yieldPos = oldYieldPos;
2392 this.awaitPos = oldAwaitPos;
2393 return this.parseParenArrowList(startPos, startLoc, exprList)
2394 }
2395
2396 if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
2397 if (spreadStart) { this.unexpected(spreadStart); }
2398 this.checkExpressionErrors(refDestructuringErrors, true);
2399 this.yieldPos = oldYieldPos || this.yieldPos;
2400 this.awaitPos = oldAwaitPos || this.awaitPos;
2401
2402 if (exprList.length > 1) {
2403 val = this.startNodeAt(innerStartPos, innerStartLoc);
2404 val.expressions = exprList;
2405 this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
2406 } else {
2407 val = exprList[0];
2408 }
2409 } else {
2410 val = this.parseParenExpression();
2411 }
2412
2413 if (this.options.preserveParens) {
2414 var par = this.startNodeAt(startPos, startLoc);
2415 par.expression = val;
2416 return this.finishNode(par, "ParenthesizedExpression")
2417 } else {
2418 return val
2419 }
2420 };
2421
2422 pp$3.parseParenItem = function(item) {
2423 return item
2424 };
2425
2426 pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
2427 return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
2428 };
2429
2430 // New's precedence is slightly tricky. It must allow its argument to
2431 // be a `[]` or dot subscript expression, but not a call — at least,
2432 // not without wrapping it in parentheses. Thus, it uses the noCalls
2433 // argument to parseSubscripts to prevent it from consuming the
2434 // argument list.
2435
2436 var empty$1 = [];
2437
2438 pp$3.parseNew = function() {
2439 var node = this.startNode();
2440 var meta = this.parseIdent(true);
2441 if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
2442 node.meta = meta;
2443 var containsEsc = this.containsEsc;
2444 node.property = this.parseIdent(true);
2445 if (node.property.name !== "target" || containsEsc)
2446 { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); }
2447 if (!this.inNonArrowFunction())
2448 { this.raiseRecoverable(node.start, "new.target can only be used in functions"); }
2449 return this.finishNode(node, "MetaProperty")
2450 }
2451 var startPos = this.start, startLoc = this.startLoc;
2452 node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
2453 if (this.options.ecmaVersion > 10 && node.callee.type === "Import") {
2454 this.raise(node.callee.start, "Cannot use new with import(...)");
2455 }
2456 if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8 && node.callee.type !== "Import", false); }
2457 else { node.arguments = empty$1; }
2458 return this.finishNode(node, "NewExpression")
2459 };
2460
2461 // Parse template expression.
2462
2463 pp$3.parseTemplateElement = function(ref) {
2464 var isTagged = ref.isTagged;
2465
2466 var elem = this.startNode();
2467 if (this.type === types.invalidTemplate) {
2468 if (!isTagged) {
2469 this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
2470 }
2471 elem.value = {
2472 raw: this.value,
2473 cooked: null
2474 };
2475 } else {
2476 elem.value = {
2477 raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
2478 cooked: this.value
2479 };
2480 }
2481 this.next();
2482 elem.tail = this.type === types.backQuote;
2483 return this.finishNode(elem, "TemplateElement")
2484 };
2485
2486 pp$3.parseTemplate = function(ref) {
2487 if ( ref === void 0 ) ref = {};
2488 var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
2489
2490 var node = this.startNode();
2491 this.next();
2492 node.expressions = [];
2493 var curElt = this.parseTemplateElement({isTagged: isTagged});
2494 node.quasis = [curElt];
2495 while (!curElt.tail) {
2496 if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); }
2497 this.expect(types.dollarBraceL);
2498 node.expressions.push(this.parseExpression());
2499 this.expect(types.braceR);
2500 node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
2501 }
2502 this.next();
2503 return this.finishNode(node, "TemplateLiteral")
2504 };
2505
2506 pp$3.isAsyncProp = function(prop) {
2507 return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
2508 (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&
2509 !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
2510 };
2511
2512 // Parse an object literal or binding pattern.
2513
2514 pp$3.parseObj = function(isPattern, refDestructuringErrors) {
2515 var node = this.startNode(), first = true, propHash = {};
2516 node.properties = [];
2517 this.next();
2518 while (!this.eat(types.braceR)) {
2519 if (!first) {
2520 this.expect(types.comma);
2521 if (this.afterTrailingComma(types.braceR)) { break }
2522 } else { first = false; }
2523
2524 var prop = this.parseProperty(isPattern, refDestructuringErrors);
2525 if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
2526 node.properties.push(prop);
2527 }
2528 return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
2529 };
2530
2531 pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
2532 var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
2533 if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {
2534 if (isPattern) {
2535 prop.argument = this.parseIdent(false);
2536 if (this.type === types.comma) {
2537 this.raise(this.start, "Comma is not permitted after the rest element");
2538 }
2539 return this.finishNode(prop, "RestElement")
2540 }
2541 // To disallow parenthesized identifier via `this.toAssignable()`.
2542 if (this.type === types.parenL && refDestructuringErrors) {
2543 if (refDestructuringErrors.parenthesizedAssign < 0) {
2544 refDestructuringErrors.parenthesizedAssign = this.start;
2545 }
2546 if (refDestructuringErrors.parenthesizedBind < 0) {
2547 refDestructuringErrors.parenthesizedBind = this.start;
2548 }
2549 }
2550 // Parse argument.
2551 prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
2552 // To disallow trailing comma via `this.toAssignable()`.
2553 if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
2554 refDestructuringErrors.trailingComma = this.start;
2555 }
2556 // Finish
2557 return this.finishNode(prop, "SpreadElement")
2558 }
2559 if (this.options.ecmaVersion >= 6) {
2560 prop.method = false;
2561 prop.shorthand = false;
2562 if (isPattern || refDestructuringErrors) {
2563 startPos = this.start;
2564 startLoc = this.startLoc;
2565 }
2566 if (!isPattern)
2567 { isGenerator = this.eat(types.star); }
2568 }
2569 var containsEsc = this.containsEsc;
2570 this.parsePropertyName(prop);
2571 if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
2572 isAsync = true;
2573 isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
2574 this.parsePropertyName(prop, refDestructuringErrors);
2575 } else {
2576 isAsync = false;
2577 }
2578 this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
2579 return this.finishNode(prop, "Property")
2580 };
2581
2582 pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
2583 if ((isGenerator || isAsync) && this.type === types.colon)
2584 { this.unexpected(); }
2585
2586 if (this.eat(types.colon)) {
2587 prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
2588 prop.kind = "init";
2589 } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
2590 if (isPattern) { this.unexpected(); }
2591 prop.kind = "init";
2592 prop.method = true;
2593 prop.value = this.parseMethod(isGenerator, isAsync);
2594 } else if (!isPattern && !containsEsc &&
2595 this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
2596 (prop.key.name === "get" || prop.key.name === "set") &&
2597 (this.type !== types.comma && this.type !== types.braceR)) {
2598 if (isGenerator || isAsync) { this.unexpected(); }
2599 prop.kind = prop.key.name;
2600 this.parsePropertyName(prop);
2601 prop.value = this.parseMethod(false);
2602 var paramCount = prop.kind === "get" ? 0 : 1;
2603 if (prop.value.params.length !== paramCount) {
2604 var start = prop.value.start;
2605 if (prop.kind === "get")
2606 { this.raiseRecoverable(start, "getter should have no params"); }
2607 else
2608 { this.raiseRecoverable(start, "setter should have exactly one param"); }
2609 } else {
2610 if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
2611 { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
2612 }
2613 } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
2614 if (isGenerator || isAsync) { this.unexpected(); }
2615 this.checkUnreserved(prop.key);
2616 if (prop.key.name === "await" && !this.awaitIdentPos)
2617 { this.awaitIdentPos = startPos; }
2618 prop.kind = "init";
2619 if (isPattern) {
2620 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2621 } else if (this.type === types.eq && refDestructuringErrors) {
2622 if (refDestructuringErrors.shorthandAssign < 0)
2623 { refDestructuringErrors.shorthandAssign = this.start; }
2624 prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
2625 } else {
2626 prop.value = prop.key;
2627 }
2628 prop.shorthand = true;
2629 } else { this.unexpected(); }
2630 };
2631
2632 pp$3.parsePropertyName = function(prop) {
2633 if (this.options.ecmaVersion >= 6) {
2634 if (this.eat(types.bracketL)) {
2635 prop.computed = true;
2636 prop.key = this.parseMaybeAssign();
2637 this.expect(types.bracketR);
2638 return prop.key
2639 } else {
2640 prop.computed = false;
2641 }
2642 }
2643 return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)
2644 };
2645
2646 // Initialize empty function node.
2647
2648 pp$3.initFunction = function(node) {
2649 node.id = null;
2650 if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
2651 if (this.options.ecmaVersion >= 8) { node.async = false; }
2652 };
2653
2654 // Parse object or class method.
2655
2656 pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
2657 var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2658
2659 this.initFunction(node);
2660 if (this.options.ecmaVersion >= 6)
2661 { node.generator = isGenerator; }
2662 if (this.options.ecmaVersion >= 8)
2663 { node.async = !!isAsync; }
2664
2665 this.yieldPos = 0;
2666 this.awaitPos = 0;
2667 this.awaitIdentPos = 0;
2668 this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
2669
2670 this.expect(types.parenL);
2671 node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
2672 this.checkYieldAwaitInDefaultParams();
2673 this.parseFunctionBody(node, false, true);
2674
2675 this.yieldPos = oldYieldPos;
2676 this.awaitPos = oldAwaitPos;
2677 this.awaitIdentPos = oldAwaitIdentPos;
2678 return this.finishNode(node, "FunctionExpression")
2679 };
2680
2681 // Parse arrow function expression with given parameters.
2682
2683 pp$3.parseArrowExpression = function(node, params, isAsync) {
2684 var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
2685
2686 this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
2687 this.initFunction(node);
2688 if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
2689
2690 this.yieldPos = 0;
2691 this.awaitPos = 0;
2692 this.awaitIdentPos = 0;
2693
2694 node.params = this.toAssignableList(params, true);
2695 this.parseFunctionBody(node, true, false);
2696
2697 this.yieldPos = oldYieldPos;
2698 this.awaitPos = oldAwaitPos;
2699 this.awaitIdentPos = oldAwaitIdentPos;
2700 return this.finishNode(node, "ArrowFunctionExpression")
2701 };
2702
2703 // Parse function body and check parameters.
2704
2705 pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) {
2706 var isExpression = isArrowFunction && this.type !== types.braceL;
2707 var oldStrict = this.strict, useStrict = false;
2708
2709 if (isExpression) {
2710 node.body = this.parseMaybeAssign();
2711 node.expression = true;
2712 this.checkParams(node, false);
2713 } else {
2714 var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
2715 if (!oldStrict || nonSimple) {
2716 useStrict = this.strictDirective(this.end);
2717 // If this is a strict mode function, verify that argument names
2718 // are not repeated, and it does not try to bind the words `eval`
2719 // or `arguments`.
2720 if (useStrict && nonSimple)
2721 { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
2722 }
2723 // Start a new scope with regard to labels and the `inFunction`
2724 // flag (restore them to their old value afterwards).
2725 var oldLabels = this.labels;
2726 this.labels = [];
2727 if (useStrict) { this.strict = true; }
2728
2729 // Add the params to varDeclaredNames to ensure that an error is thrown
2730 // if a let/const declaration in the function clashes with one of the params.
2731 this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
2732 node.body = this.parseBlock(false);
2733 node.expression = false;
2734 this.adaptDirectivePrologue(node.body.body);
2735 this.labels = oldLabels;
2736 }
2737 this.exitScope();
2738
2739 // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
2740 if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); }
2741 this.strict = oldStrict;
2742 };
2743
2744 pp$3.isSimpleParamList = function(params) {
2745 for (var i = 0, list = params; i < list.length; i += 1)
2746 {
2747 var param = list[i];
2748
2749 if (param.type !== "Identifier") { return false
2750 } }
2751 return true
2752 };
2753
2754 // Checks function params for various disallowed patterns such as using "eval"
2755 // or "arguments" and duplicate parameters.
2756
2757 pp$3.checkParams = function(node, allowDuplicates) {
2758 var nameHash = {};
2759 for (var i = 0, list = node.params; i < list.length; i += 1)
2760 {
2761 var param = list[i];
2762
2763 this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash);
2764 }
2765 };
2766
2767 // Parses a comma-separated list of expressions, and returns them as
2768 // an array. `close` is the token type that ends the list, and
2769 // `allowEmpty` can be turned on to allow subsequent commas with
2770 // nothing in between them to be parsed as `null` (which is needed
2771 // for array literals).
2772
2773 pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
2774 var elts = [], first = true;
2775 while (!this.eat(close)) {
2776 if (!first) {
2777 this.expect(types.comma);
2778 if (allowTrailingComma && this.afterTrailingComma(close)) { break }
2779 } else { first = false; }
2780
2781 var elt = (void 0);
2782 if (allowEmpty && this.type === types.comma)
2783 { elt = null; }
2784 else if (this.type === types.ellipsis) {
2785 elt = this.parseSpread(refDestructuringErrors);
2786 if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0)
2787 { refDestructuringErrors.trailingComma = this.start; }
2788 } else {
2789 elt = this.parseMaybeAssign(false, refDestructuringErrors);
2790 }
2791 elts.push(elt);
2792 }
2793 return elts
2794 };
2795
2796 pp$3.checkUnreserved = function(ref) {
2797 var start = ref.start;
2798 var end = ref.end;
2799 var name = ref.name;
2800
2801 if (this.inGenerator && name === "yield")
2802 { this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
2803 if (this.inAsync && name === "await")
2804 { this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
2805 if (this.keywords.test(name))
2806 { this.raise(start, ("Unexpected keyword '" + name + "'")); }
2807 if (this.options.ecmaVersion < 6 &&
2808 this.input.slice(start, end).indexOf("\\") !== -1) { return }
2809 var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
2810 if (re.test(name)) {
2811 if (!this.inAsync && name === "await")
2812 { this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
2813 this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
2814 }
2815 };
2816
2817 // Parse the next token as an identifier. If `liberal` is true (used
2818 // when parsing properties), it will also convert keywords into
2819 // identifiers.
2820
2821 pp$3.parseIdent = function(liberal, isBinding) {
2822 var node = this.startNode();
2823 if (liberal && this.options.allowReserved === "never") { liberal = false; }
2824 if (this.type === types.name) {
2825 node.name = this.value;
2826 } else if (this.type.keyword) {
2827 node.name = this.type.keyword;
2828
2829 // To fix https://github.com/acornjs/acorn/issues/575
2830 // `class` and `function` keywords push new context into this.context.
2831 // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
2832 // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
2833 if ((node.name === "class" || node.name === "function") &&
2834 (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
2835 this.context.pop();
2836 }
2837 } else {
2838 this.unexpected();
2839 }
2840 this.next();
2841 this.finishNode(node, "Identifier");
2842 if (!liberal) {
2843 this.checkUnreserved(node);
2844 if (node.name === "await" && !this.awaitIdentPos)
2845 { this.awaitIdentPos = node.start; }
2846 }
2847 return node
2848 };
2849
2850 // Parses yield expression inside generator.
2851
2852 pp$3.parseYield = function(noIn) {
2853 if (!this.yieldPos) { this.yieldPos = this.start; }
2854
2855 var node = this.startNode();
2856 this.next();
2857 if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {
2858 node.delegate = false;
2859 node.argument = null;
2860 } else {
2861 node.delegate = this.eat(types.star);
2862 node.argument = this.parseMaybeAssign(noIn);
2863 }
2864 return this.finishNode(node, "YieldExpression")
2865 };
2866
2867 pp$3.parseAwait = function() {
2868 if (!this.awaitPos) { this.awaitPos = this.start; }
2869
2870 var node = this.startNode();
2871 this.next();
2872 node.argument = this.parseMaybeUnary(null, true);
2873 return this.finishNode(node, "AwaitExpression")
2874 };
2875
2876 var pp$4 = Parser.prototype;
2877
2878 // This function is used to raise exceptions on parse errors. It
2879 // takes an offset integer (into the current `input`) to indicate
2880 // the location of the error, attaches the position to the end
2881 // of the error message, and then raises a `SyntaxError` with that
2882 // message.
2883
2884 pp$4.raise = function(pos, message) {
2885 var loc = getLineInfo(this.input, pos);
2886 message += " (" + loc.line + ":" + loc.column + ")";
2887 var err = new SyntaxError(message);
2888 err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
2889 throw err
2890 };
2891
2892 pp$4.raiseRecoverable = pp$4.raise;
2893
2894 pp$4.curPosition = function() {
2895 if (this.options.locations) {
2896 return new Position(this.curLine, this.pos - this.lineStart)
2897 }
2898 };
2899
2900 var pp$5 = Parser.prototype;
2901
2902 var Scope = function Scope(flags) {
2903 this.flags = flags;
2904 // A list of var-declared names in the current lexical scope
2905 this.var = [];
2906 // A list of lexically-declared names in the current lexical scope
2907 this.lexical = [];
2908 // A list of lexically-declared FunctionDeclaration names in the current lexical scope
2909 this.functions = [];
2910 };
2911
2912 // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
2913
2914 pp$5.enterScope = function(flags) {
2915 this.scopeStack.push(new Scope(flags));
2916 };
2917
2918 pp$5.exitScope = function() {
2919 this.scopeStack.pop();
2920 };
2921
2922 // The spec says:
2923 // > At the top level of a function, or script, function declarations are
2924 // > treated like var declarations rather than like lexical declarations.
2925 pp$5.treatFunctionsAsVarInScope = function(scope) {
2926 return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
2927 };
2928
2929 pp$5.declareName = function(name, bindingType, pos) {
2930 var redeclared = false;
2931 if (bindingType === BIND_LEXICAL) {
2932 var scope = this.currentScope();
2933 redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
2934 scope.lexical.push(name);
2935 if (this.inModule && (scope.flags & SCOPE_TOP))
2936 { delete this.undefinedExports[name]; }
2937 } else if (bindingType === BIND_SIMPLE_CATCH) {
2938 var scope$1 = this.currentScope();
2939 scope$1.lexical.push(name);
2940 } else if (bindingType === BIND_FUNCTION) {
2941 var scope$2 = this.currentScope();
2942 if (this.treatFunctionsAsVar)
2943 { redeclared = scope$2.lexical.indexOf(name) > -1; }
2944 else
2945 { redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
2946 scope$2.functions.push(name);
2947 } else {
2948 for (var i = this.scopeStack.length - 1; i >= 0; --i) {
2949 var scope$3 = this.scopeStack[i];
2950 if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
2951 !this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
2952 redeclared = true;
2953 break
2954 }
2955 scope$3.var.push(name);
2956 if (this.inModule && (scope$3.flags & SCOPE_TOP))
2957 { delete this.undefinedExports[name]; }
2958 if (scope$3.flags & SCOPE_VAR) { break }
2959 }
2960 }
2961 if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
2962 };
2963
2964 pp$5.checkLocalExport = function(id) {
2965 // scope.functions must be empty as Module code is always strict.
2966 if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
2967 this.scopeStack[0].var.indexOf(id.name) === -1) {
2968 this.undefinedExports[id.name] = id;
2969 }
2970 };
2971
2972 pp$5.currentScope = function() {
2973 return this.scopeStack[this.scopeStack.length - 1]
2974 };
2975
2976 pp$5.currentVarScope = function() {
2977 for (var i = this.scopeStack.length - 1;; i--) {
2978 var scope = this.scopeStack[i];
2979 if (scope.flags & SCOPE_VAR) { return scope }
2980 }
2981 };
2982
2983 // Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
2984 pp$5.currentThisScope = function() {
2985 for (var i = this.scopeStack.length - 1;; i--) {
2986 var scope = this.scopeStack[i];
2987 if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
2988 }
2989 };
2990
2991 var Node = function Node(parser, pos, loc) {
2992 this.type = "";
2993 this.start = pos;
2994 this.end = 0;
2995 if (parser.options.locations)
2996 { this.loc = new SourceLocation(parser, loc); }
2997 if (parser.options.directSourceFile)
2998 { this.sourceFile = parser.options.directSourceFile; }
2999 if (parser.options.ranges)
3000 { this.range = [pos, 0]; }
3001 };
3002
3003 // Start an AST node, attaching a start offset.
3004
3005 var pp$6 = Parser.prototype;
3006
3007 pp$6.startNode = function() {
3008 return new Node(this, this.start, this.startLoc)
3009 };
3010
3011 pp$6.startNodeAt = function(pos, loc) {
3012 return new Node(this, pos, loc)
3013 };
3014
3015 // Finish an AST node, adding `type` and `end` properties.
3016
3017 function finishNodeAt(node, type, pos, loc) {
3018 node.type = type;
3019 node.end = pos;
3020 if (this.options.locations)
3021 { node.loc.end = loc; }
3022 if (this.options.ranges)
3023 { node.range[1] = pos; }
3024 return node
3025 }
3026
3027 pp$6.finishNode = function(node, type) {
3028 return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
3029 };
3030
3031 // Finish node at given position
3032
3033 pp$6.finishNodeAt = function(node, type, pos, loc) {
3034 return finishNodeAt.call(this, node, type, pos, loc)
3035 };
3036
3037 // The algorithm used to determine whether a regexp can appear at a
3038
3039 var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
3040 this.token = token;
3041 this.isExpr = !!isExpr;
3042 this.preserveSpace = !!preserveSpace;
3043 this.override = override;
3044 this.generator = !!generator;
3045 };
3046
3047 var types$1 = {
3048 b_stat: new TokContext("{", false),
3049 b_expr: new TokContext("{", true),
3050 b_tmpl: new TokContext("${", false),
3051 p_stat: new TokContext("(", false),
3052 p_expr: new TokContext("(", true),
3053 q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
3054 f_stat: new TokContext("function", false),
3055 f_expr: new TokContext("function", true),
3056 f_expr_gen: new TokContext("function", true, false, null, true),
3057 f_gen: new TokContext("function", false, false, null, true)
3058 };
3059
3060 var pp$7 = Parser.prototype;
3061
3062 pp$7.initialContext = function() {
3063 return [types$1.b_stat]
3064 };
3065
3066 pp$7.braceIsBlock = function(prevType) {
3067 var parent = this.curContext();
3068 if (parent === types$1.f_expr || parent === types$1.f_stat)
3069 { return true }
3070 if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
3071 { return !parent.isExpr }
3072
3073 // The check for `tt.name && exprAllowed` detects whether we are
3074 // after a `yield` or `of` construct. See the `updateContext` for
3075 // `tt.name`.
3076 if (prevType === types._return || prevType === types.name && this.exprAllowed)
3077 { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
3078 if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)
3079 { return true }
3080 if (prevType === types.braceL)
3081 { return parent === types$1.b_stat }
3082 if (prevType === types._var || prevType === types._const || prevType === types.name)
3083 { return false }
3084 return !this.exprAllowed
3085 };
3086
3087 pp$7.inGeneratorContext = function() {
3088 for (var i = this.context.length - 1; i >= 1; i--) {
3089 var context = this.context[i];
3090 if (context.token === "function")
3091 { return context.generator }
3092 }
3093 return false
3094 };
3095
3096 pp$7.updateContext = function(prevType) {
3097 var update, type = this.type;
3098 if (type.keyword && prevType === types.dot)
3099 { this.exprAllowed = false; }
3100 else if (update = type.updateContext)
3101 { update.call(this, prevType); }
3102 else
3103 { this.exprAllowed = type.beforeExpr; }
3104 };
3105
3106 // Token-specific context update code
3107
3108 types.parenR.updateContext = types.braceR.updateContext = function() {
3109 if (this.context.length === 1) {
3110 this.exprAllowed = true;
3111 return
3112 }
3113 var out = this.context.pop();
3114 if (out === types$1.b_stat && this.curContext().token === "function") {
3115 out = this.context.pop();
3116 }
3117 this.exprAllowed = !out.isExpr;
3118 };
3119
3120 types.braceL.updateContext = function(prevType) {
3121 this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
3122 this.exprAllowed = true;
3123 };
3124
3125 types.dollarBraceL.updateContext = function() {
3126 this.context.push(types$1.b_tmpl);
3127 this.exprAllowed = true;
3128 };
3129
3130 types.parenL.updateContext = function(prevType) {
3131 var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
3132 this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
3133 this.exprAllowed = true;
3134 };
3135
3136 types.incDec.updateContext = function() {
3137 // tokExprAllowed stays unchanged
3138 };
3139
3140 types._function.updateContext = types._class.updateContext = function(prevType) {
3141 if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
3142 !(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
3143 !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
3144 { this.context.push(types$1.f_expr); }
3145 else
3146 { this.context.push(types$1.f_stat); }
3147 this.exprAllowed = false;
3148 };
3149
3150 types.backQuote.updateContext = function() {
3151 if (this.curContext() === types$1.q_tmpl)
3152 { this.context.pop(); }
3153 else
3154 { this.context.push(types$1.q_tmpl); }
3155 this.exprAllowed = false;
3156 };
3157
3158 types.star.updateContext = function(prevType) {
3159 if (prevType === types._function) {
3160 var index = this.context.length - 1;
3161 if (this.context[index] === types$1.f_expr)
3162 { this.context[index] = types$1.f_expr_gen; }
3163 else
3164 { this.context[index] = types$1.f_gen; }
3165 }
3166 this.exprAllowed = true;
3167 };
3168
3169 types.name.updateContext = function(prevType) {
3170 var allowed = false;
3171 if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {
3172 if (this.value === "of" && !this.exprAllowed ||
3173 this.value === "yield" && this.inGeneratorContext())
3174 { allowed = true; }
3175 }
3176 this.exprAllowed = allowed;
3177 };
3178
3179 // This file contains Unicode properties extracted from the ECMAScript
3180 // specification. The lists are extracted like so:
3181 // $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
3182
3183 // #table-binary-unicode-properties
3184 var ecma9BinaryProperties = "ASCII ASCII_Hex_Digit AHex Alphabetic Alpha Any Assigned Bidi_Control Bidi_C Bidi_Mirrored Bidi_M Case_Ignorable CI Cased Changes_When_Casefolded CWCF Changes_When_Casemapped CWCM Changes_When_Lowercased CWL Changes_When_NFKC_Casefolded CWKCF Changes_When_Titlecased CWT Changes_When_Uppercased CWU Dash Default_Ignorable_Code_Point DI Deprecated Dep Diacritic Dia Emoji Emoji_Component Emoji_Modifier Emoji_Modifier_Base Emoji_Presentation Extender Ext Grapheme_Base Gr_Base Grapheme_Extend Gr_Ext Hex_Digit Hex IDS_Binary_Operator IDSB IDS_Trinary_Operator IDST ID_Continue IDC ID_Start IDS Ideographic Ideo Join_Control Join_C Logical_Order_Exception LOE Lowercase Lower Math Noncharacter_Code_Point NChar Pattern_Syntax Pat_Syn Pattern_White_Space Pat_WS Quotation_Mark QMark Radical Regional_Indicator RI Sentence_Terminal STerm Soft_Dotted SD Terminal_Punctuation Term Unified_Ideograph UIdeo Uppercase Upper Variation_Selector VS White_Space space XID_Continue XIDC XID_Start XIDS";
3185 var unicodeBinaryProperties = {
3186 9: ecma9BinaryProperties,
3187 10: ecma9BinaryProperties + " Extended_Pictographic"
3188 };
3189
3190 // #table-unicode-general-category-values
3191 var unicodeGeneralCategoryValues = "Cased_Letter LC Close_Punctuation Pe Connector_Punctuation Pc Control Cc cntrl Currency_Symbol Sc Dash_Punctuation Pd Decimal_Number Nd digit Enclosing_Mark Me Final_Punctuation Pf Format Cf Initial_Punctuation Pi Letter L Letter_Number Nl Line_Separator Zl Lowercase_Letter Ll Mark M Combining_Mark Math_Symbol Sm Modifier_Letter Lm Modifier_Symbol Sk Nonspacing_Mark Mn Number N Open_Punctuation Ps Other C Other_Letter Lo Other_Number No Other_Punctuation Po Other_Symbol So Paragraph_Separator Zp Private_Use Co Punctuation P punct Separator Z Space_Separator Zs Spacing_Mark Mc Surrogate Cs Symbol S Titlecase_Letter Lt Unassigned Cn Uppercase_Letter Lu";
3192
3193 // #table-unicode-script-values
3194 var ecma9ScriptValues = "Adlam Adlm Ahom Ahom Anatolian_Hieroglyphs Hluw Arabic Arab Armenian Armn Avestan Avst Balinese Bali Bamum Bamu Bassa_Vah Bass Batak Batk Bengali Beng Bhaiksuki Bhks Bopomofo Bopo Brahmi Brah Braille Brai Buginese Bugi Buhid Buhd Canadian_Aboriginal Cans Carian Cari Caucasian_Albanian Aghb Chakma Cakm Cham Cham Cherokee Cher Common Zyyy Coptic Copt Qaac Cuneiform Xsux Cypriot Cprt Cyrillic Cyrl Deseret Dsrt Devanagari Deva Duployan Dupl Egyptian_Hieroglyphs Egyp Elbasan Elba Ethiopic Ethi Georgian Geor Glagolitic Glag Gothic Goth Grantha Gran Greek Grek Gujarati Gujr Gurmukhi Guru Han Hani Hangul Hang Hanunoo Hano Hatran Hatr Hebrew Hebr Hiragana Hira Imperial_Aramaic Armi Inherited Zinh Qaai Inscriptional_Pahlavi Phli Inscriptional_Parthian Prti Javanese Java Kaithi Kthi Kannada Knda Katakana Kana Kayah_Li Kali Kharoshthi Khar Khmer Khmr Khojki Khoj Khudawadi Sind Lao Laoo Latin Latn Lepcha Lepc Limbu Limb Linear_A Lina Linear_B Linb Lisu Lisu Lycian Lyci Lydian Lydi Mahajani Mahj Malayalam Mlym Mandaic Mand Manichaean Mani Marchen Marc Masaram_Gondi Gonm Meetei_Mayek Mtei Mende_Kikakui Mend Meroitic_Cursive Merc Meroitic_Hieroglyphs Mero Miao Plrd Modi Modi Mongolian Mong Mro Mroo Multani Mult Myanmar Mymr Nabataean Nbat New_Tai_Lue Talu Newa Newa Nko Nkoo Nushu Nshu Ogham Ogam Ol_Chiki Olck Old_Hungarian Hung Old_Italic Ital Old_North_Arabian Narb Old_Permic Perm Old_Persian Xpeo Old_South_Arabian Sarb Old_Turkic Orkh Oriya Orya Osage Osge Osmanya Osma Pahawh_Hmong Hmng Palmyrene Palm Pau_Cin_Hau Pauc Phags_Pa Phag Phoenician Phnx Psalter_Pahlavi Phlp Rejang Rjng Runic Runr Samaritan Samr Saurashtra Saur Sharada Shrd Shavian Shaw Siddham Sidd SignWriting Sgnw Sinhala Sinh Sora_Sompeng Sora Soyombo Soyo Sundanese Sund Syloti_Nagri Sylo Syriac Syrc Tagalog Tglg Tagbanwa Tagb Tai_Le Tale Tai_Tham Lana Tai_Viet Tavt Takri Takr Tamil Taml Tangut Tang Telugu Telu Thaana Thaa Thai Thai Tibetan Tibt Tifinagh Tfng Tirhuta Tirh Ugaritic Ugar Vai Vaii Warang_Citi Wara Yi Yiii Zanabazar_Square Zanb";
3195 var unicodeScriptValues = {
3196 9: ecma9ScriptValues,
3197 10: ecma9ScriptValues + " Dogra Dogr Elymaic Elym Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Old_Sogdian Sogo Sogdian Sogd Wancho Wcho"
3198 };
3199
3200 var data = {};
3201 function buildUnicodeData(ecmaVersion) {
3202 var d = data[ecmaVersion] = {
3203 binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
3204 nonBinary: {
3205 General_Category: wordsRegexp(unicodeGeneralCategoryValues),
3206 Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
3207 }
3208 };
3209 d.nonBinary.Script_Extensions = d.nonBinary.Script;
3210
3211 d.nonBinary.gc = d.nonBinary.General_Category;
3212 d.nonBinary.sc = d.nonBinary.Script;
3213 d.nonBinary.scx = d.nonBinary.Script_Extensions;
3214 }
3215 buildUnicodeData(9);
3216 buildUnicodeData(10);
3217
3218 var pp$8 = Parser.prototype;
3219
3220 var RegExpValidationState = function RegExpValidationState(parser) {
3221 this.parser = parser;
3222 this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
3223 this.unicodeProperties = data[parser.options.ecmaVersion >= 10 ? 10 : parser.options.ecmaVersion];
3224 this.source = "";
3225 this.flags = "";
3226 this.start = 0;
3227 this.switchU = false;
3228 this.switchN = false;
3229 this.pos = 0;
3230 this.lastIntValue = 0;
3231 this.lastStringValue = "";
3232 this.lastAssertionIsQuantifiable = false;
3233 this.numCapturingParens = 0;
3234 this.maxBackReference = 0;
3235 this.groupNames = [];
3236 this.backReferenceNames = [];
3237 };
3238
3239 RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
3240 var unicode = flags.indexOf("u") !== -1;
3241 this.start = start | 0;
3242 this.source = pattern + "";
3243 this.flags = flags;
3244 this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
3245 this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
3246 };
3247
3248 RegExpValidationState.prototype.raise = function raise (message) {
3249 this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
3250 };
3251
3252 // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
3253 // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
3254 RegExpValidationState.prototype.at = function at (i) {
3255 var s = this.source;
3256 var l = s.length;
3257 if (i >= l) {
3258 return -1
3259 }
3260 var c = s.charCodeAt(i);
3261 if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
3262 return c
3263 }
3264 return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00
3265 };
3266
3267 RegExpValidationState.prototype.nextIndex = function nextIndex (i) {
3268 var s = this.source;
3269 var l = s.length;
3270 if (i >= l) {
3271 return l
3272 }
3273 var c = s.charCodeAt(i);
3274 if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
3275 return i + 1
3276 }
3277 return i + 2
3278 };
3279
3280 RegExpValidationState.prototype.current = function current () {
3281 return this.at(this.pos)
3282 };
3283
3284 RegExpValidationState.prototype.lookahead = function lookahead () {
3285 return this.at(this.nextIndex(this.pos))
3286 };
3287
3288 RegExpValidationState.prototype.advance = function advance () {
3289 this.pos = this.nextIndex(this.pos);
3290 };
3291
3292 RegExpValidationState.prototype.eat = function eat (ch) {
3293 if (this.current() === ch) {
3294 this.advance();
3295 return true
3296 }
3297 return false
3298 };
3299
3300 function codePointToString(ch) {
3301 if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
3302 ch -= 0x10000;
3303 return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
3304 }
3305
3306 /**
3307 * Validate the flags part of a given RegExpLiteral.
3308 *
3309 * @param {RegExpValidationState} state The state to validate RegExp.
3310 * @returns {void}
3311 */
3312 pp$8.validateRegExpFlags = function(state) {
3313 var validFlags = state.validFlags;
3314 var flags = state.flags;
3315
3316 for (var i = 0; i < flags.length; i++) {
3317 var flag = flags.charAt(i);
3318 if (validFlags.indexOf(flag) === -1) {
3319 this.raise(state.start, "Invalid regular expression flag");
3320 }
3321 if (flags.indexOf(flag, i + 1) > -1) {
3322 this.raise(state.start, "Duplicate regular expression flag");
3323 }
3324 }
3325 };
3326
3327 /**
3328 * Validate the pattern part of a given RegExpLiteral.
3329 *
3330 * @param {RegExpValidationState} state The state to validate RegExp.
3331 * @returns {void}
3332 */
3333 pp$8.validateRegExpPattern = function(state) {
3334 this.regexp_pattern(state);
3335
3336 // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
3337 // parsing contains a |GroupName|, reparse with the goal symbol
3338 // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
3339 // exception if _P_ did not conform to the grammar, if any elements of _P_
3340 // were not matched by the parse, or if any Early Error conditions exist.
3341 if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
3342 state.switchN = true;
3343 this.regexp_pattern(state);
3344 }
3345 };
3346
3347 // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
3348 pp$8.regexp_pattern = function(state) {
3349 state.pos = 0;
3350 state.lastIntValue = 0;
3351 state.lastStringValue = "";
3352 state.lastAssertionIsQuantifiable = false;
3353 state.numCapturingParens = 0;
3354 state.maxBackReference = 0;
3355 state.groupNames.length = 0;
3356 state.backReferenceNames.length = 0;
3357
3358 this.regexp_disjunction(state);
3359
3360 if (state.pos !== state.source.length) {
3361 // Make the same messages as V8.
3362 if (state.eat(0x29 /* ) */)) {
3363 state.raise("Unmatched ')'");
3364 }
3365 if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {
3366 state.raise("Lone quantifier brackets");
3367 }
3368 }
3369 if (state.maxBackReference > state.numCapturingParens) {
3370 state.raise("Invalid escape");
3371 }
3372 for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
3373 var name = list[i];
3374
3375 if (state.groupNames.indexOf(name) === -1) {
3376 state.raise("Invalid named capture referenced");
3377 }
3378 }
3379 };
3380
3381 // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
3382 pp$8.regexp_disjunction = function(state) {
3383 this.regexp_alternative(state);
3384 while (state.eat(0x7C /* | */)) {
3385 this.regexp_alternative(state);
3386 }
3387
3388 // Make the same message as V8.
3389 if (this.regexp_eatQuantifier(state, true)) {
3390 state.raise("Nothing to repeat");
3391 }
3392 if (state.eat(0x7B /* { */)) {
3393 state.raise("Lone quantifier brackets");
3394 }
3395 };
3396
3397 // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
3398 pp$8.regexp_alternative = function(state) {
3399 while (state.pos < state.source.length && this.regexp_eatTerm(state))
3400 { }
3401 };
3402
3403 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
3404 pp$8.regexp_eatTerm = function(state) {
3405 if (this.regexp_eatAssertion(state)) {
3406 // Handle `QuantifiableAssertion Quantifier` alternative.
3407 // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
3408 // is a QuantifiableAssertion.
3409 if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
3410 // Make the same message as V8.
3411 if (state.switchU) {
3412 state.raise("Invalid quantifier");
3413 }
3414 }
3415 return true
3416 }
3417
3418 if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
3419 this.regexp_eatQuantifier(state);
3420 return true
3421 }
3422
3423 return false
3424 };
3425
3426 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
3427 pp$8.regexp_eatAssertion = function(state) {
3428 var start = state.pos;
3429 state.lastAssertionIsQuantifiable = false;
3430
3431 // ^, $
3432 if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
3433 return true
3434 }
3435
3436 // \b \B
3437 if (state.eat(0x5C /* \ */)) {
3438 if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
3439 return true
3440 }
3441 state.pos = start;
3442 }
3443
3444 // Lookahead / Lookbehind
3445 if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
3446 var lookbehind = false;
3447 if (this.options.ecmaVersion >= 9) {
3448 lookbehind = state.eat(0x3C /* < */);
3449 }
3450 if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
3451 this.regexp_disjunction(state);
3452 if (!state.eat(0x29 /* ) */)) {
3453 state.raise("Unterminated group");
3454 }
3455 state.lastAssertionIsQuantifiable = !lookbehind;
3456 return true
3457 }
3458 }
3459
3460 state.pos = start;
3461 return false
3462 };
3463
3464 // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
3465 pp$8.regexp_eatQuantifier = function(state, noError) {
3466 if ( noError === void 0 ) noError = false;
3467
3468 if (this.regexp_eatQuantifierPrefix(state, noError)) {
3469 state.eat(0x3F /* ? */);
3470 return true
3471 }
3472 return false
3473 };
3474
3475 // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
3476 pp$8.regexp_eatQuantifierPrefix = function(state, noError) {
3477 return (
3478 state.eat(0x2A /* * */) ||
3479 state.eat(0x2B /* + */) ||
3480 state.eat(0x3F /* ? */) ||
3481 this.regexp_eatBracedQuantifier(state, noError)
3482 )
3483 };
3484 pp$8.regexp_eatBracedQuantifier = function(state, noError) {
3485 var start = state.pos;
3486 if (state.eat(0x7B /* { */)) {
3487 var min = 0, max = -1;
3488 if (this.regexp_eatDecimalDigits(state)) {
3489 min = state.lastIntValue;
3490 if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
3491 max = state.lastIntValue;
3492 }
3493 if (state.eat(0x7D /* } */)) {
3494 // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
3495 if (max !== -1 && max < min && !noError) {
3496 state.raise("numbers out of order in {} quantifier");
3497 }
3498 return true
3499 }
3500 }
3501 if (state.switchU && !noError) {
3502 state.raise("Incomplete quantifier");
3503 }
3504 state.pos = start;
3505 }
3506 return false
3507 };
3508
3509 // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
3510 pp$8.regexp_eatAtom = function(state) {
3511 return (
3512 this.regexp_eatPatternCharacters(state) ||
3513 state.eat(0x2E /* . */) ||
3514 this.regexp_eatReverseSolidusAtomEscape(state) ||
3515 this.regexp_eatCharacterClass(state) ||
3516 this.regexp_eatUncapturingGroup(state) ||
3517 this.regexp_eatCapturingGroup(state)
3518 )
3519 };
3520 pp$8.regexp_eatReverseSolidusAtomEscape = function(state) {
3521 var start = state.pos;
3522 if (state.eat(0x5C /* \ */)) {
3523 if (this.regexp_eatAtomEscape(state)) {
3524 return true
3525 }
3526 state.pos = start;
3527 }
3528 return false
3529 };
3530 pp$8.regexp_eatUncapturingGroup = function(state) {
3531 var start = state.pos;
3532 if (state.eat(0x28 /* ( */)) {
3533 if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
3534 this.regexp_disjunction(state);
3535 if (state.eat(0x29 /* ) */)) {
3536 return true
3537 }
3538 state.raise("Unterminated group");
3539 }
3540 state.pos = start;
3541 }
3542 return false
3543 };
3544 pp$8.regexp_eatCapturingGroup = function(state) {
3545 if (state.eat(0x28 /* ( */)) {
3546 if (this.options.ecmaVersion >= 9) {
3547 this.regexp_groupSpecifier(state);
3548 } else if (state.current() === 0x3F /* ? */) {
3549 state.raise("Invalid group");
3550 }
3551 this.regexp_disjunction(state);
3552 if (state.eat(0x29 /* ) */)) {
3553 state.numCapturingParens += 1;
3554 return true
3555 }
3556 state.raise("Unterminated group");
3557 }
3558 return false
3559 };
3560
3561 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
3562 pp$8.regexp_eatExtendedAtom = function(state) {
3563 return (
3564 state.eat(0x2E /* . */) ||
3565 this.regexp_eatReverseSolidusAtomEscape(state) ||
3566 this.regexp_eatCharacterClass(state) ||
3567 this.regexp_eatUncapturingGroup(state) ||
3568 this.regexp_eatCapturingGroup(state) ||
3569 this.regexp_eatInvalidBracedQuantifier(state) ||
3570 this.regexp_eatExtendedPatternCharacter(state)
3571 )
3572 };
3573
3574 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
3575 pp$8.regexp_eatInvalidBracedQuantifier = function(state) {
3576 if (this.regexp_eatBracedQuantifier(state, true)) {
3577 state.raise("Nothing to repeat");
3578 }
3579 return false
3580 };
3581
3582 // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
3583 pp$8.regexp_eatSyntaxCharacter = function(state) {
3584 var ch = state.current();
3585 if (isSyntaxCharacter(ch)) {
3586 state.lastIntValue = ch;
3587 state.advance();
3588 return true
3589 }
3590 return false
3591 };
3592 function isSyntaxCharacter(ch) {
3593 return (
3594 ch === 0x24 /* $ */ ||
3595 ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
3596 ch === 0x2E /* . */ ||
3597 ch === 0x3F /* ? */ ||
3598 ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
3599 ch >= 0x7B /* { */ && ch <= 0x7D /* } */
3600 )
3601 }
3602
3603 // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
3604 // But eat eager.
3605 pp$8.regexp_eatPatternCharacters = function(state) {
3606 var start = state.pos;
3607 var ch = 0;
3608 while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
3609 state.advance();
3610 }
3611 return state.pos !== start
3612 };
3613
3614 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
3615 pp$8.regexp_eatExtendedPatternCharacter = function(state) {
3616 var ch = state.current();
3617 if (
3618 ch !== -1 &&
3619 ch !== 0x24 /* $ */ &&
3620 !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
3621 ch !== 0x2E /* . */ &&
3622 ch !== 0x3F /* ? */ &&
3623 ch !== 0x5B /* [ */ &&
3624 ch !== 0x5E /* ^ */ &&
3625 ch !== 0x7C /* | */
3626 ) {
3627 state.advance();
3628 return true
3629 }
3630 return false
3631 };
3632
3633 // GroupSpecifier[U] ::
3634 // [empty]
3635 // `?` GroupName[?U]
3636 pp$8.regexp_groupSpecifier = function(state) {
3637 if (state.eat(0x3F /* ? */)) {
3638 if (this.regexp_eatGroupName(state)) {
3639 if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
3640 state.raise("Duplicate capture group name");
3641 }
3642 state.groupNames.push(state.lastStringValue);
3643 return
3644 }
3645 state.raise("Invalid group");
3646 }
3647 };
3648
3649 // GroupName[U] ::
3650 // `<` RegExpIdentifierName[?U] `>`
3651 // Note: this updates `state.lastStringValue` property with the eaten name.
3652 pp$8.regexp_eatGroupName = function(state) {
3653 state.lastStringValue = "";
3654 if (state.eat(0x3C /* < */)) {
3655 if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
3656 return true
3657 }
3658 state.raise("Invalid capture group name");
3659 }
3660 return false
3661 };
3662
3663 // RegExpIdentifierName[U] ::
3664 // RegExpIdentifierStart[?U]
3665 // RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
3666 // Note: this updates `state.lastStringValue` property with the eaten name.
3667 pp$8.regexp_eatRegExpIdentifierName = function(state) {
3668 state.lastStringValue = "";
3669 if (this.regexp_eatRegExpIdentifierStart(state)) {
3670 state.lastStringValue += codePointToString(state.lastIntValue);
3671 while (this.regexp_eatRegExpIdentifierPart(state)) {
3672 state.lastStringValue += codePointToString(state.lastIntValue);
3673 }
3674 return true
3675 }
3676 return false
3677 };
3678
3679 // RegExpIdentifierStart[U] ::
3680 // UnicodeIDStart
3681 // `$`
3682 // `_`
3683 // `\` RegExpUnicodeEscapeSequence[?U]
3684 pp$8.regexp_eatRegExpIdentifierStart = function(state) {
3685 var start = state.pos;
3686 var ch = state.current();
3687 state.advance();
3688
3689 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
3690 ch = state.lastIntValue;
3691 }
3692 if (isRegExpIdentifierStart(ch)) {
3693 state.lastIntValue = ch;
3694 return true
3695 }
3696
3697 state.pos = start;
3698 return false
3699 };
3700 function isRegExpIdentifierStart(ch) {
3701 return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
3702 }
3703
3704 // RegExpIdentifierPart[U] ::
3705 // UnicodeIDContinue
3706 // `$`
3707 // `_`
3708 // `\` RegExpUnicodeEscapeSequence[?U]
3709 // <ZWNJ>
3710 // <ZWJ>
3711 pp$8.regexp_eatRegExpIdentifierPart = function(state) {
3712 var start = state.pos;
3713 var ch = state.current();
3714 state.advance();
3715
3716 if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
3717 ch = state.lastIntValue;
3718 }
3719 if (isRegExpIdentifierPart(ch)) {
3720 state.lastIntValue = ch;
3721 return true
3722 }
3723
3724 state.pos = start;
3725 return false
3726 };
3727 function isRegExpIdentifierPart(ch) {
3728 return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
3729 }
3730
3731 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
3732 pp$8.regexp_eatAtomEscape = function(state) {
3733 if (
3734 this.regexp_eatBackReference(state) ||
3735 this.regexp_eatCharacterClassEscape(state) ||
3736 this.regexp_eatCharacterEscape(state) ||
3737 (state.switchN && this.regexp_eatKGroupName(state))
3738 ) {
3739 return true
3740 }
3741 if (state.switchU) {
3742 // Make the same message as V8.
3743 if (state.current() === 0x63 /* c */) {
3744 state.raise("Invalid unicode escape");
3745 }
3746 state.raise("Invalid escape");
3747 }
3748 return false
3749 };
3750 pp$8.regexp_eatBackReference = function(state) {
3751 var start = state.pos;
3752 if (this.regexp_eatDecimalEscape(state)) {
3753 var n = state.lastIntValue;
3754 if (state.switchU) {
3755 // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
3756 if (n > state.maxBackReference) {
3757 state.maxBackReference = n;
3758 }
3759 return true
3760 }
3761 if (n <= state.numCapturingParens) {
3762 return true
3763 }
3764 state.pos = start;
3765 }
3766 return false
3767 };
3768 pp$8.regexp_eatKGroupName = function(state) {
3769 if (state.eat(0x6B /* k */)) {
3770 if (this.regexp_eatGroupName(state)) {
3771 state.backReferenceNames.push(state.lastStringValue);
3772 return true
3773 }
3774 state.raise("Invalid named reference");
3775 }
3776 return false
3777 };
3778
3779 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
3780 pp$8.regexp_eatCharacterEscape = function(state) {
3781 return (
3782 this.regexp_eatControlEscape(state) ||
3783 this.regexp_eatCControlLetter(state) ||
3784 this.regexp_eatZero(state) ||
3785 this.regexp_eatHexEscapeSequence(state) ||
3786 this.regexp_eatRegExpUnicodeEscapeSequence(state) ||
3787 (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
3788 this.regexp_eatIdentityEscape(state)
3789 )
3790 };
3791 pp$8.regexp_eatCControlLetter = function(state) {
3792 var start = state.pos;
3793 if (state.eat(0x63 /* c */)) {
3794 if (this.regexp_eatControlLetter(state)) {
3795 return true
3796 }
3797 state.pos = start;
3798 }
3799 return false
3800 };
3801 pp$8.regexp_eatZero = function(state) {
3802 if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
3803 state.lastIntValue = 0;
3804 state.advance();
3805 return true
3806 }
3807 return false
3808 };
3809
3810 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
3811 pp$8.regexp_eatControlEscape = function(state) {
3812 var ch = state.current();
3813 if (ch === 0x74 /* t */) {
3814 state.lastIntValue = 0x09; /* \t */
3815 state.advance();
3816 return true
3817 }
3818 if (ch === 0x6E /* n */) {
3819 state.lastIntValue = 0x0A; /* \n */
3820 state.advance();
3821 return true
3822 }
3823 if (ch === 0x76 /* v */) {
3824 state.lastIntValue = 0x0B; /* \v */
3825 state.advance();
3826 return true
3827 }
3828 if (ch === 0x66 /* f */) {
3829 state.lastIntValue = 0x0C; /* \f */
3830 state.advance();
3831 return true
3832 }
3833 if (ch === 0x72 /* r */) {
3834 state.lastIntValue = 0x0D; /* \r */
3835 state.advance();
3836 return true
3837 }
3838 return false
3839 };
3840
3841 // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
3842 pp$8.regexp_eatControlLetter = function(state) {
3843 var ch = state.current();
3844 if (isControlLetter(ch)) {
3845 state.lastIntValue = ch % 0x20;
3846 state.advance();
3847 return true
3848 }
3849 return false
3850 };
3851 function isControlLetter(ch) {
3852 return (
3853 (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
3854 (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
3855 )
3856 }
3857
3858 // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
3859 pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state) {
3860 var start = state.pos;
3861
3862 if (state.eat(0x75 /* u */)) {
3863 if (this.regexp_eatFixedHexDigits(state, 4)) {
3864 var lead = state.lastIntValue;
3865 if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {
3866 var leadSurrogateEnd = state.pos;
3867 if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
3868 var trail = state.lastIntValue;
3869 if (trail >= 0xDC00 && trail <= 0xDFFF) {
3870 state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
3871 return true
3872 }
3873 }
3874 state.pos = leadSurrogateEnd;
3875 state.lastIntValue = lead;
3876 }
3877 return true
3878 }
3879 if (
3880 state.switchU &&
3881 state.eat(0x7B /* { */) &&
3882 this.regexp_eatHexDigits(state) &&
3883 state.eat(0x7D /* } */) &&
3884 isValidUnicode(state.lastIntValue)
3885 ) {
3886 return true
3887 }
3888 if (state.switchU) {
3889 state.raise("Invalid unicode escape");
3890 }
3891 state.pos = start;
3892 }
3893
3894 return false
3895 };
3896 function isValidUnicode(ch) {
3897 return ch >= 0 && ch <= 0x10FFFF
3898 }
3899
3900 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
3901 pp$8.regexp_eatIdentityEscape = function(state) {
3902 if (state.switchU) {
3903 if (this.regexp_eatSyntaxCharacter(state)) {
3904 return true
3905 }
3906 if (state.eat(0x2F /* / */)) {
3907 state.lastIntValue = 0x2F; /* / */
3908 return true
3909 }
3910 return false
3911 }
3912
3913 var ch = state.current();
3914 if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
3915 state.lastIntValue = ch;
3916 state.advance();
3917 return true
3918 }
3919
3920 return false
3921 };
3922
3923 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
3924 pp$8.regexp_eatDecimalEscape = function(state) {
3925 state.lastIntValue = 0;
3926 var ch = state.current();
3927 if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
3928 do {
3929 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
3930 state.advance();
3931 } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
3932 return true
3933 }
3934 return false
3935 };
3936
3937 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
3938 pp$8.regexp_eatCharacterClassEscape = function(state) {
3939 var ch = state.current();
3940
3941 if (isCharacterClassEscape(ch)) {
3942 state.lastIntValue = -1;
3943 state.advance();
3944 return true
3945 }
3946
3947 if (
3948 state.switchU &&
3949 this.options.ecmaVersion >= 9 &&
3950 (ch === 0x50 /* P */ || ch === 0x70 /* p */)
3951 ) {
3952 state.lastIntValue = -1;
3953 state.advance();
3954 if (
3955 state.eat(0x7B /* { */) &&
3956 this.regexp_eatUnicodePropertyValueExpression(state) &&
3957 state.eat(0x7D /* } */)
3958 ) {
3959 return true
3960 }
3961 state.raise("Invalid property name");
3962 }
3963
3964 return false
3965 };
3966 function isCharacterClassEscape(ch) {
3967 return (
3968 ch === 0x64 /* d */ ||
3969 ch === 0x44 /* D */ ||
3970 ch === 0x73 /* s */ ||
3971 ch === 0x53 /* S */ ||
3972 ch === 0x77 /* w */ ||
3973 ch === 0x57 /* W */
3974 )
3975 }
3976
3977 // UnicodePropertyValueExpression ::
3978 // UnicodePropertyName `=` UnicodePropertyValue
3979 // LoneUnicodePropertyNameOrValue
3980 pp$8.regexp_eatUnicodePropertyValueExpression = function(state) {
3981 var start = state.pos;
3982
3983 // UnicodePropertyName `=` UnicodePropertyValue
3984 if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
3985 var name = state.lastStringValue;
3986 if (this.regexp_eatUnicodePropertyValue(state)) {
3987 var value = state.lastStringValue;
3988 this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
3989 return true
3990 }
3991 }
3992 state.pos = start;
3993
3994 // LoneUnicodePropertyNameOrValue
3995 if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
3996 var nameOrValue = state.lastStringValue;
3997 this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
3998 return true
3999 }
4000 return false
4001 };
4002 pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
4003 if (!has(state.unicodeProperties.nonBinary, name))
4004 { state.raise("Invalid property name"); }
4005 if (!state.unicodeProperties.nonBinary[name].test(value))
4006 { state.raise("Invalid property value"); }
4007 };
4008 pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
4009 if (!state.unicodeProperties.binary.test(nameOrValue))
4010 { state.raise("Invalid property name"); }
4011 };
4012
4013 // UnicodePropertyName ::
4014 // UnicodePropertyNameCharacters
4015 pp$8.regexp_eatUnicodePropertyName = function(state) {
4016 var ch = 0;
4017 state.lastStringValue = "";
4018 while (isUnicodePropertyNameCharacter(ch = state.current())) {
4019 state.lastStringValue += codePointToString(ch);
4020 state.advance();
4021 }
4022 return state.lastStringValue !== ""
4023 };
4024 function isUnicodePropertyNameCharacter(ch) {
4025 return isControlLetter(ch) || ch === 0x5F /* _ */
4026 }
4027
4028 // UnicodePropertyValue ::
4029 // UnicodePropertyValueCharacters
4030 pp$8.regexp_eatUnicodePropertyValue = function(state) {
4031 var ch = 0;
4032 state.lastStringValue = "";
4033 while (isUnicodePropertyValueCharacter(ch = state.current())) {
4034 state.lastStringValue += codePointToString(ch);
4035 state.advance();
4036 }
4037 return state.lastStringValue !== ""
4038 };
4039 function isUnicodePropertyValueCharacter(ch) {
4040 return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
4041 }
4042
4043 // LoneUnicodePropertyNameOrValue ::
4044 // UnicodePropertyValueCharacters
4045 pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
4046 return this.regexp_eatUnicodePropertyValue(state)
4047 };
4048
4049 // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
4050 pp$8.regexp_eatCharacterClass = function(state) {
4051 if (state.eat(0x5B /* [ */)) {
4052 state.eat(0x5E /* ^ */);
4053 this.regexp_classRanges(state);
4054 if (state.eat(0x5D /* [ */)) {
4055 return true
4056 }
4057 // Unreachable since it threw "unterminated regular expression" error before.
4058 state.raise("Unterminated character class");
4059 }
4060 return false
4061 };
4062
4063 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
4064 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
4065 // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
4066 pp$8.regexp_classRanges = function(state) {
4067 while (this.regexp_eatClassAtom(state)) {
4068 var left = state.lastIntValue;
4069 if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
4070 var right = state.lastIntValue;
4071 if (state.switchU && (left === -1 || right === -1)) {
4072 state.raise("Invalid character class");
4073 }
4074 if (left !== -1 && right !== -1 && left > right) {
4075 state.raise("Range out of order in character class");
4076 }
4077 }
4078 }
4079 };
4080
4081 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
4082 // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
4083 pp$8.regexp_eatClassAtom = function(state) {
4084 var start = state.pos;
4085
4086 if (state.eat(0x5C /* \ */)) {
4087 if (this.regexp_eatClassEscape(state)) {
4088 return true
4089 }
4090 if (state.switchU) {
4091 // Make the same message as V8.
4092 var ch$1 = state.current();
4093 if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
4094 state.raise("Invalid class escape");
4095 }
4096 state.raise("Invalid escape");
4097 }
4098 state.pos = start;
4099 }
4100
4101 var ch = state.current();
4102 if (ch !== 0x5D /* [ */) {
4103 state.lastIntValue = ch;
4104 state.advance();
4105 return true
4106 }
4107
4108 return false
4109 };
4110
4111 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
4112 pp$8.regexp_eatClassEscape = function(state) {
4113 var start = state.pos;
4114
4115 if (state.eat(0x62 /* b */)) {
4116 state.lastIntValue = 0x08; /* <BS> */
4117 return true
4118 }
4119
4120 if (state.switchU && state.eat(0x2D /* - */)) {
4121 state.lastIntValue = 0x2D; /* - */
4122 return true
4123 }
4124
4125 if (!state.switchU && state.eat(0x63 /* c */)) {
4126 if (this.regexp_eatClassControlLetter(state)) {
4127 return true
4128 }
4129 state.pos = start;
4130 }
4131
4132 return (
4133 this.regexp_eatCharacterClassEscape(state) ||
4134 this.regexp_eatCharacterEscape(state)
4135 )
4136 };
4137
4138 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
4139 pp$8.regexp_eatClassControlLetter = function(state) {
4140 var ch = state.current();
4141 if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
4142 state.lastIntValue = ch % 0x20;
4143 state.advance();
4144 return true
4145 }
4146 return false
4147 };
4148
4149 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4150 pp$8.regexp_eatHexEscapeSequence = function(state) {
4151 var start = state.pos;
4152 if (state.eat(0x78 /* x */)) {
4153 if (this.regexp_eatFixedHexDigits(state, 2)) {
4154 return true
4155 }
4156 if (state.switchU) {
4157 state.raise("Invalid escape");
4158 }
4159 state.pos = start;
4160 }
4161 return false
4162 };
4163
4164 // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
4165 pp$8.regexp_eatDecimalDigits = function(state) {
4166 var start = state.pos;
4167 var ch = 0;
4168 state.lastIntValue = 0;
4169 while (isDecimalDigit(ch = state.current())) {
4170 state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
4171 state.advance();
4172 }
4173 return state.pos !== start
4174 };
4175 function isDecimalDigit(ch) {
4176 return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
4177 }
4178
4179 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
4180 pp$8.regexp_eatHexDigits = function(state) {
4181 var start = state.pos;
4182 var ch = 0;
4183 state.lastIntValue = 0;
4184 while (isHexDigit(ch = state.current())) {
4185 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4186 state.advance();
4187 }
4188 return state.pos !== start
4189 };
4190 function isHexDigit(ch) {
4191 return (
4192 (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
4193 (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
4194 (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
4195 )
4196 }
4197 function hexToInt(ch) {
4198 if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
4199 return 10 + (ch - 0x41 /* A */)
4200 }
4201 if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
4202 return 10 + (ch - 0x61 /* a */)
4203 }
4204 return ch - 0x30 /* 0 */
4205 }
4206
4207 // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
4208 // Allows only 0-377(octal) i.e. 0-255(decimal).
4209 pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) {
4210 if (this.regexp_eatOctalDigit(state)) {
4211 var n1 = state.lastIntValue;
4212 if (this.regexp_eatOctalDigit(state)) {
4213 var n2 = state.lastIntValue;
4214 if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
4215 state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
4216 } else {
4217 state.lastIntValue = n1 * 8 + n2;
4218 }
4219 } else {
4220 state.lastIntValue = n1;
4221 }
4222 return true
4223 }
4224 return false
4225 };
4226
4227 // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
4228 pp$8.regexp_eatOctalDigit = function(state) {
4229 var ch = state.current();
4230 if (isOctalDigit(ch)) {
4231 state.lastIntValue = ch - 0x30; /* 0 */
4232 state.advance();
4233 return true
4234 }
4235 state.lastIntValue = 0;
4236 return false
4237 };
4238 function isOctalDigit(ch) {
4239 return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
4240 }
4241
4242 // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
4243 // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
4244 // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
4245 pp$8.regexp_eatFixedHexDigits = function(state, length) {
4246 var start = state.pos;
4247 state.lastIntValue = 0;
4248 for (var i = 0; i < length; ++i) {
4249 var ch = state.current();
4250 if (!isHexDigit(ch)) {
4251 state.pos = start;
4252 return false
4253 }
4254 state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
4255 state.advance();
4256 }
4257 return true
4258 };
4259
4260 // Object type used to represent tokens. Note that normally, tokens
4261 // simply exist as properties on the parser object. This is only
4262 // used for the onToken callback and the external tokenizer.
4263
4264 var Token = function Token(p) {
4265 this.type = p.type;
4266 this.value = p.value;
4267 this.start = p.start;
4268 this.end = p.end;
4269 if (p.options.locations)
4270 { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
4271 if (p.options.ranges)
4272 { this.range = [p.start, p.end]; }
4273 };
4274
4275 // ## Tokenizer
4276
4277 var pp$9 = Parser.prototype;
4278
4279 // Move to the next token
4280
4281 pp$9.next = function() {
4282 if (this.options.onToken)
4283 { this.options.onToken(new Token(this)); }
4284
4285 this.lastTokEnd = this.end;
4286 this.lastTokStart = this.start;
4287 this.lastTokEndLoc = this.endLoc;
4288 this.lastTokStartLoc = this.startLoc;
4289 this.nextToken();
4290 };
4291
4292 pp$9.getToken = function() {
4293 this.next();
4294 return new Token(this)
4295 };
4296
4297 // If we're in an ES6 environment, make parsers iterable
4298 if (typeof Symbol !== "undefined")
4299 { pp$9[Symbol.iterator] = function() {
4300 var this$1 = this;
4301
4302 return {
4303 next: function () {
4304 var token = this$1.getToken();
4305 return {
4306 done: token.type === types.eof,
4307 value: token
4308 }
4309 }
4310 }
4311 }; }
4312
4313 // Toggle strict mode. Re-reads the next number or string to please
4314 // pedantic tests (`"use strict"; 010;` should fail).
4315
4316 pp$9.curContext = function() {
4317 return this.context[this.context.length - 1]
4318 };
4319
4320 // Read a single token, updating the parser object's token-related
4321 // properties.
4322
4323 pp$9.nextToken = function() {
4324 var curContext = this.curContext();
4325 if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
4326
4327 this.start = this.pos;
4328 if (this.options.locations) { this.startLoc = this.curPosition(); }
4329 if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
4330
4331 if (curContext.override) { return curContext.override(this) }
4332 else { this.readToken(this.fullCharCodeAtPos()); }
4333 };
4334
4335 pp$9.readToken = function(code) {
4336 // Identifier or keyword. '\uXXXX' sequences are allowed in
4337 // identifiers, so '\' also dispatches to that.
4338 if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
4339 { return this.readWord() }
4340
4341 return this.getTokenFromCode(code)
4342 };
4343
4344 pp$9.fullCharCodeAtPos = function() {
4345 var code = this.input.charCodeAt(this.pos);
4346 if (code <= 0xd7ff || code >= 0xe000) { return code }
4347 var next = this.input.charCodeAt(this.pos + 1);
4348 return (code << 10) + next - 0x35fdc00
4349 };
4350
4351 pp$9.skipBlockComment = function() {
4352 var startLoc = this.options.onComment && this.curPosition();
4353 var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
4354 if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
4355 this.pos = end + 2;
4356 if (this.options.locations) {
4357 lineBreakG.lastIndex = start;
4358 var match;
4359 while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
4360 ++this.curLine;
4361 this.lineStart = match.index + match[0].length;
4362 }
4363 }
4364 if (this.options.onComment)
4365 { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
4366 startLoc, this.curPosition()); }
4367 };
4368
4369 pp$9.skipLineComment = function(startSkip) {
4370 var start = this.pos;
4371 var startLoc = this.options.onComment && this.curPosition();
4372 var ch = this.input.charCodeAt(this.pos += startSkip);
4373 while (this.pos < this.input.length && !isNewLine(ch)) {
4374 ch = this.input.charCodeAt(++this.pos);
4375 }
4376 if (this.options.onComment)
4377 { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
4378 startLoc, this.curPosition()); }
4379 };
4380
4381 // Called at the start of the parse and after every token. Skips
4382 // whitespace and comments, and.
4383
4384 pp$9.skipSpace = function() {
4385 loop: while (this.pos < this.input.length) {
4386 var ch = this.input.charCodeAt(this.pos);
4387 switch (ch) {
4388 case 32: case 160: // ' '
4389 ++this.pos;
4390 break
4391 case 13:
4392 if (this.input.charCodeAt(this.pos + 1) === 10) {
4393 ++this.pos;
4394 }
4395 case 10: case 8232: case 8233:
4396 ++this.pos;
4397 if (this.options.locations) {
4398 ++this.curLine;
4399 this.lineStart = this.pos;
4400 }
4401 break
4402 case 47: // '/'
4403 switch (this.input.charCodeAt(this.pos + 1)) {
4404 case 42: // '*'
4405 this.skipBlockComment();
4406 break
4407 case 47:
4408 this.skipLineComment(2);
4409 break
4410 default:
4411 break loop
4412 }
4413 break
4414 default:
4415 if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
4416 ++this.pos;
4417 } else {
4418 break loop
4419 }
4420 }
4421 }
4422 };
4423
4424 // Called at the end of every token. Sets `end`, `val`, and
4425 // maintains `context` and `exprAllowed`, and skips the space after
4426 // the token, so that the next one's `start` will point at the
4427 // right position.
4428
4429 pp$9.finishToken = function(type, val) {
4430 this.end = this.pos;
4431 if (this.options.locations) { this.endLoc = this.curPosition(); }
4432 var prevType = this.type;
4433 this.type = type;
4434 this.value = val;
4435
4436 this.updateContext(prevType);
4437 };
4438
4439 // ### Token reading
4440
4441 // This is the function that is called to fetch the next token. It
4442 // is somewhat obscure, because it works in character codes rather
4443 // than characters, and because operator parsing has been inlined
4444 // into it.
4445 //
4446 // All in the name of speed.
4447 //
4448 pp$9.readToken_dot = function() {
4449 var next = this.input.charCodeAt(this.pos + 1);
4450 if (next >= 48 && next <= 57) { return this.readNumber(true) }
4451 var next2 = this.input.charCodeAt(this.pos + 2);
4452 if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
4453 this.pos += 3;
4454 return this.finishToken(types.ellipsis)
4455 } else {
4456 ++this.pos;
4457 return this.finishToken(types.dot)
4458 }
4459 };
4460
4461 pp$9.readToken_slash = function() { // '/'
4462 var next = this.input.charCodeAt(this.pos + 1);
4463 if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
4464 if (next === 61) { return this.finishOp(types.assign, 2) }
4465 return this.finishOp(types.slash, 1)
4466 };
4467
4468 pp$9.readToken_mult_modulo_exp = function(code) { // '%*'
4469 var next = this.input.charCodeAt(this.pos + 1);
4470 var size = 1;
4471 var tokentype = code === 42 ? types.star : types.modulo;
4472
4473 // exponentiation operator ** and **=
4474 if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
4475 ++size;
4476 tokentype = types.starstar;
4477 next = this.input.charCodeAt(this.pos + 2);
4478 }
4479
4480 if (next === 61) { return this.finishOp(types.assign, size + 1) }
4481 return this.finishOp(tokentype, size)
4482 };
4483
4484 pp$9.readToken_pipe_amp = function(code) { // '|&'
4485 var next = this.input.charCodeAt(this.pos + 1);
4486 if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }
4487 if (next === 61) { return this.finishOp(types.assign, 2) }
4488 return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
4489 };
4490
4491 pp$9.readToken_caret = function() { // '^'
4492 var next = this.input.charCodeAt(this.pos + 1);
4493 if (next === 61) { return this.finishOp(types.assign, 2) }
4494 return this.finishOp(types.bitwiseXOR, 1)
4495 };
4496
4497 pp$9.readToken_plus_min = function(code) { // '+-'
4498 var next = this.input.charCodeAt(this.pos + 1);
4499 if (next === code) {
4500 if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
4501 (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
4502 // A `-->` line comment
4503 this.skipLineComment(3);
4504 this.skipSpace();
4505 return this.nextToken()
4506 }
4507 return this.finishOp(types.incDec, 2)
4508 }
4509 if (next === 61) { return this.finishOp(types.assign, 2) }
4510 return this.finishOp(types.plusMin, 1)
4511 };
4512
4513 pp$9.readToken_lt_gt = function(code) { // '<>'
4514 var next = this.input.charCodeAt(this.pos + 1);
4515 var size = 1;
4516 if (next === code) {
4517 size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
4518 if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
4519 return this.finishOp(types.bitShift, size)
4520 }
4521 if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
4522 this.input.charCodeAt(this.pos + 3) === 45) {
4523 // `<!--`, an XML-style comment that should be interpreted as a line comment
4524 this.skipLineComment(4);
4525 this.skipSpace();
4526 return this.nextToken()
4527 }
4528 if (next === 61) { size = 2; }
4529 return this.finishOp(types.relational, size)
4530 };
4531
4532 pp$9.readToken_eq_excl = function(code) { // '=!'
4533 var next = this.input.charCodeAt(this.pos + 1);
4534 if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
4535 if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
4536 this.pos += 2;
4537 return this.finishToken(types.arrow)
4538 }
4539 return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
4540 };
4541
4542 pp$9.getTokenFromCode = function(code) {
4543 switch (code) {
4544 // The interpretation of a dot depends on whether it is followed
4545 // by a digit or another two dots.
4546 case 46: // '.'
4547 return this.readToken_dot()
4548
4549 // Punctuation tokens.
4550 case 40: ++this.pos; return this.finishToken(types.parenL)
4551 case 41: ++this.pos; return this.finishToken(types.parenR)
4552 case 59: ++this.pos; return this.finishToken(types.semi)
4553 case 44: ++this.pos; return this.finishToken(types.comma)
4554 case 91: ++this.pos; return this.finishToken(types.bracketL)
4555 case 93: ++this.pos; return this.finishToken(types.bracketR)
4556 case 123: ++this.pos; return this.finishToken(types.braceL)
4557 case 125: ++this.pos; return this.finishToken(types.braceR)
4558 case 58: ++this.pos; return this.finishToken(types.colon)
4559 case 63: ++this.pos; return this.finishToken(types.question)
4560
4561 case 96: // '`'
4562 if (this.options.ecmaVersion < 6) { break }
4563 ++this.pos;
4564 return this.finishToken(types.backQuote)
4565
4566 case 48: // '0'
4567 var next = this.input.charCodeAt(this.pos + 1);
4568 if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
4569 if (this.options.ecmaVersion >= 6) {
4570 if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
4571 if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
4572 }
4573
4574 // Anything else beginning with a digit is an integer, octal
4575 // number, or float.
4576 case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
4577 return this.readNumber(false)
4578
4579 // Quotes produce strings.
4580 case 34: case 39: // '"', "'"
4581 return this.readString(code)
4582
4583 // Operators are parsed inline in tiny state machines. '=' (61) is
4584 // often referred to. `finishOp` simply skips the amount of
4585 // characters it is given as second argument, and returns a token
4586 // of the type given by its first argument.
4587
4588 case 47: // '/'
4589 return this.readToken_slash()
4590
4591 case 37: case 42: // '%*'
4592 return this.readToken_mult_modulo_exp(code)
4593
4594 case 124: case 38: // '|&'
4595 return this.readToken_pipe_amp(code)
4596
4597 case 94: // '^'
4598 return this.readToken_caret()
4599
4600 case 43: case 45: // '+-'
4601 return this.readToken_plus_min(code)
4602
4603 case 60: case 62: // '<>'
4604 return this.readToken_lt_gt(code)
4605
4606 case 61: case 33: // '=!'
4607 return this.readToken_eq_excl(code)
4608
4609 case 126: // '~'
4610 return this.finishOp(types.prefix, 1)
4611 }
4612
4613 this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
4614 };
4615
4616 pp$9.finishOp = function(type, size) {
4617 var str = this.input.slice(this.pos, this.pos + size);
4618 this.pos += size;
4619 return this.finishToken(type, str)
4620 };
4621
4622 pp$9.readRegexp = function() {
4623 var escaped, inClass, start = this.pos;
4624 for (;;) {
4625 if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
4626 var ch = this.input.charAt(this.pos);
4627 if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
4628 if (!escaped) {
4629 if (ch === "[") { inClass = true; }
4630 else if (ch === "]" && inClass) { inClass = false; }
4631 else if (ch === "/" && !inClass) { break }
4632 escaped = ch === "\\";
4633 } else { escaped = false; }
4634 ++this.pos;
4635 }
4636 var pattern = this.input.slice(start, this.pos);
4637 ++this.pos;
4638 var flagsStart = this.pos;
4639 var flags = this.readWord1();
4640 if (this.containsEsc) { this.unexpected(flagsStart); }
4641
4642 // Validate pattern
4643 var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
4644 state.reset(start, pattern, flags);
4645 this.validateRegExpFlags(state);
4646 this.validateRegExpPattern(state);
4647
4648 // Create Literal#value property value.
4649 var value = null;
4650 try {
4651 value = new RegExp(pattern, flags);
4652 } catch (e) {
4653 // ESTree requires null if it failed to instantiate RegExp object.
4654 // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
4655 }
4656
4657 return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value})
4658 };
4659
4660 // Read an integer in the given radix. Return null if zero digits
4661 // were read, the integer value otherwise. When `len` is given, this
4662 // will return `null` unless the integer has exactly `len` digits.
4663
4664 pp$9.readInt = function(radix, len) {
4665 var start = this.pos, total = 0;
4666 for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
4667 var code = this.input.charCodeAt(this.pos), val = (void 0);
4668 if (code >= 97) { val = code - 97 + 10; } // a
4669 else if (code >= 65) { val = code - 65 + 10; } // A
4670 else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
4671 else { val = Infinity; }
4672 if (val >= radix) { break }
4673 ++this.pos;
4674 total = total * radix + val;
4675 }
4676 if (this.pos === start || len != null && this.pos - start !== len) { return null }
4677
4678 return total
4679 };
4680
4681 pp$9.readRadixNumber = function(radix) {
4682 var start = this.pos;
4683 this.pos += 2; // 0x
4684 var val = this.readInt(radix);
4685 if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
4686 if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
4687 val = typeof BigInt !== "undefined" ? BigInt(this.input.slice(start, this.pos)) : null;
4688 ++this.pos;
4689 } else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4690 return this.finishToken(types.num, val)
4691 };
4692
4693 // Read an integer, octal integer, or floating-point number.
4694
4695 pp$9.readNumber = function(startsWithDot) {
4696 var start = this.pos;
4697 if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
4698 var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
4699 if (octal && this.strict) { this.raise(start, "Invalid number"); }
4700 if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
4701 var next = this.input.charCodeAt(this.pos);
4702 if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
4703 var str$1 = this.input.slice(start, this.pos);
4704 var val$1 = typeof BigInt !== "undefined" ? BigInt(str$1) : null;
4705 ++this.pos;
4706 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4707 return this.finishToken(types.num, val$1)
4708 }
4709 if (next === 46 && !octal) { // '.'
4710 ++this.pos;
4711 this.readInt(10);
4712 next = this.input.charCodeAt(this.pos);
4713 }
4714 if ((next === 69 || next === 101) && !octal) { // 'eE'
4715 next = this.input.charCodeAt(++this.pos);
4716 if (next === 43 || next === 45) { ++this.pos; } // '+-'
4717 if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
4718 }
4719 if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
4720
4721 var str = this.input.slice(start, this.pos);
4722 var val = octal ? parseInt(str, 8) : parseFloat(str);
4723 return this.finishToken(types.num, val)
4724 };
4725
4726 // Read a string value, interpreting backslash-escapes.
4727
4728 pp$9.readCodePoint = function() {
4729 var ch = this.input.charCodeAt(this.pos), code;
4730
4731 if (ch === 123) { // '{'
4732 if (this.options.ecmaVersion < 6) { this.unexpected(); }
4733 var codePos = ++this.pos;
4734 code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
4735 ++this.pos;
4736 if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
4737 } else {
4738 code = this.readHexChar(4);
4739 }
4740 return code
4741 };
4742
4743 function codePointToString$1(code) {
4744 // UTF-16 Decoding
4745 if (code <= 0xFFFF) { return String.fromCharCode(code) }
4746 code -= 0x10000;
4747 return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
4748 }
4749
4750 pp$9.readString = function(quote) {
4751 var out = "", chunkStart = ++this.pos;
4752 for (;;) {
4753 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
4754 var ch = this.input.charCodeAt(this.pos);
4755 if (ch === quote) { break }
4756 if (ch === 92) { // '\'
4757 out += this.input.slice(chunkStart, this.pos);
4758 out += this.readEscapedChar(false);
4759 chunkStart = this.pos;
4760 } else {
4761 if (isNewLine(ch, this.options.ecmaVersion >= 10)) { this.raise(this.start, "Unterminated string constant"); }
4762 ++this.pos;
4763 }
4764 }
4765 out += this.input.slice(chunkStart, this.pos++);
4766 return this.finishToken(types.string, out)
4767 };
4768
4769 // Reads template string tokens.
4770
4771 var INVALID_TEMPLATE_ESCAPE_ERROR = {};
4772
4773 pp$9.tryReadTemplateToken = function() {
4774 this.inTemplateElement = true;
4775 try {
4776 this.readTmplToken();
4777 } catch (err) {
4778 if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
4779 this.readInvalidTemplateToken();
4780 } else {
4781 throw err
4782 }
4783 }
4784
4785 this.inTemplateElement = false;
4786 };
4787
4788 pp$9.invalidStringToken = function(position, message) {
4789 if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
4790 throw INVALID_TEMPLATE_ESCAPE_ERROR
4791 } else {
4792 this.raise(position, message);
4793 }
4794 };
4795
4796 pp$9.readTmplToken = function() {
4797 var out = "", chunkStart = this.pos;
4798 for (;;) {
4799 if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
4800 var ch = this.input.charCodeAt(this.pos);
4801 if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
4802 if (this.pos === this.start && (this.type === types.template || this.type === types.invalidTemplate)) {
4803 if (ch === 36) {
4804 this.pos += 2;
4805 return this.finishToken(types.dollarBraceL)
4806 } else {
4807 ++this.pos;
4808 return this.finishToken(types.backQuote)
4809 }
4810 }
4811 out += this.input.slice(chunkStart, this.pos);
4812 return this.finishToken(types.template, out)
4813 }
4814 if (ch === 92) { // '\'
4815 out += this.input.slice(chunkStart, this.pos);
4816 out += this.readEscapedChar(true);
4817 chunkStart = this.pos;
4818 } else if (isNewLine(ch)) {
4819 out += this.input.slice(chunkStart, this.pos);
4820 ++this.pos;
4821 switch (ch) {
4822 case 13:
4823 if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
4824 case 10:
4825 out += "\n";
4826 break
4827 default:
4828 out += String.fromCharCode(ch);
4829 break
4830 }
4831 if (this.options.locations) {
4832 ++this.curLine;
4833 this.lineStart = this.pos;
4834 }
4835 chunkStart = this.pos;
4836 } else {
4837 ++this.pos;
4838 }
4839 }
4840 };
4841
4842 // Reads a template token to search for the end, without validating any escape sequences
4843 pp$9.readInvalidTemplateToken = function() {
4844 for (; this.pos < this.input.length; this.pos++) {
4845 switch (this.input[this.pos]) {
4846 case "\\":
4847 ++this.pos;
4848 break
4849
4850 case "$":
4851 if (this.input[this.pos + 1] !== "{") {
4852 break
4853 }
4854 // falls through
4855
4856 case "`":
4857 return this.finishToken(types.invalidTemplate, this.input.slice(this.start, this.pos))
4858
4859 // no default
4860 }
4861 }
4862 this.raise(this.start, "Unterminated template");
4863 };
4864
4865 // Used to read escaped characters
4866
4867 pp$9.readEscapedChar = function(inTemplate) {
4868 var ch = this.input.charCodeAt(++this.pos);
4869 ++this.pos;
4870 switch (ch) {
4871 case 110: return "\n" // 'n' -> '\n'
4872 case 114: return "\r" // 'r' -> '\r'
4873 case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
4874 case 117: return codePointToString$1(this.readCodePoint()) // 'u'
4875 case 116: return "\t" // 't' -> '\t'
4876 case 98: return "\b" // 'b' -> '\b'
4877 case 118: return "\u000b" // 'v' -> '\u000b'
4878 case 102: return "\f" // 'f' -> '\f'
4879 case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
4880 case 10: // ' \n'
4881 if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
4882 return ""
4883 default:
4884 if (ch >= 48 && ch <= 55) {
4885 var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
4886 var octal = parseInt(octalStr, 8);
4887 if (octal > 255) {
4888 octalStr = octalStr.slice(0, -1);
4889 octal = parseInt(octalStr, 8);
4890 }
4891 this.pos += octalStr.length - 1;
4892 ch = this.input.charCodeAt(this.pos);
4893 if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
4894 this.invalidStringToken(
4895 this.pos - 1 - octalStr.length,
4896 inTemplate
4897 ? "Octal literal in template string"
4898 : "Octal literal in strict mode"
4899 );
4900 }
4901 return String.fromCharCode(octal)
4902 }
4903 if (isNewLine(ch)) {
4904 // Unicode new line characters after \ get removed from output in both
4905 // template literals and strings
4906 return ""
4907 }
4908 return String.fromCharCode(ch)
4909 }
4910 };
4911
4912 // Used to read character escape sequences ('\x', '\u', '\U').
4913
4914 pp$9.readHexChar = function(len) {
4915 var codePos = this.pos;
4916 var n = this.readInt(16, len);
4917 if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
4918 return n
4919 };
4920
4921 // Read an identifier, and return it as a string. Sets `this.containsEsc`
4922 // to whether the word contained a '\u' escape.
4923 //
4924 // Incrementally adds only escaped chars, adding other chunks as-is
4925 // as a micro-optimization.
4926
4927 pp$9.readWord1 = function() {
4928 this.containsEsc = false;
4929 var word = "", first = true, chunkStart = this.pos;
4930 var astral = this.options.ecmaVersion >= 6;
4931 while (this.pos < this.input.length) {
4932 var ch = this.fullCharCodeAtPos();
4933 if (isIdentifierChar(ch, astral)) {
4934 this.pos += ch <= 0xffff ? 1 : 2;
4935 } else if (ch === 92) { // "\"
4936 this.containsEsc = true;
4937 word += this.input.slice(chunkStart, this.pos);
4938 var escStart = this.pos;
4939 if (this.input.charCodeAt(++this.pos) !== 117) // "u"
4940 { this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
4941 ++this.pos;
4942 var esc = this.readCodePoint();
4943 if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
4944 { this.invalidStringToken(escStart, "Invalid Unicode escape"); }
4945 word += codePointToString$1(esc);
4946 chunkStart = this.pos;
4947 } else {
4948 break
4949 }
4950 first = false;
4951 }
4952 return word + this.input.slice(chunkStart, this.pos)
4953 };
4954
4955 // Read an identifier or keyword token. Will check for reserved
4956 // words when necessary.
4957
4958 pp$9.readWord = function() {
4959 var word = this.readWord1();
4960 var type = types.name;
4961 if (this.keywords.test(word)) {
4962 if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); }
4963 type = keywords$1[word];
4964 }
4965 return this.finishToken(type, word)
4966 };
4967
4968 // Acorn is a tiny, fast JavaScript parser written in JavaScript.
4969
4970 var version = "6.2.0";
4971
4972 // The main exported interface (under `self.acorn` when in the
4973 // browser) is a `parse` function that takes a code string and
4974 // returns an abstract syntax tree as specified by [Mozilla parser
4975 // API][api].
4976 //
4977 // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
4978
4979 function parse(input, options) {
4980 return Parser.parse(input, options)
4981 }
4982
4983 // This function tries to parse a single expression at a given
4984 // offset in a string. Useful for parsing mixed-language formats
4985 // that embed JavaScript expressions.
4986
4987 function parseExpressionAt(input, pos, options) {
4988 return Parser.parseExpressionAt(input, pos, options)
4989 }
4990
4991 // Acorn is organized as a tokenizer and a recursive-descent parser.
4992 // The `tokenizer` export provides an interface to the tokenizer.
4993
4994 function tokenizer(input, options) {
4995 return Parser.tokenizer(input, options)
4996 }
4997
4998 var acorn = /*#__PURE__*/Object.freeze({
4999 Node: Node,
5000 Parser: Parser,
5001 Position: Position,
5002 SourceLocation: SourceLocation,
5003 TokContext: TokContext,
5004 Token: Token,
5005 TokenType: TokenType,
5006 defaultOptions: defaultOptions,
5007 getLineInfo: getLineInfo,
5008 isIdentifierChar: isIdentifierChar,
5009 isIdentifierStart: isIdentifierStart,
5010 isNewLine: isNewLine,
5011 keywordTypes: keywords$1,
5012 lineBreak: lineBreak,
5013 lineBreakG: lineBreakG,
5014 nonASCIIwhitespace: nonASCIIwhitespace,
5015 parse: parse,
5016 parseExpressionAt: parseExpressionAt,
5017 tokContexts: types$1,
5018 tokTypes: types,
5019 tokenizer: tokenizer,
5020 version: version
5021 });
5022
5023 function unwrapExports (x) {
5024 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
5025 }
5026
5027 function createCommonjsModule(fn, module) {
5028 return module = { exports: {} }, fn(module, module.exports), module.exports;
5029 }
5030
5031 function getCjsExportFromNamespace (n) {
5032 return n && n['default'] || n;
5033 }
5034
5035 var _acorn = getCjsExportFromNamespace(acorn);
5036
5037 var lib = createCommonjsModule(function (module, exports) {
5038
5039 Object.defineProperty(exports, "__esModule", {
5040 value: true
5041 });
5042 exports.DynamicImportKey = undefined;
5043
5044 var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
5045
5046 var _get = function () {
5047 function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }
5048
5049 return get;
5050 }();
5051
5052 exports['default'] = dynamicImport;
5053
5054
5055
5056 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5057
5058 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
5059
5060 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable no-underscore-dangle */
5061
5062
5063 var DynamicImportKey = exports.DynamicImportKey = 'Import';
5064
5065 // NOTE: This allows `yield import()` to parse correctly.
5066 _acorn.tokTypes._import.startsExpr = true;
5067
5068 function parseDynamicImport() {
5069 var node = this.startNode();
5070 this.next();
5071 if (this.type !== _acorn.tokTypes.parenL) {
5072 this.unexpected();
5073 }
5074 return this.finishNode(node, DynamicImportKey);
5075 }
5076
5077 function parenAfter() {
5078 return (/^(\s|\/\/.*|\/\*[^]*?\*\/)*\(/.test(this.input.slice(this.pos))
5079 );
5080 }
5081
5082 function dynamicImport(Parser) {
5083 return function (_Parser) {
5084 _inherits(_class, _Parser);
5085
5086 function _class() {
5087 _classCallCheck(this, _class);
5088
5089 return _possibleConstructorReturn(this, (_class.__proto__ || Object.getPrototypeOf(_class)).apply(this, arguments));
5090 }
5091
5092 _createClass(_class, [{
5093 key: 'parseStatement',
5094 value: function () {
5095 function parseStatement(context, topLevel, exports) {
5096 if (this.type === _acorn.tokTypes._import && parenAfter.call(this)) {
5097 return this.parseExpressionStatement(this.startNode(), this.parseExpression());
5098 }
5099 return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'parseStatement', this).call(this, context, topLevel, exports);
5100 }
5101
5102 return parseStatement;
5103 }()
5104 }, {
5105 key: 'parseExprAtom',
5106 value: function () {
5107 function parseExprAtom(refDestructuringErrors) {
5108 if (this.type === _acorn.tokTypes._import) {
5109 return parseDynamicImport.call(this);
5110 }
5111 return _get(_class.prototype.__proto__ || Object.getPrototypeOf(_class.prototype), 'parseExprAtom', this).call(this, refDestructuringErrors);
5112 }
5113
5114 return parseExprAtom;
5115 }()
5116 }]);
5117
5118 return _class;
5119 }(Parser);
5120 }
5121 });
5122
5123 var dynamicImport = unwrapExports(lib);
5124 var lib_1 = lib.DynamicImportKey;
5125
5126 const Parser$1 = Parser.extend(dynamicImport);
5127 const parse$1 = (source) => Parser$1.parse(source, {
5128 sourceType: 'module',
5129 ecmaVersion: 9,
5130 preserveParens: true
5131 });
5132 const parse_expression_at = (source, index) => Parser$1.parseExpressionAt(source, index, {
5133 ecmaVersion: 9,
5134 preserveParens: true
5135 });
5136
5137 const literals = new Map([['true', true], ['false', false], ['null', null]]);
5138 function read_expression(parser) {
5139 const start = parser.index;
5140 const name = parser.read_until(/\s*}/);
5141 if (name && /^[a-z]+$/.test(name)) {
5142 const end = start + name.length;
5143 if (literals.has(name)) {
5144 // eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
5145 return {
5146 type: 'Literal',
5147 start,
5148 end,
5149 value: literals.get(name),
5150 raw: name,
5151 };
5152 }
5153 // eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
5154 return {
5155 type: 'Identifier',
5156 start,
5157 end: start + name.length,
5158 name,
5159 };
5160 }
5161 parser.index = start;
5162 try {
5163 const node = parse_expression_at(parser.template, parser.index);
5164 parser.index = node.end;
5165 return node;
5166 }
5167 catch (err) {
5168 parser.acorn_error(err);
5169 }
5170 }
5171
5172 function repeat(str, i) {
5173 let result = '';
5174 while (i--)
5175 result += str;
5176 return result;
5177 }
5178
5179 const script_closing_tag = '</script>';
5180 function get_context(parser, attributes, start) {
5181 const context = attributes.find(attribute => attribute.name === 'context');
5182 if (!context)
5183 return 'default';
5184 if (context.value.length !== 1 || context.value[0].type !== 'Text') {
5185 parser.error({
5186 code: 'invalid-script',
5187 message: `context attribute must be static`
5188 }, start);
5189 }
5190 const value = context.value[0].data;
5191 if (value !== 'module') {
5192 parser.error({
5193 code: `invalid-script`,
5194 message: `If the context attribute is supplied, its value must be "module"`
5195 }, context.start);
5196 }
5197 return value;
5198 }
5199 function read_script(parser, start, attributes) {
5200 const script_start = parser.index;
5201 const script_end = parser.template.indexOf(script_closing_tag, script_start);
5202 if (script_end === -1)
5203 parser.error({
5204 code: `unclosed-script`,
5205 message: `<script> must have a closing tag`
5206 });
5207 const source = repeat(' ', script_start) + parser.template.slice(script_start, script_end);
5208 parser.index = script_end + script_closing_tag.length;
5209 let ast;
5210 try {
5211 ast = parse$1(source);
5212 }
5213 catch (err) {
5214 parser.acorn_error(err);
5215 }
5216 ast.start = script_start;
5217 return {
5218 start,
5219 end: parser.index,
5220 context: get_context(parser, attributes, start),
5221 content: ast,
5222 };
5223 }
5224
5225 var MAX_LINE_LENGTH = 100;
5226 var OFFSET_CORRECTION = 60;
5227 var TAB_REPLACEMENT = ' ';
5228
5229 function sourceFragment(error, extraLines) {
5230 function processLines(start, end) {
5231 return lines.slice(start, end).map(function(line, idx) {
5232 var num = String(start + idx + 1);
5233
5234 while (num.length < maxNumLength) {
5235 num = ' ' + num;
5236 }
5237
5238 return num + ' |' + line;
5239 }).join('\n');
5240 }
5241
5242 var lines = error.source.split(/\n|\r\n?|\f/);
5243 var line = error.line;
5244 var column = error.column;
5245 var startLine = Math.max(1, line - extraLines) - 1;
5246 var endLine = Math.min(line + extraLines, lines.length + 1);
5247 var maxNumLength = Math.max(4, String(endLine).length) + 1;
5248 var cutLeft = 0;
5249
5250 // correct column according to replaced tab before column
5251 column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
5252
5253 if (column > MAX_LINE_LENGTH) {
5254 cutLeft = column - OFFSET_CORRECTION + 3;
5255 column = OFFSET_CORRECTION - 2;
5256 }
5257
5258 for (var i = startLine; i <= endLine; i++) {
5259 if (i >= 0 && i < lines.length) {
5260 lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
5261 lines[i] =
5262 (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
5263 lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
5264 (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
5265 }
5266 }
5267
5268 return [
5269 processLines(startLine, line),
5270 new Array(column + maxNumLength + 2).join('-') + '^',
5271 processLines(line, endLine)
5272 ].join('\n');
5273 }
5274
5275 var CssSyntaxError = function(message, source, offset, line, column) {
5276 // some VMs prevent setting line/column otherwise (iOS Safari 10 even throw an exception)
5277 var error = Object.create(SyntaxError.prototype);
5278
5279 error.name = 'CssSyntaxError';
5280 error.message = message;
5281 error.stack = (new Error().stack || '').replace(/^.+\n/, error.name + ': ' + error.message + '\n');
5282 error.source = source;
5283 error.offset = offset;
5284 error.line = line;
5285 error.column = column;
5286
5287 error.sourceFragment = function(extraLines) {
5288 return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
5289 };
5290 Object.defineProperty(error, 'formattedMessage', {
5291 get: function() {
5292 return (
5293 'Parse error: ' + error.message + '\n' +
5294 sourceFragment(error, 2)
5295 );
5296 }
5297 });
5298
5299 // for backward capability
5300 error.parseError = {
5301 offset: offset,
5302 line: line,
5303 column: column
5304 };
5305
5306 return error;
5307 };
5308
5309 var error = CssSyntaxError;
5310
5311 // token types (note: value shouldn't intersect with used char codes)
5312 var WHITESPACE = 1;
5313 var IDENTIFIER = 2;
5314 var NUMBER = 3;
5315 var STRING = 4;
5316 var COMMENT = 5;
5317 var PUNCTUATOR = 6;
5318 var CDO = 7;
5319 var CDC = 8;
5320 var ATRULE = 14;
5321 var FUNCTION = 15;
5322 var URL = 16;
5323 var RAW = 17;
5324
5325 var TAB = 9;
5326 var N = 10;
5327 var F = 12;
5328 var R = 13;
5329 var SPACE = 32;
5330
5331 var TYPE = {
5332 WhiteSpace: WHITESPACE,
5333 Identifier: IDENTIFIER,
5334 Number: NUMBER,
5335 String: STRING,
5336 Comment: COMMENT,
5337 Punctuator: PUNCTUATOR,
5338 CDO: CDO,
5339 CDC: CDC,
5340 Atrule: ATRULE,
5341 Function: FUNCTION,
5342 Url: URL,
5343 Raw: RAW,
5344
5345 ExclamationMark: 33, // !
5346 QuotationMark: 34, // "
5347 NumberSign: 35, // #
5348 DollarSign: 36, // $
5349 PercentSign: 37, // %
5350 Ampersand: 38, // &
5351 Apostrophe: 39, // '
5352 LeftParenthesis: 40, // (
5353 RightParenthesis: 41, // )
5354 Asterisk: 42, // *
5355 PlusSign: 43, // +
5356 Comma: 44, // ,
5357 HyphenMinus: 45, // -
5358 FullStop: 46, // .
5359 Solidus: 47, // /
5360 Colon: 58, // :
5361 Semicolon: 59, // ;
5362 LessThanSign: 60, // <
5363 EqualsSign: 61, // =
5364 GreaterThanSign: 62, // >
5365 QuestionMark: 63, // ?
5366 CommercialAt: 64, // @
5367 LeftSquareBracket: 91, // [
5368 Backslash: 92, // \
5369 RightSquareBracket: 93, // ]
5370 CircumflexAccent: 94, // ^
5371 LowLine: 95, // _
5372 GraveAccent: 96, // `
5373 LeftCurlyBracket: 123, // {
5374 VerticalLine: 124, // |
5375 RightCurlyBracket: 125, // }
5376 Tilde: 126 // ~
5377 };
5378
5379 var NAME = Object.keys(TYPE).reduce(function(result, key) {
5380 result[TYPE[key]] = key;
5381 return result;
5382 }, {});
5383
5384 // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
5385 // > non-ASCII code point
5386 // > A code point with a value equal to or greater than U+0080 <control>
5387 // > name-start code point
5388 // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
5389 // > name code point
5390 // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
5391 // That means only ASCII code points has a special meaning and we a maps for 0..127 codes only
5392 var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
5393 var SYMBOL_TYPE = new SafeUint32Array(0x80);
5394 var PUNCTUATION = new SafeUint32Array(0x80);
5395 var STOP_URL_RAW = new SafeUint32Array(0x80);
5396
5397 for (var i = 0; i < SYMBOL_TYPE.length; i++) {
5398 SYMBOL_TYPE[i] = IDENTIFIER;
5399 }
5400
5401 // fill categories
5402 [
5403 TYPE.ExclamationMark, // !
5404 TYPE.QuotationMark, // "
5405 TYPE.NumberSign, // #
5406 TYPE.DollarSign, // $
5407 TYPE.PercentSign, // %
5408 TYPE.Ampersand, // &
5409 TYPE.Apostrophe, // '
5410 TYPE.LeftParenthesis, // (
5411 TYPE.RightParenthesis, // )
5412 TYPE.Asterisk, // *
5413 TYPE.PlusSign, // +
5414 TYPE.Comma, // ,
5415 TYPE.HyphenMinus, // -
5416 TYPE.FullStop, // .
5417 TYPE.Solidus, // /
5418 TYPE.Colon, // :
5419 TYPE.Semicolon, // ;
5420 TYPE.LessThanSign, // <
5421 TYPE.EqualsSign, // =
5422 TYPE.GreaterThanSign, // >
5423 TYPE.QuestionMark, // ?
5424 TYPE.CommercialAt, // @
5425 TYPE.LeftSquareBracket, // [
5426 // TYPE.Backslash, // \
5427 TYPE.RightSquareBracket, // ]
5428 TYPE.CircumflexAccent, // ^
5429 // TYPE.LowLine, // _
5430 TYPE.GraveAccent, // `
5431 TYPE.LeftCurlyBracket, // {
5432 TYPE.VerticalLine, // |
5433 TYPE.RightCurlyBracket, // }
5434 TYPE.Tilde // ~
5435 ].forEach(function(key) {
5436 SYMBOL_TYPE[Number(key)] = PUNCTUATOR;
5437 PUNCTUATION[Number(key)] = PUNCTUATOR;
5438 });
5439
5440 for (var i = 48; i <= 57; i++) {
5441 SYMBOL_TYPE[i] = NUMBER;
5442 }
5443
5444 SYMBOL_TYPE[SPACE] = WHITESPACE;
5445 SYMBOL_TYPE[TAB] = WHITESPACE;
5446 SYMBOL_TYPE[N] = WHITESPACE;
5447 SYMBOL_TYPE[R] = WHITESPACE;
5448 SYMBOL_TYPE[F] = WHITESPACE;
5449
5450 SYMBOL_TYPE[TYPE.Apostrophe] = STRING;
5451 SYMBOL_TYPE[TYPE.QuotationMark] = STRING;
5452
5453 STOP_URL_RAW[SPACE] = 1;
5454 STOP_URL_RAW[TAB] = 1;
5455 STOP_URL_RAW[N] = 1;
5456 STOP_URL_RAW[R] = 1;
5457 STOP_URL_RAW[F] = 1;
5458 STOP_URL_RAW[TYPE.Apostrophe] = 1;
5459 STOP_URL_RAW[TYPE.QuotationMark] = 1;
5460 STOP_URL_RAW[TYPE.LeftParenthesis] = 1;
5461 STOP_URL_RAW[TYPE.RightParenthesis] = 1;
5462
5463 // whitespace is punctuation ...
5464 PUNCTUATION[SPACE] = PUNCTUATOR;
5465 PUNCTUATION[TAB] = PUNCTUATOR;
5466 PUNCTUATION[N] = PUNCTUATOR;
5467 PUNCTUATION[R] = PUNCTUATOR;
5468 PUNCTUATION[F] = PUNCTUATOR;
5469 // ... hyper minus is not
5470 PUNCTUATION[TYPE.HyphenMinus] = 0;
5471
5472 var _const = {
5473 TYPE: TYPE,
5474 NAME: NAME,
5475
5476 SYMBOL_TYPE: SYMBOL_TYPE,
5477 PUNCTUATION: PUNCTUATION,
5478 STOP_URL_RAW: STOP_URL_RAW
5479 };
5480
5481 var PUNCTUATION$1 = _const.PUNCTUATION;
5482 var STOP_URL_RAW$1 = _const.STOP_URL_RAW;
5483 var TYPE$1 = _const.TYPE;
5484 var FULLSTOP = TYPE$1.FullStop;
5485 var PLUSSIGN = TYPE$1.PlusSign;
5486 var HYPHENMINUS = TYPE$1.HyphenMinus;
5487 var PUNCTUATOR$1 = TYPE$1.Punctuator;
5488 var TAB$1 = 9;
5489 var N$1 = 10;
5490 var F$1 = 12;
5491 var R$1 = 13;
5492 var SPACE$1 = 32;
5493 var BACK_SLASH = 92;
5494 var E = 101; // 'e'.charCodeAt(0)
5495
5496 function firstCharOffset(source) {
5497 // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
5498 if (source.charCodeAt(0) === 0xFEFF || // UTF-16BE
5499 source.charCodeAt(0) === 0xFFFE) { // UTF-16LE
5500 return 1;
5501 }
5502
5503 return 0;
5504 }
5505
5506 function isHex(code) {
5507 return (code >= 48 && code <= 57) || // 0 .. 9
5508 (code >= 65 && code <= 70) || // A .. F
5509 (code >= 97 && code <= 102); // a .. f
5510 }
5511
5512 function isNumber(code) {
5513 return code >= 48 && code <= 57;
5514 }
5515
5516 function isNewline(source, offset, code) {
5517 if (code === N$1 || code === F$1 || code === R$1) {
5518 if (code === R$1 && offset + 1 < source.length && source.charCodeAt(offset + 1) === N$1) {
5519 return 2;
5520 }
5521
5522 return 1;
5523 }
5524
5525 return 0;
5526 }
5527
5528 function cmpChar(testStr, offset, referenceCode) {
5529 var code = testStr.charCodeAt(offset);
5530
5531 // code.toLowerCase()
5532 if (code >= 65 && code <= 90) {
5533 code = code | 32;
5534 }
5535
5536 return code === referenceCode;
5537 }
5538
5539 function cmpStr(testStr, start, end, referenceStr) {
5540 if (end - start !== referenceStr.length) {
5541 return false;
5542 }
5543
5544 if (start < 0 || end > testStr.length) {
5545 return false;
5546 }
5547
5548 for (var i = start; i < end; i++) {
5549 var testCode = testStr.charCodeAt(i);
5550 var refCode = referenceStr.charCodeAt(i - start);
5551
5552 // testStr[i].toLowerCase()
5553 if (testCode >= 65 && testCode <= 90) {
5554 testCode = testCode | 32;
5555 }
5556
5557 if (testCode !== refCode) {
5558 return false;
5559 }
5560 }
5561
5562 return true;
5563 }
5564
5565 function endsWith(testStr, referenceStr) {
5566 return cmpStr(testStr, testStr.length - referenceStr.length, testStr.length, referenceStr);
5567 }
5568
5569 function findLastNonSpaceLocation(scanner) {
5570 for (var i = scanner.source.length - 1; i >= 0; i--) {
5571 var code = scanner.source.charCodeAt(i);
5572
5573 if (code !== SPACE$1 && code !== TAB$1 && code !== R$1 && code !== N$1 && code !== F$1) {
5574 break;
5575 }
5576 }
5577
5578 return scanner.getLocation(i + 1);
5579 }
5580
5581 function findWhiteSpaceEnd(source, offset) {
5582 for (; offset < source.length; offset++) {
5583 var code = source.charCodeAt(offset);
5584
5585 if (code !== SPACE$1 && code !== TAB$1 && code !== R$1 && code !== N$1 && code !== F$1) {
5586 break;
5587 }
5588 }
5589
5590 return offset;
5591 }
5592
5593 function findCommentEnd(source, offset) {
5594 var commentEnd = source.indexOf('*/', offset);
5595
5596 if (commentEnd === -1) {
5597 return source.length;
5598 }
5599
5600 return commentEnd + 2;
5601 }
5602
5603 function findStringEnd(source, offset, quote) {
5604 for (; offset < source.length; offset++) {
5605 var code = source.charCodeAt(offset);
5606
5607 // TODO: bad string
5608 if (code === BACK_SLASH) {
5609 offset++;
5610 } else if (code === quote) {
5611 offset++;
5612 break;
5613 }
5614 }
5615
5616 return offset;
5617 }
5618
5619 function findDecimalNumberEnd(source, offset) {
5620 for (; offset < source.length; offset++) {
5621 var code = source.charCodeAt(offset);
5622
5623 if (code < 48 || code > 57) { // not a 0 .. 9
5624 break;
5625 }
5626 }
5627
5628 return offset;
5629 }
5630
5631 function findNumberEnd(source, offset, allowFraction) {
5632 var code;
5633
5634 offset = findDecimalNumberEnd(source, offset);
5635
5636 // fraction: .\d+
5637 if (allowFraction && offset + 1 < source.length && source.charCodeAt(offset) === FULLSTOP) {
5638 code = source.charCodeAt(offset + 1);
5639
5640 if (isNumber(code)) {
5641 offset = findDecimalNumberEnd(source, offset + 1);
5642 }
5643 }
5644
5645 // exponent: e[+-]\d+
5646 if (offset + 1 < source.length) {
5647 if ((source.charCodeAt(offset) | 32) === E) { // case insensitive check for `e`
5648 code = source.charCodeAt(offset + 1);
5649
5650 if (code === PLUSSIGN || code === HYPHENMINUS) {
5651 if (offset + 2 < source.length) {
5652 code = source.charCodeAt(offset + 2);
5653 }
5654 }
5655
5656 if (isNumber(code)) {
5657 offset = findDecimalNumberEnd(source, offset + 2);
5658 }
5659 }
5660 }
5661
5662 return offset;
5663 }
5664
5665 // skip escaped unicode sequence that can ends with space
5666 // [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
5667 function findEscaseEnd(source, offset) {
5668 for (var i = 0; i < 7 && offset + i < source.length; i++) {
5669 var code = source.charCodeAt(offset + i);
5670
5671 if (i !== 6 && isHex(code)) {
5672 continue;
5673 }
5674
5675 if (i > 0) {
5676 offset += i - 1 + isNewline(source, offset + i, code);
5677 if (code === SPACE$1 || code === TAB$1) {
5678 offset++;
5679 }
5680 }
5681
5682 break;
5683 }
5684
5685 return offset;
5686 }
5687
5688 function findIdentifierEnd(source, offset) {
5689 for (; offset < source.length; offset++) {
5690 var code = source.charCodeAt(offset);
5691
5692 if (code === BACK_SLASH) {
5693 offset = findEscaseEnd(source, offset + 1);
5694 } else if (code < 0x80 && PUNCTUATION$1[code] === PUNCTUATOR$1) {
5695 break;
5696 }
5697 }
5698
5699 return offset;
5700 }
5701
5702 function findUrlRawEnd(source, offset) {
5703 for (; offset < source.length; offset++) {
5704 var code = source.charCodeAt(offset);
5705
5706 if (code === BACK_SLASH) {
5707 offset = findEscaseEnd(source, offset + 1);
5708 } else if (code < 0x80 && STOP_URL_RAW$1[code] === 1) {
5709 break;
5710 }
5711 }
5712
5713 return offset;
5714 }
5715
5716 var utils = {
5717 firstCharOffset: firstCharOffset,
5718
5719 isHex: isHex,
5720 isNumber: isNumber,
5721 isNewline: isNewline,
5722
5723 cmpChar: cmpChar,
5724 cmpStr: cmpStr,
5725 endsWith: endsWith,
5726
5727 findLastNonSpaceLocation: findLastNonSpaceLocation,
5728 findWhiteSpaceEnd: findWhiteSpaceEnd,
5729 findCommentEnd: findCommentEnd,
5730 findStringEnd: findStringEnd,
5731 findDecimalNumberEnd: findDecimalNumberEnd,
5732 findNumberEnd: findNumberEnd,
5733 findEscaseEnd: findEscaseEnd,
5734 findIdentifierEnd: findIdentifierEnd,
5735 findUrlRawEnd: findUrlRawEnd
5736 };
5737
5738 var TYPE$2 = _const.TYPE;
5739 var NAME$1 = _const.NAME;
5740 var SYMBOL_TYPE$1 = _const.SYMBOL_TYPE;
5741
5742
5743 var firstCharOffset$1 = utils.firstCharOffset;
5744 var cmpStr$1 = utils.cmpStr;
5745 var isNumber$1 = utils.isNumber;
5746 var findLastNonSpaceLocation$1 = utils.findLastNonSpaceLocation;
5747 var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
5748 var findCommentEnd$1 = utils.findCommentEnd;
5749 var findStringEnd$1 = utils.findStringEnd;
5750 var findNumberEnd$1 = utils.findNumberEnd;
5751 var findIdentifierEnd$1 = utils.findIdentifierEnd;
5752 var findUrlRawEnd$1 = utils.findUrlRawEnd;
5753
5754 var NULL = 0;
5755 var WHITESPACE$1 = TYPE$2.WhiteSpace;
5756 var IDENTIFIER$1 = TYPE$2.Identifier;
5757 var NUMBER$1 = TYPE$2.Number;
5758 var STRING$1 = TYPE$2.String;
5759 var COMMENT$1 = TYPE$2.Comment;
5760 var PUNCTUATOR$2 = TYPE$2.Punctuator;
5761 var CDO$1 = TYPE$2.CDO;
5762 var CDC$1 = TYPE$2.CDC;
5763 var ATRULE$1 = TYPE$2.Atrule;
5764 var FUNCTION$1 = TYPE$2.Function;
5765 var URL$1 = TYPE$2.Url;
5766 var RAW$1 = TYPE$2.Raw;
5767
5768 var N$2 = 10;
5769 var F$2 = 12;
5770 var R$2 = 13;
5771 var STAR = TYPE$2.Asterisk;
5772 var SLASH = TYPE$2.Solidus;
5773 var FULLSTOP$1 = TYPE$2.FullStop;
5774 var PLUSSIGN$1 = TYPE$2.PlusSign;
5775 var HYPHENMINUS$1 = TYPE$2.HyphenMinus;
5776 var GREATERTHANSIGN = TYPE$2.GreaterThanSign;
5777 var LESSTHANSIGN = TYPE$2.LessThanSign;
5778 var EXCLAMATIONMARK = TYPE$2.ExclamationMark;
5779 var COMMERCIALAT = TYPE$2.CommercialAt;
5780 var QUOTATIONMARK = TYPE$2.QuotationMark;
5781 var APOSTROPHE = TYPE$2.Apostrophe;
5782 var LEFTPARENTHESIS = TYPE$2.LeftParenthesis;
5783 var RIGHTPARENTHESIS = TYPE$2.RightParenthesis;
5784 var LEFTCURLYBRACKET = TYPE$2.LeftCurlyBracket;
5785 var RIGHTCURLYBRACKET = TYPE$2.RightCurlyBracket;
5786 var LEFTSQUAREBRACKET = TYPE$2.LeftSquareBracket;
5787 var RIGHTSQUAREBRACKET = TYPE$2.RightSquareBracket;
5788
5789 var MIN_BUFFER_SIZE = 16 * 1024;
5790 var OFFSET_MASK = 0x00FFFFFF;
5791 var TYPE_SHIFT = 24;
5792 var SafeUint32Array$1 = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
5793
5794 function computeLinesAndColumns(tokenizer, source) {
5795 var sourceLength = source.length;
5796 var start = firstCharOffset$1(source);
5797 var lines = tokenizer.lines;
5798 var line = tokenizer.startLine;
5799 var columns = tokenizer.columns;
5800 var column = tokenizer.startColumn;
5801
5802 if (lines === null || lines.length < sourceLength + 1) {
5803 lines = new SafeUint32Array$1(Math.max(sourceLength + 1024, MIN_BUFFER_SIZE));
5804 columns = new SafeUint32Array$1(lines.length);
5805 }
5806
5807 for (var i = start; i < sourceLength; i++) {
5808 var code = source.charCodeAt(i);
5809
5810 lines[i] = line;
5811 columns[i] = column++;
5812
5813 if (code === N$2 || code === R$2 || code === F$2) {
5814 if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$2) {
5815 i++;
5816 lines[i] = line;
5817 columns[i] = column;
5818 }
5819
5820 line++;
5821 column = 1;
5822 }
5823 }
5824
5825 lines[i] = line;
5826 columns[i] = column;
5827
5828 tokenizer.linesAnsColumnsComputed = true;
5829 tokenizer.lines = lines;
5830 tokenizer.columns = columns;
5831 }
5832
5833 function tokenLayout(tokenizer, source, startPos) {
5834 var sourceLength = source.length;
5835 var offsetAndType = tokenizer.offsetAndType;
5836 var balance = tokenizer.balance;
5837 var tokenCount = 0;
5838 var prevType = 0;
5839 var offset = startPos;
5840 var anchor = 0;
5841 var balanceCloseCode = 0;
5842 var balanceStart = 0;
5843 var balancePrev = 0;
5844
5845 if (offsetAndType === null || offsetAndType.length < sourceLength + 1) {
5846 offsetAndType = new SafeUint32Array$1(sourceLength + 1024);
5847 balance = new SafeUint32Array$1(sourceLength + 1024);
5848 }
5849
5850 while (offset < sourceLength) {
5851 var code = source.charCodeAt(offset);
5852 var type = code < 0x80 ? SYMBOL_TYPE$1[code] : IDENTIFIER$1;
5853
5854 balance[tokenCount] = sourceLength;
5855
5856 switch (type) {
5857 case WHITESPACE$1:
5858 offset = findWhiteSpaceEnd$1(source, offset + 1);
5859 break;
5860
5861 case PUNCTUATOR$2:
5862 switch (code) {
5863 case balanceCloseCode:
5864 balancePrev = balanceStart & OFFSET_MASK;
5865 balanceStart = balance[balancePrev];
5866 balanceCloseCode = balanceStart >> TYPE_SHIFT;
5867 balance[tokenCount] = balancePrev;
5868 balance[balancePrev++] = tokenCount;
5869 for (; balancePrev < tokenCount; balancePrev++) {
5870 if (balance[balancePrev] === sourceLength) {
5871 balance[balancePrev] = tokenCount;
5872 }
5873 }
5874 break;
5875
5876 case LEFTSQUAREBRACKET:
5877 balance[tokenCount] = balanceStart;
5878 balanceCloseCode = RIGHTSQUAREBRACKET;
5879 balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
5880 break;
5881
5882 case LEFTCURLYBRACKET:
5883 balance[tokenCount] = balanceStart;
5884 balanceCloseCode = RIGHTCURLYBRACKET;
5885 balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
5886 break;
5887
5888 case LEFTPARENTHESIS:
5889 balance[tokenCount] = balanceStart;
5890 balanceCloseCode = RIGHTPARENTHESIS;
5891 balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
5892 break;
5893 }
5894
5895 // /*
5896 if (code === STAR && prevType === SLASH) {
5897 type = COMMENT$1;
5898 offset = findCommentEnd$1(source, offset + 1);
5899 tokenCount--; // rewrite prev token
5900 break;
5901 }
5902
5903 // edge case for -.123 and +.123
5904 if (code === FULLSTOP$1 && (prevType === PLUSSIGN$1 || prevType === HYPHENMINUS$1)) {
5905 if (offset + 1 < sourceLength && isNumber$1(source.charCodeAt(offset + 1))) {
5906 type = NUMBER$1;
5907 offset = findNumberEnd$1(source, offset + 2, false);
5908 tokenCount--; // rewrite prev token
5909 break;
5910 }
5911 }
5912
5913 // <!--
5914 if (code === EXCLAMATIONMARK && prevType === LESSTHANSIGN) {
5915 if (offset + 2 < sourceLength &&
5916 source.charCodeAt(offset + 1) === HYPHENMINUS$1 &&
5917 source.charCodeAt(offset + 2) === HYPHENMINUS$1) {
5918 type = CDO$1;
5919 offset = offset + 3;
5920 tokenCount--; // rewrite prev token
5921 break;
5922 }
5923 }
5924
5925 // -->
5926 if (code === HYPHENMINUS$1 && prevType === HYPHENMINUS$1) {
5927 if (offset + 1 < sourceLength && source.charCodeAt(offset + 1) === GREATERTHANSIGN) {
5928 type = CDC$1;
5929 offset = offset + 2;
5930 tokenCount--; // rewrite prev token
5931 break;
5932 }
5933 }
5934
5935 // ident(
5936 if (code === LEFTPARENTHESIS && prevType === IDENTIFIER$1) {
5937 offset = offset + 1;
5938 tokenCount--; // rewrite prev token
5939 balance[tokenCount] = balance[tokenCount + 1];
5940 balanceStart--;
5941
5942 // 4 char length identifier and equal to `url(` (case insensitive)
5943 if (offset - anchor === 4 && cmpStr$1(source, anchor, offset, 'url(')) {
5944 // special case for url() because it can contain any symbols sequence with few exceptions
5945 anchor = findWhiteSpaceEnd$1(source, offset);
5946 code = source.charCodeAt(anchor);
5947 if (code !== LEFTPARENTHESIS &&
5948 code !== RIGHTPARENTHESIS &&
5949 code !== QUOTATIONMARK &&
5950 code !== APOSTROPHE) {
5951 // url(
5952 offsetAndType[tokenCount++] = (URL$1 << TYPE_SHIFT) | offset;
5953 balance[tokenCount] = sourceLength;
5954
5955 // ws*
5956 if (anchor !== offset) {
5957 offsetAndType[tokenCount++] = (WHITESPACE$1 << TYPE_SHIFT) | anchor;
5958 balance[tokenCount] = sourceLength;
5959 }
5960
5961 // raw
5962 type = RAW$1;
5963 offset = findUrlRawEnd$1(source, anchor);
5964 } else {
5965 type = URL$1;
5966 }
5967 } else {
5968 type = FUNCTION$1;
5969 }
5970 break;
5971 }
5972
5973 type = code;
5974 offset = offset + 1;
5975 break;
5976
5977 case NUMBER$1:
5978 offset = findNumberEnd$1(source, offset + 1, prevType !== FULLSTOP$1);
5979
5980 // merge number with a preceding dot, dash or plus
5981 if (prevType === FULLSTOP$1 ||
5982 prevType === HYPHENMINUS$1 ||
5983 prevType === PLUSSIGN$1) {
5984 tokenCount--; // rewrite prev token
5985 }
5986
5987 break;
5988
5989 case STRING$1:
5990 offset = findStringEnd$1(source, offset + 1, code);
5991 break;
5992
5993 default:
5994 anchor = offset;
5995 offset = findIdentifierEnd$1(source, offset);
5996
5997 // merge identifier with a preceding dash
5998 if (prevType === HYPHENMINUS$1) {
5999 // rewrite prev token
6000 tokenCount--;
6001 // restore prev prev token type
6002 // for case @-prefix-ident
6003 prevType = tokenCount === 0 ? 0 : offsetAndType[tokenCount - 1] >> TYPE_SHIFT;
6004 }
6005
6006 if (prevType === COMMERCIALAT) {
6007 // rewrite prev token and change type to <at-keyword-token>
6008 tokenCount--;
6009 type = ATRULE$1;
6010 }
6011 }
6012
6013 offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | offset;
6014 prevType = type;
6015 }
6016
6017 // finalize arrays
6018 offsetAndType[tokenCount] = offset;
6019 balance[tokenCount] = sourceLength;
6020 while (balanceStart !== 0) {
6021 balancePrev = balanceStart & OFFSET_MASK;
6022 balanceStart = balance[balancePrev];
6023 balance[balancePrev] = sourceLength;
6024 }
6025
6026 tokenizer.offsetAndType = offsetAndType;
6027 tokenizer.tokenCount = tokenCount;
6028 tokenizer.balance = balance;
6029 }
6030
6031 //
6032 // tokenizer
6033 //
6034
6035 var Tokenizer = function(source, startOffset, startLine, startColumn) {
6036 this.offsetAndType = null;
6037 this.balance = null;
6038 this.lines = null;
6039 this.columns = null;
6040
6041 this.setSource(source, startOffset, startLine, startColumn);
6042 };
6043
6044 Tokenizer.prototype = {
6045 setSource: function(source, startOffset, startLine, startColumn) {
6046 var safeSource = String(source || '');
6047 var start = firstCharOffset$1(safeSource);
6048
6049 this.source = safeSource;
6050 this.firstCharOffset = start;
6051 this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
6052 this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
6053 this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
6054 this.linesAnsColumnsComputed = false;
6055
6056 this.eof = false;
6057 this.currentToken = -1;
6058 this.tokenType = 0;
6059 this.tokenStart = start;
6060 this.tokenEnd = start;
6061
6062 tokenLayout(this, safeSource, start);
6063 this.next();
6064 },
6065
6066 lookupType: function(offset) {
6067 offset += this.currentToken;
6068
6069 if (offset < this.tokenCount) {
6070 return this.offsetAndType[offset] >> TYPE_SHIFT;
6071 }
6072
6073 return NULL;
6074 },
6075 lookupNonWSType: function(offset) {
6076 offset += this.currentToken;
6077
6078 for (var type; offset < this.tokenCount; offset++) {
6079 type = this.offsetAndType[offset] >> TYPE_SHIFT;
6080
6081 if (type !== WHITESPACE$1) {
6082 return type;
6083 }
6084 }
6085
6086 return NULL;
6087 },
6088 lookupValue: function(offset, referenceStr) {
6089 offset += this.currentToken;
6090
6091 if (offset < this.tokenCount) {
6092 return cmpStr$1(
6093 this.source,
6094 this.offsetAndType[offset - 1] & OFFSET_MASK,
6095 this.offsetAndType[offset] & OFFSET_MASK,
6096 referenceStr
6097 );
6098 }
6099
6100 return false;
6101 },
6102 getTokenStart: function(tokenNum) {
6103 if (tokenNum === this.currentToken) {
6104 return this.tokenStart;
6105 }
6106
6107 if (tokenNum > 0) {
6108 return tokenNum < this.tokenCount
6109 ? this.offsetAndType[tokenNum - 1] & OFFSET_MASK
6110 : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
6111 }
6112
6113 return this.firstCharOffset;
6114 },
6115 getOffsetExcludeWS: function() {
6116 if (this.currentToken > 0) {
6117 if ((this.offsetAndType[this.currentToken - 1] >> TYPE_SHIFT) === WHITESPACE$1) {
6118 return this.currentToken > 1
6119 ? this.offsetAndType[this.currentToken - 2] & OFFSET_MASK
6120 : this.firstCharOffset;
6121 }
6122 }
6123 return this.tokenStart;
6124 },
6125 getRawLength: function(startToken, endTokenType1, endTokenType2, includeTokenType2) {
6126 var cursor = startToken;
6127 var balanceEnd;
6128
6129 loop:
6130 for (; cursor < this.tokenCount; cursor++) {
6131 balanceEnd = this.balance[cursor];
6132
6133 // belance end points to offset before start
6134 if (balanceEnd < startToken) {
6135 break loop;
6136 }
6137
6138 // check token is stop type
6139 switch (this.offsetAndType[cursor] >> TYPE_SHIFT) {
6140 case endTokenType1:
6141 break loop;
6142
6143 case endTokenType2:
6144 if (includeTokenType2) {
6145 cursor++;
6146 }
6147 break loop;
6148
6149 default:
6150 // fast forward to the end of balanced block
6151 if (this.balance[balanceEnd] === cursor) {
6152 cursor = balanceEnd;
6153 }
6154 }
6155
6156 }
6157
6158 return cursor - this.currentToken;
6159 },
6160
6161 getTokenValue: function() {
6162 return this.source.substring(this.tokenStart, this.tokenEnd);
6163 },
6164 substrToCursor: function(start) {
6165 return this.source.substring(start, this.tokenStart);
6166 },
6167
6168 skipWS: function() {
6169 for (var i = this.currentToken, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
6170 if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE$1) {
6171 break;
6172 }
6173 }
6174
6175 if (skipTokenCount > 0) {
6176 this.skip(skipTokenCount);
6177 }
6178 },
6179 skipSC: function() {
6180 while (this.tokenType === WHITESPACE$1 || this.tokenType === COMMENT$1) {
6181 this.next();
6182 }
6183 },
6184 skip: function(tokenCount) {
6185 var next = this.currentToken + tokenCount;
6186
6187 if (next < this.tokenCount) {
6188 this.currentToken = next;
6189 this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
6190 next = this.offsetAndType[next];
6191 this.tokenType = next >> TYPE_SHIFT;
6192 this.tokenEnd = next & OFFSET_MASK;
6193 } else {
6194 this.currentToken = this.tokenCount;
6195 this.next();
6196 }
6197 },
6198 next: function() {
6199 var next = this.currentToken + 1;
6200
6201 if (next < this.tokenCount) {
6202 this.currentToken = next;
6203 this.tokenStart = this.tokenEnd;
6204 next = this.offsetAndType[next];
6205 this.tokenType = next >> TYPE_SHIFT;
6206 this.tokenEnd = next & OFFSET_MASK;
6207 } else {
6208 this.currentToken = this.tokenCount;
6209 this.eof = true;
6210 this.tokenType = NULL;
6211 this.tokenStart = this.tokenEnd = this.source.length;
6212 }
6213 },
6214
6215 eat: function(tokenType) {
6216 if (this.tokenType !== tokenType) {
6217 var offset = this.tokenStart;
6218 var message = NAME$1[tokenType] + ' is expected';
6219
6220 // tweak message and offset
6221 if (tokenType === IDENTIFIER$1) {
6222 // when identifier is expected but there is a function or url
6223 if (this.tokenType === FUNCTION$1 || this.tokenType === URL$1) {
6224 offset = this.tokenEnd - 1;
6225 message += ' but function found';
6226 }
6227 } else {
6228 // when test type is part of another token show error for current position + 1
6229 // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
6230 if (this.source.charCodeAt(this.tokenStart) === tokenType) {
6231 offset = offset + 1;
6232 }
6233 }
6234
6235 this.error(message, offset);
6236 }
6237
6238 this.next();
6239 },
6240 eatNonWS: function(tokenType) {
6241 this.skipWS();
6242 this.eat(tokenType);
6243 },
6244
6245 consume: function(tokenType) {
6246 var value = this.getTokenValue();
6247
6248 this.eat(tokenType);
6249
6250 return value;
6251 },
6252 consumeFunctionName: function() {
6253 var name = this.source.substring(this.tokenStart, this.tokenEnd - 1);
6254
6255 this.eat(FUNCTION$1);
6256
6257 return name;
6258 },
6259 consumeNonWS: function(tokenType) {
6260 this.skipWS();
6261
6262 return this.consume(tokenType);
6263 },
6264
6265 expectIdentifier: function(name) {
6266 if (this.tokenType !== IDENTIFIER$1 || cmpStr$1(this.source, this.tokenStart, this.tokenEnd, name) === false) {
6267 this.error('Identifier `' + name + '` is expected');
6268 }
6269
6270 this.next();
6271 },
6272
6273 getLocation: function(offset, filename) {
6274 if (!this.linesAnsColumnsComputed) {
6275 computeLinesAndColumns(this, this.source);
6276 }
6277
6278 return {
6279 source: filename,
6280 offset: this.startOffset + offset,
6281 line: this.lines[offset],
6282 column: this.columns[offset]
6283 };
6284 },
6285
6286 getLocationRange: function(start, end, filename) {
6287 if (!this.linesAnsColumnsComputed) {
6288 computeLinesAndColumns(this, this.source);
6289 }
6290
6291 return {
6292 source: filename,
6293 start: {
6294 offset: this.startOffset + start,
6295 line: this.lines[start],
6296 column: this.columns[start]
6297 },
6298 end: {
6299 offset: this.startOffset + end,
6300 line: this.lines[end],
6301 column: this.columns[end]
6302 }
6303 };
6304 },
6305
6306 error: function(message, offset) {
6307 var location = typeof offset !== 'undefined' && offset < this.source.length
6308 ? this.getLocation(offset)
6309 : this.eof
6310 ? findLastNonSpaceLocation$1(this)
6311 : this.getLocation(this.tokenStart);
6312
6313 throw new error(
6314 message || 'Unexpected input',
6315 this.source,
6316 location.offset,
6317 location.line,
6318 location.column
6319 );
6320 },
6321
6322 dump: function() {
6323 var offset = 0;
6324
6325 return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
6326 var start = offset;
6327 var end = item & OFFSET_MASK;
6328
6329 offset = end;
6330
6331 return {
6332 idx: idx,
6333 type: NAME$1[item >> TYPE_SHIFT],
6334 chunk: this.source.substring(start, end),
6335 balance: this.balance[idx]
6336 };
6337 }, this);
6338 }
6339 };
6340
6341 // extend with error class
6342 Tokenizer.CssSyntaxError = error;
6343
6344 // extend tokenizer with constants
6345 Object.keys(_const).forEach(function(key) {
6346 Tokenizer[key] = _const[key];
6347 });
6348
6349 // extend tokenizer with static methods from utils
6350 Object.keys(utils).forEach(function(key) {
6351 Tokenizer[key] = utils[key];
6352 });
6353
6354 // warm up tokenizer to elimitate code branches that never execute
6355 // fix soft deoptimizations (insufficient type feedback)
6356 new Tokenizer('\n\r\r\n\f<!---->//""\'\'/*\r\n\f*/1a;.\\31\t\+2{url(a);func();+1.2e3 -.4e-5 .6e+7}').getLocation();
6357
6358 var Tokenizer_1 = Tokenizer;
6359
6360 var tokenizer$1 = Tokenizer_1;
6361
6362 //
6363 // item item item item
6364 // /------\ /------\ /------\ /------\
6365 // | data | | data | | data | | data |
6366 // null <--+-prev |<---+-prev |<---+-prev |<---+-prev |
6367 // | next-+--->| next-+--->| next-+--->| next-+--> null
6368 // \------/ \------/ \------/ \------/
6369 // ^ ^
6370 // | list |
6371 // | /------\ |
6372 // \--------------+-head | |
6373 // | tail-+--------------/
6374 // \------/
6375 //
6376
6377 function createItem(data) {
6378 return {
6379 prev: null,
6380 next: null,
6381 data: data
6382 };
6383 }
6384
6385 var cursors = null;
6386 var List = function() {
6387 this.cursor = null;
6388 this.head = null;
6389 this.tail = null;
6390 };
6391
6392 List.createItem = createItem;
6393 List.prototype.createItem = createItem;
6394
6395 List.prototype.getSize = function() {
6396 var size = 0;
6397 var cursor = this.head;
6398
6399 while (cursor) {
6400 size++;
6401 cursor = cursor.next;
6402 }
6403
6404 return size;
6405 };
6406
6407 List.prototype.fromArray = function(array) {
6408 var cursor = null;
6409
6410 this.head = null;
6411
6412 for (var i = 0; i < array.length; i++) {
6413 var item = createItem(array[i]);
6414
6415 if (cursor !== null) {
6416 cursor.next = item;
6417 } else {
6418 this.head = item;
6419 }
6420
6421 item.prev = cursor;
6422 cursor = item;
6423 }
6424
6425 this.tail = cursor;
6426
6427 return this;
6428 };
6429
6430 List.prototype.toArray = function() {
6431 var cursor = this.head;
6432 var result = [];
6433
6434 while (cursor) {
6435 result.push(cursor.data);
6436 cursor = cursor.next;
6437 }
6438
6439 return result;
6440 };
6441
6442 List.prototype.toJSON = List.prototype.toArray;
6443
6444 List.prototype.isEmpty = function() {
6445 return this.head === null;
6446 };
6447
6448 List.prototype.first = function() {
6449 return this.head && this.head.data;
6450 };
6451
6452 List.prototype.last = function() {
6453 return this.tail && this.tail.data;
6454 };
6455
6456 function allocateCursor(node, prev, next) {
6457 var cursor;
6458
6459 if (cursors !== null) {
6460 cursor = cursors;
6461 cursors = cursors.cursor;
6462 cursor.prev = prev;
6463 cursor.next = next;
6464 cursor.cursor = node.cursor;
6465 } else {
6466 cursor = {
6467 prev: prev,
6468 next: next,
6469 cursor: node.cursor
6470 };
6471 }
6472
6473 node.cursor = cursor;
6474
6475 return cursor;
6476 }
6477
6478 function releaseCursor(node) {
6479 var cursor = node.cursor;
6480
6481 node.cursor = cursor.cursor;
6482 cursor.prev = null;
6483 cursor.next = null;
6484 cursor.cursor = cursors;
6485 cursors = cursor;
6486 }
6487
6488 List.prototype.each = function(fn, context) {
6489 var item;
6490
6491 if (context === undefined) {
6492 context = this;
6493 }
6494
6495 // push cursor
6496 var cursor = allocateCursor(this, null, this.head);
6497
6498 while (cursor.next !== null) {
6499 item = cursor.next;
6500 cursor.next = item.next;
6501
6502 fn.call(context, item.data, item, this);
6503 }
6504
6505 // pop cursor
6506 releaseCursor(this);
6507 };
6508
6509 List.prototype.eachRight = function(fn, context) {
6510 var item;
6511
6512 if (context === undefined) {
6513 context = this;
6514 }
6515
6516 // push cursor
6517 var cursor = allocateCursor(this, this.tail, null);
6518
6519 while (cursor.prev !== null) {
6520 item = cursor.prev;
6521 cursor.prev = item.prev;
6522
6523 fn.call(context, item.data, item, this);
6524 }
6525
6526 // pop cursor
6527 releaseCursor(this);
6528 };
6529
6530 List.prototype.nextUntil = function(start, fn, context) {
6531 if (start === null) {
6532 return;
6533 }
6534
6535 var item;
6536
6537 if (context === undefined) {
6538 context = this;
6539 }
6540
6541 // push cursor
6542 var cursor = allocateCursor(this, null, start);
6543
6544 while (cursor.next !== null) {
6545 item = cursor.next;
6546 cursor.next = item.next;
6547
6548 if (fn.call(context, item.data, item, this)) {
6549 break;
6550 }
6551 }
6552
6553 // pop cursor
6554 releaseCursor(this);
6555 };
6556
6557 List.prototype.prevUntil = function(start, fn, context) {
6558 if (start === null) {
6559 return;
6560 }
6561
6562 var item;
6563
6564 if (context === undefined) {
6565 context = this;
6566 }
6567
6568 // push cursor
6569 var cursor = allocateCursor(this, start, null);
6570
6571 while (cursor.prev !== null) {
6572 item = cursor.prev;
6573 cursor.prev = item.prev;
6574
6575 if (fn.call(context, item.data, item, this)) {
6576 break;
6577 }
6578 }
6579
6580 // pop cursor
6581 releaseCursor(this);
6582 };
6583
6584 List.prototype.some = function(fn, context) {
6585 var cursor = this.head;
6586
6587 if (context === undefined) {
6588 context = this;
6589 }
6590
6591 while (cursor !== null) {
6592 if (fn.call(context, cursor.data, cursor, this)) {
6593 return true;
6594 }
6595
6596 cursor = cursor.next;
6597 }
6598
6599 return false;
6600 };
6601
6602 List.prototype.map = function(fn, context) {
6603 var result = [];
6604 var cursor = this.head;
6605
6606 if (context === undefined) {
6607 context = this;
6608 }
6609
6610 while (cursor !== null) {
6611 result.push(fn.call(context, cursor.data, cursor, this));
6612 cursor = cursor.next;
6613 }
6614
6615 return result;
6616 };
6617
6618 List.prototype.clear = function() {
6619 this.head = null;
6620 this.tail = null;
6621 };
6622
6623 List.prototype.copy = function() {
6624 var result = new List();
6625 var cursor = this.head;
6626
6627 while (cursor !== null) {
6628 result.insert(createItem(cursor.data));
6629 cursor = cursor.next;
6630 }
6631
6632 return result;
6633 };
6634
6635 List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
6636 var cursor = this.cursor;
6637
6638 while (cursor !== null) {
6639 if (cursor.prev === prevOld) {
6640 cursor.prev = prevNew;
6641 }
6642
6643 if (cursor.next === nextOld) {
6644 cursor.next = nextNew;
6645 }
6646
6647 cursor = cursor.cursor;
6648 }
6649 };
6650
6651 List.prototype.prepend = function(item) {
6652 // head
6653 // ^
6654 // item
6655 this.updateCursors(null, item, this.head, item);
6656
6657 // insert to the beginning of the list
6658 if (this.head !== null) {
6659 // new item <- first item
6660 this.head.prev = item;
6661
6662 // new item -> first item
6663 item.next = this.head;
6664 } else {
6665 // if list has no head, then it also has no tail
6666 // in this case tail points to the new item
6667 this.tail = item;
6668 }
6669
6670 // head always points to new item
6671 this.head = item;
6672
6673 return this;
6674 };
6675
6676 List.prototype.prependData = function(data) {
6677 return this.prepend(createItem(data));
6678 };
6679
6680 List.prototype.append = function(item) {
6681 // tail
6682 // ^
6683 // item
6684 this.updateCursors(this.tail, item, null, item);
6685
6686 // insert to the ending of the list
6687 if (this.tail !== null) {
6688 // last item -> new item
6689 this.tail.next = item;
6690
6691 // last item <- new item
6692 item.prev = this.tail;
6693 } else {
6694 // if list has no tail, then it also has no head
6695 // in this case head points to new item
6696 this.head = item;
6697 }
6698
6699 // tail always points to new item
6700 this.tail = item;
6701
6702 return this;
6703 };
6704
6705 List.prototype.appendData = function(data) {
6706 return this.append(createItem(data));
6707 };
6708
6709 List.prototype.insert = function(item, before) {
6710 if (before !== undefined && before !== null) {
6711 // prev before
6712 // ^
6713 // item
6714 this.updateCursors(before.prev, item, before, item);
6715
6716 if (before.prev === null) {
6717 // insert to the beginning of list
6718 if (this.head !== before) {
6719 throw new Error('before doesn\'t belong to list');
6720 }
6721
6722 // since head points to before therefore list doesn't empty
6723 // no need to check tail
6724 this.head = item;
6725 before.prev = item;
6726 item.next = before;
6727
6728 this.updateCursors(null, item);
6729 } else {
6730
6731 // insert between two items
6732 before.prev.next = item;
6733 item.prev = before.prev;
6734
6735 before.prev = item;
6736 item.next = before;
6737 }
6738 } else {
6739 this.append(item);
6740 }
6741 };
6742
6743 List.prototype.insertData = function(data, before) {
6744 this.insert(createItem(data), before);
6745 };
6746
6747 List.prototype.remove = function(item) {
6748 // item
6749 // ^
6750 // prev next
6751 this.updateCursors(item, item.prev, item, item.next);
6752
6753 if (item.prev !== null) {
6754 item.prev.next = item.next;
6755 } else {
6756 if (this.head !== item) {
6757 throw new Error('item doesn\'t belong to list');
6758 }
6759
6760 this.head = item.next;
6761 }
6762
6763 if (item.next !== null) {
6764 item.next.prev = item.prev;
6765 } else {
6766 if (this.tail !== item) {
6767 throw new Error('item doesn\'t belong to list');
6768 }
6769
6770 this.tail = item.prev;
6771 }
6772
6773 item.prev = null;
6774 item.next = null;
6775
6776 return item;
6777 };
6778
6779 List.prototype.appendList = function(list) {
6780 // ignore empty lists
6781 if (list.head === null) {
6782 return;
6783 }
6784
6785 this.updateCursors(this.tail, list.tail, null, list.head);
6786
6787 // insert to end of the list
6788 if (this.tail !== null) {
6789 // if destination list has a tail, then it also has a head,
6790 // but head doesn't change
6791
6792 // dest tail -> source head
6793 this.tail.next = list.head;
6794
6795 // dest tail <- source head
6796 list.head.prev = this.tail;
6797 } else {
6798 // if list has no a tail, then it also has no a head
6799 // in this case points head to new item
6800 this.head = list.head;
6801 }
6802
6803 // tail always start point to new item
6804 this.tail = list.tail;
6805
6806 list.head = null;
6807 list.tail = null;
6808 };
6809
6810 List.prototype.insertList = function(list, before) {
6811 if (before !== undefined && before !== null) {
6812 // ignore empty lists
6813 if (list.head === null) {
6814 return;
6815 }
6816
6817 this.updateCursors(before.prev, list.tail, before, list.head);
6818
6819 // insert in the middle of dist list
6820 if (before.prev !== null) {
6821 // before.prev <-> list.head
6822 before.prev.next = list.head;
6823 list.head.prev = before.prev;
6824 } else {
6825 this.head = list.head;
6826 }
6827
6828 before.prev = list.tail;
6829 list.tail.next = before;
6830
6831 list.head = null;
6832 list.tail = null;
6833 } else {
6834 this.appendList(list);
6835 }
6836 };
6837
6838 List.prototype.replace = function(oldItem, newItemOrList) {
6839 if ('head' in newItemOrList) {
6840 this.insertList(newItemOrList, oldItem);
6841 } else {
6842 this.insert(newItemOrList, oldItem);
6843 }
6844 this.remove(oldItem);
6845 };
6846
6847 var list = List;
6848
6849 var TYPE$3 = tokenizer$1.TYPE;
6850 var WHITESPACE$2 = TYPE$3.WhiteSpace;
6851 var COMMENT$2 = TYPE$3.Comment;
6852
6853 var sequence = function readSequence(recognizer) {
6854 var children = new list();
6855 var child = null;
6856 var context = {
6857 recognizer: recognizer,
6858 space: null,
6859 ignoreWS: false,
6860 ignoreWSAfter: false
6861 };
6862
6863 this.scanner.skipSC();
6864
6865 while (!this.scanner.eof) {
6866 switch (this.scanner.tokenType) {
6867 case COMMENT$2:
6868 this.scanner.next();
6869 continue;
6870
6871 case WHITESPACE$2:
6872 if (context.ignoreWS) {
6873 this.scanner.next();
6874 } else {
6875 context.space = this.WhiteSpace();
6876 }
6877 continue;
6878 }
6879
6880 child = recognizer.getNode.call(this, context);
6881
6882 if (child === undefined) {
6883 break;
6884 }
6885
6886 if (context.space !== null) {
6887 children.appendData(context.space);
6888 context.space = null;
6889 }
6890
6891 children.appendData(child);
6892
6893 if (context.ignoreWSAfter) {
6894 context.ignoreWSAfter = false;
6895 context.ignoreWS = true;
6896 } else {
6897 context.ignoreWS = false;
6898 }
6899 }
6900
6901 return children;
6902 };
6903
6904 var noop = function() {};
6905
6906 function createParseContext(name) {
6907 return function() {
6908 return this[name]();
6909 };
6910 }
6911
6912 function processConfig(config) {
6913 var parserConfig = {
6914 context: {},
6915 scope: {},
6916 atrule: {},
6917 pseudo: {}
6918 };
6919
6920 if (config.parseContext) {
6921 for (var name in config.parseContext) {
6922 switch (typeof config.parseContext[name]) {
6923 case 'function':
6924 parserConfig.context[name] = config.parseContext[name];
6925 break;
6926
6927 case 'string':
6928 parserConfig.context[name] = createParseContext(config.parseContext[name]);
6929 break;
6930 }
6931 }
6932 }
6933
6934 if (config.scope) {
6935 for (var name in config.scope) {
6936 parserConfig.scope[name] = config.scope[name];
6937 }
6938 }
6939
6940 if (config.atrule) {
6941 for (var name in config.atrule) {
6942 var atrule = config.atrule[name];
6943
6944 if (atrule.parse) {
6945 parserConfig.atrule[name] = atrule.parse;
6946 }
6947 }
6948 }
6949
6950 if (config.pseudo) {
6951 for (var name in config.pseudo) {
6952 var pseudo = config.pseudo[name];
6953
6954 if (pseudo.parse) {
6955 parserConfig.pseudo[name] = pseudo.parse;
6956 }
6957 }
6958 }
6959
6960 if (config.node) {
6961 for (var name in config.node) {
6962 parserConfig[name] = config.node[name].parse;
6963 }
6964 }
6965
6966 return parserConfig;
6967 }
6968
6969 var create = function createParser(config) {
6970 var parser = {
6971 scanner: new tokenizer$1(),
6972 filename: '<unknown>',
6973 needPositions: false,
6974 tolerant: false,
6975 onParseError: noop,
6976 parseAtruleExpression: true,
6977 parseSelector: true,
6978 parseValue: true,
6979 parseCustomProperty: false,
6980
6981 readSequence: sequence,
6982
6983 tolerantParse: function(consumer, fallback) {
6984 if (this.tolerant) {
6985 var start = this.scanner.currentToken;
6986
6987 try {
6988 return consumer.call(this);
6989 } catch (e) {
6990 this.onParseError(e);
6991 return fallback.call(this, start);
6992 }
6993 } else {
6994 return consumer.call(this);
6995 }
6996 },
6997
6998 getLocation: function(start, end) {
6999 if (this.needPositions) {
7000 return this.scanner.getLocationRange(
7001 start,
7002 end,
7003 this.filename
7004 );
7005 }
7006
7007 return null;
7008 },
7009 getLocationFromList: function(list) {
7010 if (this.needPositions) {
7011 return this.scanner.getLocationRange(
7012 list.head !== null ? list.first().loc.start.offset - this.scanner.startOffset : this.scanner.tokenStart,
7013 list.head !== null ? list.last().loc.end.offset - this.scanner.startOffset : this.scanner.tokenStart,
7014 this.filename
7015 );
7016 }
7017
7018 return null;
7019 }
7020 };
7021
7022 config = processConfig(config || {});
7023 for (var key in config) {
7024 parser[key] = config[key];
7025 }
7026
7027 return function(source, options) {
7028 options = options || {};
7029
7030 var context = options.context || 'default';
7031 var ast;
7032
7033 parser.scanner.setSource(source, options.offset, options.line, options.column);
7034 parser.filename = options.filename || '<unknown>';
7035 parser.needPositions = Boolean(options.positions);
7036 parser.tolerant = Boolean(options.tolerant);
7037 parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop;
7038 parser.parseAtruleExpression = 'parseAtruleExpression' in options ? Boolean(options.parseAtruleExpression) : true;
7039 parser.parseSelector = 'parseSelector' in options ? Boolean(options.parseSelector) : true;
7040 parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
7041 parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
7042
7043 if (!parser.context.hasOwnProperty(context)) {
7044 throw new Error('Unknown context `' + context + '`');
7045 }
7046
7047 ast = parser.context[context].call(parser, options);
7048
7049 if (!parser.scanner.eof) {
7050 parser.scanner.error();
7051 }
7052
7053 // console.log(JSON.stringify(ast, null, 4));
7054 return ast;
7055 };
7056 };
7057
7058 var cmpChar$1 = tokenizer$1.cmpChar;
7059 var TYPE$4 = tokenizer$1.TYPE;
7060
7061 var IDENTIFIER$2 = TYPE$4.Identifier;
7062 var STRING$2 = TYPE$4.String;
7063 var NUMBER$2 = TYPE$4.Number;
7064 var FUNCTION$2 = TYPE$4.Function;
7065 var URL$2 = TYPE$4.Url;
7066 var NUMBERSIGN = TYPE$4.NumberSign;
7067 var LEFTPARENTHESIS$1 = TYPE$4.LeftParenthesis;
7068 var LEFTSQUAREBRACKET$1 = TYPE$4.LeftSquareBracket;
7069 var PLUSSIGN$2 = TYPE$4.PlusSign;
7070 var HYPHENMINUS$2 = TYPE$4.HyphenMinus;
7071 var COMMA = TYPE$4.Comma;
7072 var SOLIDUS = TYPE$4.Solidus;
7073 var ASTERISK = TYPE$4.Asterisk;
7074 var PERCENTSIGN = TYPE$4.PercentSign;
7075 var BACKSLASH = TYPE$4.Backslash;
7076 var U = 117; // 'u'.charCodeAt(0)
7077
7078 var _default = function defaultRecognizer(context) {
7079 switch (this.scanner.tokenType) {
7080 case NUMBERSIGN:
7081 return this.HexColor();
7082
7083 case COMMA:
7084 context.space = null;
7085 context.ignoreWSAfter = true;
7086 return this.Operator();
7087
7088 case SOLIDUS:
7089 case ASTERISK:
7090 case PLUSSIGN$2:
7091 case HYPHENMINUS$2:
7092 return this.Operator();
7093
7094 case LEFTPARENTHESIS$1:
7095 return this.Parentheses(this.readSequence, context.recognizer);
7096
7097 case LEFTSQUAREBRACKET$1:
7098 return this.Brackets(this.readSequence, context.recognizer);
7099
7100 case STRING$2:
7101 return this.String();
7102
7103 case NUMBER$2:
7104 switch (this.scanner.lookupType(1)) {
7105 case PERCENTSIGN:
7106 return this.Percentage();
7107
7108 case IDENTIFIER$2:
7109 // edge case: number with folowing \0 and \9 hack shouldn't to be a Dimension
7110 if (cmpChar$1(this.scanner.source, this.scanner.tokenEnd, BACKSLASH)) {
7111 return this.Number();
7112 } else {
7113 return this.Dimension();
7114 }
7115
7116 default:
7117 return this.Number();
7118 }
7119
7120 case FUNCTION$2:
7121 return this.Function(this.readSequence, context.recognizer);
7122
7123 case URL$2:
7124 return this.Url();
7125
7126 case IDENTIFIER$2:
7127 // check for unicode range, it should start with u+ or U+
7128 if (cmpChar$1(this.scanner.source, this.scanner.tokenStart, U) &&
7129 cmpChar$1(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$2)) {
7130 return this.UnicodeRange();
7131 } else {
7132 return this.Identifier();
7133 }
7134 }
7135 };
7136
7137 var atruleExpression = {
7138 getNode: _default
7139 };
7140
7141 var TYPE$5 = tokenizer$1.TYPE;
7142
7143 var IDENTIFIER$3 = TYPE$5.Identifier;
7144 var NUMBER$3 = TYPE$5.Number;
7145 var NUMBERSIGN$1 = TYPE$5.NumberSign;
7146 var LEFTSQUAREBRACKET$2 = TYPE$5.LeftSquareBracket;
7147 var PLUSSIGN$3 = TYPE$5.PlusSign;
7148 var SOLIDUS$1 = TYPE$5.Solidus;
7149 var ASTERISK$1 = TYPE$5.Asterisk;
7150 var FULLSTOP$2 = TYPE$5.FullStop;
7151 var COLON = TYPE$5.Colon;
7152 var GREATERTHANSIGN$1 = TYPE$5.GreaterThanSign;
7153 var VERTICALLINE = TYPE$5.VerticalLine;
7154 var TILDE = TYPE$5.Tilde;
7155
7156 function getNode(context) {
7157 switch (this.scanner.tokenType) {
7158 case PLUSSIGN$3:
7159 case GREATERTHANSIGN$1:
7160 case TILDE:
7161 context.space = null;
7162 context.ignoreWSAfter = true;
7163 return this.Combinator();
7164
7165 case SOLIDUS$1: // /deep/
7166 return this.Combinator();
7167
7168 case FULLSTOP$2:
7169 return this.ClassSelector();
7170
7171 case LEFTSQUAREBRACKET$2:
7172 return this.AttributeSelector();
7173
7174 case NUMBERSIGN$1:
7175 return this.IdSelector();
7176
7177 case COLON:
7178 if (this.scanner.lookupType(1) === COLON) {
7179 return this.PseudoElementSelector();
7180 } else {
7181 return this.PseudoClassSelector();
7182 }
7183
7184 case IDENTIFIER$3:
7185 case ASTERISK$1:
7186 case VERTICALLINE:
7187 return this.TypeSelector();
7188
7189 case NUMBER$3:
7190 return this.Percentage();
7191 }
7192 }
7193 var selector = {
7194 getNode: getNode
7195 };
7196
7197 // https://drafts.csswg.org/css-images-4/#element-notation
7198 // https://developer.mozilla.org/en-US/docs/Web/CSS/element
7199 var element = function() {
7200 this.scanner.skipSC();
7201
7202 var id = this.IdSelector();
7203
7204 this.scanner.skipSC();
7205
7206 return new list().appendData(
7207 id
7208 );
7209 };
7210
7211 // legacy IE function
7212 // expression '(' raw ')'
7213 var expression = function() {
7214 return new list().appendData(
7215 this.Raw(this.scanner.currentToken, 0, 0, false, false)
7216 );
7217 };
7218
7219 var TYPE$6 = tokenizer$1.TYPE;
7220
7221 var IDENTIFIER$4 = TYPE$6.Identifier;
7222 var COMMA$1 = TYPE$6.Comma;
7223 var SEMICOLON = TYPE$6.Semicolon;
7224 var HYPHENMINUS$3 = TYPE$6.HyphenMinus;
7225 var EXCLAMATIONMARK$1 = TYPE$6.ExclamationMark;
7226
7227 // var '(' ident (',' <value>? )? ')'
7228 var _var = function() {
7229 var children = new list();
7230
7231 this.scanner.skipSC();
7232
7233 var identStart = this.scanner.tokenStart;
7234
7235 this.scanner.eat(HYPHENMINUS$3);
7236 if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== HYPHENMINUS$3) {
7237 this.scanner.error('HyphenMinus is expected');
7238 }
7239 this.scanner.eat(IDENTIFIER$4);
7240
7241 children.appendData({
7242 type: 'Identifier',
7243 loc: this.getLocation(identStart, this.scanner.tokenStart),
7244 name: this.scanner.substrToCursor(identStart)
7245 });
7246
7247 this.scanner.skipSC();
7248
7249 if (this.scanner.tokenType === COMMA$1) {
7250 children.appendData(this.Operator());
7251 children.appendData(this.parseCustomProperty
7252 ? this.Value(null)
7253 : this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$1, SEMICOLON, false, false)
7254 );
7255 }
7256
7257 return children;
7258 };
7259
7260 var value = {
7261 getNode: _default,
7262 '-moz-element': element,
7263 'element': element,
7264 'expression': expression,
7265 'var': _var
7266 };
7267
7268 var scope = {
7269 AtruleExpression: atruleExpression,
7270 Selector: selector,
7271 Value: value
7272 };
7273
7274 var fontFace = {
7275 parse: {
7276 expression: null,
7277 block: function() {
7278 return this.Block(this.Declaration);
7279 }
7280 }
7281 };
7282
7283 var TYPE$7 = tokenizer$1.TYPE;
7284
7285 var STRING$3 = TYPE$7.String;
7286 var IDENTIFIER$5 = TYPE$7.Identifier;
7287 var URL$3 = TYPE$7.Url;
7288 var LEFTPARENTHESIS$2 = TYPE$7.LeftParenthesis;
7289
7290 var _import = {
7291 parse: {
7292 expression: function() {
7293 var children = new list();
7294
7295 this.scanner.skipSC();
7296
7297 switch (this.scanner.tokenType) {
7298 case STRING$3:
7299 children.appendData(this.String());
7300 break;
7301
7302 case URL$3:
7303 children.appendData(this.Url());
7304 break;
7305
7306 default:
7307 this.scanner.error('String or url() is expected');
7308 }
7309
7310 if (this.scanner.lookupNonWSType(0) === IDENTIFIER$5 ||
7311 this.scanner.lookupNonWSType(0) === LEFTPARENTHESIS$2) {
7312 children.appendData(this.WhiteSpace());
7313 children.appendData(this.MediaQueryList());
7314 }
7315
7316 return children;
7317 },
7318 block: null
7319 }
7320 };
7321
7322 var media = {
7323 parse: {
7324 expression: function() {
7325 return new list().appendData(
7326 this.MediaQueryList()
7327 );
7328 },
7329 block: function() {
7330 return this.Block(this.Rule);
7331 }
7332 }
7333 };
7334
7335 var TYPE$8 = tokenizer$1.TYPE;
7336 var LEFTCURLYBRACKET$1 = TYPE$8.LeftCurlyBracket;
7337
7338 var page = {
7339 parse: {
7340 expression: function() {
7341 if (this.scanner.lookupNonWSType(0) === LEFTCURLYBRACKET$1) {
7342 return null;
7343 }
7344
7345 return new list().appendData(
7346 this.SelectorList()
7347 );
7348 },
7349 block: function() {
7350 return this.Block(this.Declaration);
7351 }
7352 }
7353 };
7354
7355 var TYPE$9 = tokenizer$1.TYPE;
7356
7357 var WHITESPACE$3 = TYPE$9.WhiteSpace;
7358 var COMMENT$3 = TYPE$9.Comment;
7359 var IDENTIFIER$6 = TYPE$9.Identifier;
7360 var FUNCTION$3 = TYPE$9.Function;
7361 var LEFTPARENTHESIS$3 = TYPE$9.LeftParenthesis;
7362 var HYPHENMINUS$4 = TYPE$9.HyphenMinus;
7363 var COLON$1 = TYPE$9.Colon;
7364
7365 function consumeRaw() {
7366 return new list().appendData(
7367 this.Raw(this.scanner.currentToken, 0, 0, false, false)
7368 );
7369 }
7370
7371 function parentheses() {
7372 var index = 0;
7373
7374 this.scanner.skipSC();
7375
7376 // TODO: make it simplier
7377 if (this.scanner.tokenType === IDENTIFIER$6) {
7378 index = 1;
7379 } else if (this.scanner.tokenType === HYPHENMINUS$4 &&
7380 this.scanner.lookupType(1) === IDENTIFIER$6) {
7381 index = 2;
7382 }
7383
7384 if (index !== 0 && this.scanner.lookupNonWSType(index) === COLON$1) {
7385 return new list().appendData(
7386 this.Declaration()
7387 );
7388 }
7389
7390 return readSequence.call(this);
7391 }
7392
7393 function readSequence() {
7394 var children = new list();
7395 var space = null;
7396 var child;
7397
7398 this.scanner.skipSC();
7399
7400 scan:
7401 while (!this.scanner.eof) {
7402 switch (this.scanner.tokenType) {
7403 case WHITESPACE$3:
7404 space = this.WhiteSpace();
7405 continue;
7406
7407 case COMMENT$3:
7408 this.scanner.next();
7409 continue;
7410
7411 case FUNCTION$3:
7412 child = this.Function(consumeRaw, this.scope.AtruleExpression);
7413 break;
7414
7415 case IDENTIFIER$6:
7416 child = this.Identifier();
7417 break;
7418
7419 case LEFTPARENTHESIS$3:
7420 child = this.Parentheses(parentheses, this.scope.AtruleExpression);
7421 break;
7422
7423 default:
7424 break scan;
7425 }
7426
7427 if (space !== null) {
7428 children.appendData(space);
7429 space = null;
7430 }
7431
7432 children.appendData(child);
7433 }
7434
7435 return children;
7436 }
7437
7438 var supports = {
7439 parse: {
7440 expression: function() {
7441 var children = readSequence.call(this);
7442
7443 if (children.isEmpty()) {
7444 this.scanner.error('Condition is expected');
7445 }
7446
7447 return children;
7448 },
7449 block: function() {
7450 return this.Block(this.Rule);
7451 }
7452 }
7453 };
7454
7455 var atrule = {
7456 'font-face': fontFace,
7457 'import': _import,
7458 'media': media,
7459 'page': page,
7460 'supports': supports
7461 };
7462
7463 var dir = {
7464 parse: function() {
7465 return new list().appendData(
7466 this.Identifier()
7467 );
7468 }
7469 };
7470
7471 var has$1 = {
7472 parse: function() {
7473 return new list().appendData(
7474 this.SelectorList()
7475 );
7476 }
7477 };
7478
7479 var lang = {
7480 parse: function() {
7481 return new list().appendData(
7482 this.Identifier()
7483 );
7484 }
7485 };
7486
7487 var selectorList = {
7488 parse: function selectorList() {
7489 return new list().appendData(
7490 this.SelectorList()
7491 );
7492 }
7493 };
7494
7495 var matches = selectorList;
7496
7497 var not = selectorList;
7498
7499 var ALLOW_OF_CLAUSE = true;
7500
7501 var nthWithOfClause = {
7502 parse: function() {
7503 return new list().appendData(
7504 this.Nth(ALLOW_OF_CLAUSE)
7505 );
7506 }
7507 };
7508
7509 var nthChild = nthWithOfClause;
7510
7511 var nthLastChild = nthWithOfClause;
7512
7513 var DISALLOW_OF_CLAUSE = false;
7514
7515 var nth = {
7516 parse: function nth() {
7517 return new list().appendData(
7518 this.Nth(DISALLOW_OF_CLAUSE)
7519 );
7520 }
7521 };
7522
7523 var nthLastOfType = nth;
7524
7525 var nthOfType = nth;
7526
7527 var slotted = {
7528 parse: function compoundSelector() {
7529 return new list().appendData(
7530 this.Selector()
7531 );
7532 }
7533 };
7534
7535 var pseudo = {
7536 'dir': dir,
7537 'has': has$1,
7538 'lang': lang,
7539 'matches': matches,
7540 'not': not,
7541 'nth-child': nthChild,
7542 'nth-last-child': nthLastChild,
7543 'nth-last-of-type': nthLastOfType,
7544 'nth-of-type': nthOfType,
7545 'slotted': slotted
7546 };
7547
7548 var cmpChar$2 = tokenizer$1.cmpChar;
7549 var isNumber$2 = tokenizer$1.isNumber;
7550 var TYPE$a = tokenizer$1.TYPE;
7551
7552 var IDENTIFIER$7 = TYPE$a.Identifier;
7553 var NUMBER$4 = TYPE$a.Number;
7554 var PLUSSIGN$4 = TYPE$a.PlusSign;
7555 var HYPHENMINUS$5 = TYPE$a.HyphenMinus;
7556 var N$3 = 110; // 'n'.charCodeAt(0)
7557 var DISALLOW_SIGN = true;
7558 var ALLOW_SIGN = false;
7559
7560 function checkTokenIsInteger(scanner, disallowSign) {
7561 var pos = scanner.tokenStart;
7562
7563 if (scanner.source.charCodeAt(pos) === PLUSSIGN$4 ||
7564 scanner.source.charCodeAt(pos) === HYPHENMINUS$5) {
7565 if (disallowSign) {
7566 scanner.error();
7567 }
7568 pos++;
7569 }
7570
7571 for (; pos < scanner.tokenEnd; pos++) {
7572 if (!isNumber$2(scanner.source.charCodeAt(pos))) {
7573 scanner.error('Unexpected input', pos);
7574 }
7575 }
7576 }
7577
7578 // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
7579 var AnPlusB = {
7580 name: 'AnPlusB',
7581 structure: {
7582 a: [String, null],
7583 b: [String, null]
7584 },
7585 parse: function() {
7586 var start = this.scanner.tokenStart;
7587 var end = start;
7588 var prefix = '';
7589 var a = null;
7590 var b = null;
7591
7592 if (this.scanner.tokenType === NUMBER$4 ||
7593 this.scanner.tokenType === PLUSSIGN$4) {
7594 checkTokenIsInteger(this.scanner, ALLOW_SIGN);
7595 prefix = this.scanner.getTokenValue();
7596 this.scanner.next();
7597 end = this.scanner.tokenStart;
7598 }
7599
7600 if (this.scanner.tokenType === IDENTIFIER$7) {
7601 var bStart = this.scanner.tokenStart;
7602
7603 if (cmpChar$2(this.scanner.source, bStart, HYPHENMINUS$5)) {
7604 if (prefix === '') {
7605 prefix = '-';
7606 bStart++;
7607 } else {
7608 this.scanner.error('Unexpected hyphen minus');
7609 }
7610 }
7611
7612 if (!cmpChar$2(this.scanner.source, bStart, N$3)) {
7613 this.scanner.error();
7614 }
7615
7616 a = prefix === '' ? '1' :
7617 prefix === '+' ? '+1' :
7618 prefix === '-' ? '-1' :
7619 prefix;
7620
7621 var len = this.scanner.tokenEnd - bStart;
7622 if (len > 1) {
7623 // ..n-..
7624 if (this.scanner.source.charCodeAt(bStart + 1) !== HYPHENMINUS$5) {
7625 this.scanner.error('Unexpected input', bStart + 1);
7626 }
7627
7628 if (len > 2) {
7629 // ..n-{number}..
7630 this.scanner.tokenStart = bStart + 2;
7631 } else {
7632 // ..n- {number}
7633 this.scanner.next();
7634 this.scanner.skipSC();
7635 }
7636
7637 checkTokenIsInteger(this.scanner, DISALLOW_SIGN);
7638 b = '-' + this.scanner.getTokenValue();
7639 this.scanner.next();
7640 end = this.scanner.tokenStart;
7641 } else {
7642 prefix = '';
7643 this.scanner.next();
7644 end = this.scanner.tokenStart;
7645 this.scanner.skipSC();
7646
7647 if (this.scanner.tokenType === HYPHENMINUS$5 ||
7648 this.scanner.tokenType === PLUSSIGN$4) {
7649 prefix = this.scanner.getTokenValue();
7650 this.scanner.next();
7651 this.scanner.skipSC();
7652 }
7653
7654 if (this.scanner.tokenType === NUMBER$4) {
7655 checkTokenIsInteger(this.scanner, prefix !== '');
7656
7657 if (!isNumber$2(this.scanner.source.charCodeAt(this.scanner.tokenStart))) {
7658 prefix = this.scanner.source.charAt(this.scanner.tokenStart);
7659 this.scanner.tokenStart++;
7660 }
7661
7662 if (prefix === '') {
7663 // should be an operator before number
7664 this.scanner.error();
7665 } else if (prefix === '+') {
7666 // plus is using by default
7667 prefix = '';
7668 }
7669
7670 b = prefix + this.scanner.getTokenValue();
7671
7672 this.scanner.next();
7673 end = this.scanner.tokenStart;
7674 } else {
7675 if (prefix) {
7676 this.scanner.eat(NUMBER$4);
7677 }
7678 }
7679 }
7680 } else {
7681 if (prefix === '' || prefix === '+') { // no number
7682 this.scanner.error(
7683 'Number or identifier is expected',
7684 this.scanner.tokenStart + (
7685 this.scanner.tokenType === PLUSSIGN$4 ||
7686 this.scanner.tokenType === HYPHENMINUS$5
7687 )
7688 );
7689 }
7690
7691 b = prefix;
7692 }
7693
7694 return {
7695 type: 'AnPlusB',
7696 loc: this.getLocation(start, end),
7697 a: a,
7698 b: b
7699 };
7700 },
7701 generate: function(processChunk, node) {
7702 var a = node.a !== null && node.a !== undefined;
7703 var b = node.b !== null && node.b !== undefined;
7704
7705 if (a) {
7706 processChunk(
7707 node.a === '+1' ? '+n' :
7708 node.a === '1' ? 'n' :
7709 node.a === '-1' ? '-n' :
7710 node.a + 'n'
7711 );
7712
7713 if (b) {
7714 b = String(node.b);
7715 if (b.charAt(0) === '-' || b.charAt(0) === '+') {
7716 processChunk(b.charAt(0));
7717 processChunk(b.substr(1));
7718 } else {
7719 processChunk('+');
7720 processChunk(b);
7721 }
7722 }
7723 } else {
7724 processChunk(String(node.b));
7725 }
7726 }
7727 };
7728
7729 var TYPE$b = tokenizer$1.TYPE;
7730
7731 var ATRULE$2 = TYPE$b.Atrule;
7732 var SEMICOLON$1 = TYPE$b.Semicolon;
7733 var LEFTCURLYBRACKET$2 = TYPE$b.LeftCurlyBracket;
7734 var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
7735
7736 function isBlockAtrule() {
7737 for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
7738 if (type === RIGHTCURLYBRACKET$1) {
7739 return true;
7740 }
7741
7742 if (type === LEFTCURLYBRACKET$2 ||
7743 type === ATRULE$2) {
7744 return false;
7745 }
7746 }
7747
7748 this.scanner.skip(offset);
7749 this.scanner.eat(RIGHTCURLYBRACKET$1);
7750 }
7751
7752 var Atrule = {
7753 name: 'Atrule',
7754 structure: {
7755 name: String,
7756 expression: ['AtruleExpression', null],
7757 block: ['Block', null]
7758 },
7759 parse: function() {
7760 var start = this.scanner.tokenStart;
7761 var name;
7762 var nameLowerCase;
7763 var expression = null;
7764 var block = null;
7765
7766 this.scanner.eat(ATRULE$2);
7767
7768 name = this.scanner.substrToCursor(start + 1);
7769 nameLowerCase = name.toLowerCase();
7770 this.scanner.skipSC();
7771
7772 expression = this.AtruleExpression(name);
7773
7774 // turn empty AtruleExpression into null
7775 if (expression.children.head === null) {
7776 expression = null;
7777 }
7778
7779 this.scanner.skipSC();
7780
7781 if (this.atrule.hasOwnProperty(nameLowerCase)) {
7782 if (typeof this.atrule[nameLowerCase].block === 'function') {
7783 if (this.scanner.tokenType !== LEFTCURLYBRACKET$2) {
7784 // FIXME: make tolerant
7785 this.scanner.error('Curly bracket is expected');
7786 }
7787
7788 block = this.atrule[nameLowerCase].block.call(this);
7789 } else {
7790 if (!this.tolerant || !this.scanner.eof) {
7791 this.scanner.eat(SEMICOLON$1);
7792 }
7793 }
7794 } else {
7795 switch (this.scanner.tokenType) {
7796 case SEMICOLON$1:
7797 this.scanner.next();
7798 break;
7799
7800 case LEFTCURLYBRACKET$2:
7801 // TODO: should consume block content as Raw?
7802 block = this.Block(isBlockAtrule.call(this) ? this.Declaration : this.Rule);
7803 break;
7804
7805 default:
7806 if (!this.tolerant) {
7807 this.scanner.error('Semicolon or block is expected');
7808 }
7809 }
7810 }
7811
7812 return {
7813 type: 'Atrule',
7814 loc: this.getLocation(start, this.scanner.tokenStart),
7815 name: name,
7816 expression: expression,
7817 block: block
7818 };
7819 },
7820 generate: function(processChunk, node) {
7821 processChunk('@');
7822 processChunk(node.name);
7823
7824 if (node.expression !== null) {
7825 processChunk(' ');
7826 this.generate(processChunk, node.expression);
7827 }
7828
7829 if (node.block) {
7830 this.generate(processChunk, node.block);
7831 } else {
7832 processChunk(';');
7833 }
7834 },
7835 walkContext: 'atrule'
7836 };
7837
7838 var TYPE$c = tokenizer$1.TYPE;
7839 var SEMICOLON$2 = TYPE$c.Semicolon;
7840 var LEFTCURLYBRACKET$3 = TYPE$c.LeftCurlyBracket;
7841
7842 function consumeRaw$1(startToken) {
7843 return new list().appendData(
7844 this.Raw(startToken, SEMICOLON$2, LEFTCURLYBRACKET$3, false, true)
7845 );
7846 }
7847
7848 function consumeDefaultSequence() {
7849 return this.readSequence(this.scope.AtruleExpression);
7850 }
7851
7852 var AtruleExpression = {
7853 name: 'AtruleExpression',
7854 structure: {
7855 children: [[]]
7856 },
7857 parse: function(name) {
7858 var children = null;
7859 var startToken = this.scanner.currentToken;
7860
7861 if (name !== null) {
7862 name = name.toLowerCase();
7863 }
7864
7865 if (this.parseAtruleExpression) {
7866 // custom consumer
7867 if (this.atrule.hasOwnProperty(name)) {
7868 if (typeof this.atrule[name].expression === 'function') {
7869 children = this.tolerantParse(this.atrule[name].expression, consumeRaw$1);
7870 }
7871 } else {
7872 // default consumer
7873 this.scanner.skipSC();
7874 children = this.tolerantParse(consumeDefaultSequence, consumeRaw$1);
7875 }
7876
7877 if (this.tolerant) {
7878 if (this.scanner.eof || (this.scanner.tokenType !== SEMICOLON$2 && this.scanner.tokenType !== LEFTCURLYBRACKET$3)) {
7879 children = consumeRaw$1.call(this, startToken);
7880 }
7881 }
7882 } else {
7883 children = consumeRaw$1.call(this, startToken);
7884 }
7885
7886 if (children === null) {
7887 children = new list();
7888 }
7889
7890 return {
7891 type: 'AtruleExpression',
7892 loc: this.getLocationFromList(children),
7893 children: children
7894 };
7895 },
7896 generate: function(processChunk, node) {
7897 this.each(processChunk, node);
7898 },
7899 walkContext: 'atruleExpression'
7900 };
7901
7902 var TYPE$d = tokenizer$1.TYPE;
7903
7904 var IDENTIFIER$8 = TYPE$d.Identifier;
7905 var STRING$4 = TYPE$d.String;
7906 var DOLLARSIGN = TYPE$d.DollarSign;
7907 var ASTERISK$2 = TYPE$d.Asterisk;
7908 var COLON$2 = TYPE$d.Colon;
7909 var EQUALSSIGN = TYPE$d.EqualsSign;
7910 var LEFTSQUAREBRACKET$3 = TYPE$d.LeftSquareBracket;
7911 var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
7912 var CIRCUMFLEXACCENT = TYPE$d.CircumflexAccent;
7913 var VERTICALLINE$1 = TYPE$d.VerticalLine;
7914 var TILDE$1 = TYPE$d.Tilde;
7915
7916 function getAttributeName() {
7917 if (this.scanner.eof) {
7918 this.scanner.error('Unexpected end of input');
7919 }
7920
7921 var start = this.scanner.tokenStart;
7922 var expectIdentifier = false;
7923 var checkColon = true;
7924
7925 if (this.scanner.tokenType === ASTERISK$2) {
7926 expectIdentifier = true;
7927 checkColon = false;
7928 this.scanner.next();
7929 } else if (this.scanner.tokenType !== VERTICALLINE$1) {
7930 this.scanner.eat(IDENTIFIER$8);
7931 }
7932
7933 if (this.scanner.tokenType === VERTICALLINE$1) {
7934 if (this.scanner.lookupType(1) !== EQUALSSIGN) {
7935 this.scanner.next();
7936 this.scanner.eat(IDENTIFIER$8);
7937 } else if (expectIdentifier) {
7938 this.scanner.error('Identifier is expected', this.scanner.tokenEnd);
7939 }
7940 } else if (expectIdentifier) {
7941 this.scanner.error('Vertical line is expected');
7942 }
7943
7944 if (checkColon && this.scanner.tokenType === COLON$2) {
7945 this.scanner.next();
7946 this.scanner.eat(IDENTIFIER$8);
7947 }
7948
7949 return {
7950 type: 'Identifier',
7951 loc: this.getLocation(start, this.scanner.tokenStart),
7952 name: this.scanner.substrToCursor(start)
7953 };
7954 }
7955
7956 function getOperator() {
7957 var start = this.scanner.tokenStart;
7958 var tokenType = this.scanner.tokenType;
7959
7960 if (tokenType !== EQUALSSIGN && // =
7961 tokenType !== TILDE$1 && // ~=
7962 tokenType !== CIRCUMFLEXACCENT && // ^=
7963 tokenType !== DOLLARSIGN && // $=
7964 tokenType !== ASTERISK$2 && // *=
7965 tokenType !== VERTICALLINE$1 // |=
7966 ) {
7967 this.scanner.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
7968 }
7969
7970 if (tokenType === EQUALSSIGN) {
7971 this.scanner.next();
7972 } else {
7973 this.scanner.next();
7974 this.scanner.eat(EQUALSSIGN);
7975 }
7976
7977 return this.scanner.substrToCursor(start);
7978 }
7979
7980 // '[' S* attrib_name ']'
7981 // '[' S* attrib_name S* attrib_matcher S* [ IDENT | STRING ] S* attrib_flags? S* ']'
7982 var AttributeSelector = {
7983 name: 'AttributeSelector',
7984 structure: {
7985 name: 'Identifier',
7986 matcher: [String, null],
7987 value: ['String', 'Identifier', null],
7988 flags: [String, null]
7989 },
7990 parse: function() {
7991 var start = this.scanner.tokenStart;
7992 var name;
7993 var matcher = null;
7994 var value = null;
7995 var flags = null;
7996
7997 this.scanner.eat(LEFTSQUAREBRACKET$3);
7998 this.scanner.skipSC();
7999
8000 name = getAttributeName.call(this);
8001 this.scanner.skipSC();
8002
8003 if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
8004 // avoid case `[name i]`
8005 if (this.scanner.tokenType !== IDENTIFIER$8) {
8006 matcher = getOperator.call(this);
8007
8008 this.scanner.skipSC();
8009
8010 value = this.scanner.tokenType === STRING$4
8011 ? this.String()
8012 : this.Identifier();
8013
8014 this.scanner.skipSC();
8015 }
8016
8017 // attribute flags
8018 if (this.scanner.tokenType === IDENTIFIER$8) {
8019 flags = this.scanner.getTokenValue();
8020 this.scanner.next();
8021
8022 this.scanner.skipSC();
8023 }
8024 }
8025
8026 this.scanner.eat(RIGHTSQUAREBRACKET$1);
8027
8028 return {
8029 type: 'AttributeSelector',
8030 loc: this.getLocation(start, this.scanner.tokenStart),
8031 name: name,
8032 matcher: matcher,
8033 value: value,
8034 flags: flags
8035 };
8036 },
8037 generate: function(processChunk, node) {
8038 var flagsPrefix = ' ';
8039
8040 processChunk('[');
8041 this.generate(processChunk, node.name);
8042
8043 if (node.matcher !== null) {
8044 processChunk(node.matcher);
8045
8046 if (node.value !== null) {
8047 this.generate(processChunk, node.value);
8048
8049 // space between string and flags is not required
8050 if (node.value.type === 'String') {
8051 flagsPrefix = '';
8052 }
8053 }
8054 }
8055
8056 if (node.flags !== null) {
8057 processChunk(flagsPrefix);
8058 processChunk(node.flags);
8059 }
8060
8061 processChunk(']');
8062 }
8063 };
8064
8065 var TYPE$e = tokenizer$1.TYPE;
8066
8067 var WHITESPACE$4 = TYPE$e.WhiteSpace;
8068 var COMMENT$4 = TYPE$e.Comment;
8069 var SEMICOLON$3 = TYPE$e.Semicolon;
8070 var ATRULE$3 = TYPE$e.Atrule;
8071 var LEFTCURLYBRACKET$4 = TYPE$e.LeftCurlyBracket;
8072 var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
8073
8074 function consumeRaw$2(startToken) {
8075 return this.Raw(startToken, 0, SEMICOLON$3, true, true);
8076 }
8077
8078 var Block = {
8079 name: 'Block',
8080 structure: {
8081 children: [['Atrule', 'Rule', 'Declaration']]
8082 },
8083 parse: function(defaultConsumer) {
8084 if (!defaultConsumer) {
8085 defaultConsumer = this.Declaration;
8086 }
8087
8088 var start = this.scanner.tokenStart;
8089 var children = new list();
8090
8091 this.scanner.eat(LEFTCURLYBRACKET$4);
8092
8093 scan:
8094 while (!this.scanner.eof) {
8095 switch (this.scanner.tokenType) {
8096 case RIGHTCURLYBRACKET$2:
8097 break scan;
8098
8099 case WHITESPACE$4:
8100 case COMMENT$4:
8101 case SEMICOLON$3:
8102 this.scanner.next();
8103 break;
8104
8105 case ATRULE$3:
8106 children.appendData(this.tolerantParse(this.Atrule, consumeRaw$2));
8107 break;
8108
8109 default:
8110 children.appendData(this.tolerantParse(defaultConsumer, consumeRaw$2));
8111 }
8112 }
8113
8114 if (!this.tolerant || !this.scanner.eof) {
8115 this.scanner.eat(RIGHTCURLYBRACKET$2);
8116 }
8117
8118 return {
8119 type: 'Block',
8120 loc: this.getLocation(start, this.scanner.tokenStart),
8121 children: children
8122 };
8123 },
8124 generate: function(processChunk, node) {
8125 processChunk('{');
8126 this.each(processChunk, node);
8127 processChunk('}');
8128 },
8129 walkContext: 'block'
8130 };
8131
8132 var TYPE$f = tokenizer$1.TYPE;
8133 var LEFTSQUAREBRACKET$4 = TYPE$f.LeftSquareBracket;
8134 var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
8135
8136 // currently only Grid Layout uses square brackets, but left it universal
8137 // https://drafts.csswg.org/css-grid/#track-sizing
8138 // [ ident* ]
8139 var Brackets = {
8140 name: 'Brackets',
8141 structure: {
8142 children: [[]]
8143 },
8144 parse: function(readSequence, recognizer) {
8145 var start = this.scanner.tokenStart;
8146 var children = null;
8147
8148 this.scanner.eat(LEFTSQUAREBRACKET$4);
8149 children = readSequence.call(this, recognizer);
8150 this.scanner.eat(RIGHTSQUAREBRACKET$2);
8151
8152 return {
8153 type: 'Brackets',
8154 loc: this.getLocation(start, this.scanner.tokenStart),
8155 children: children
8156 };
8157 },
8158 generate: function(processChunk, node) {
8159 processChunk('[');
8160 this.each(processChunk, node);
8161 processChunk(']');
8162 }
8163 };
8164
8165 var CDC$2 = tokenizer$1.TYPE.CDC;
8166
8167 var CDC_1 = {
8168 name: 'CDC',
8169 structure: [],
8170 parse: function() {
8171 var start = this.scanner.tokenStart;
8172
8173 this.scanner.eat(CDC$2); // -->
8174
8175 return {
8176 type: 'CDC',
8177 loc: this.getLocation(start, this.scanner.tokenStart)
8178 };
8179 },
8180 generate: function(processChunk) {
8181 processChunk('-->');
8182 }
8183 };
8184
8185 var CDO$2 = tokenizer$1.TYPE.CDO;
8186
8187 var CDO_1 = {
8188 name: 'CDO',
8189 structure: [],
8190 parse: function() {
8191 var start = this.scanner.tokenStart;
8192
8193 this.scanner.eat(CDO$2); // <!--
8194
8195 return {
8196 type: 'CDO',
8197 loc: this.getLocation(start, this.scanner.tokenStart)
8198 };
8199 },
8200 generate: function(processChunk) {
8201 processChunk('<!--');
8202 }
8203 };
8204
8205 var TYPE$g = tokenizer$1.TYPE;
8206 var IDENTIFIER$9 = TYPE$g.Identifier;
8207 var FULLSTOP$3 = TYPE$g.FullStop;
8208
8209 // '.' ident
8210 var ClassSelector = {
8211 name: 'ClassSelector',
8212 structure: {
8213 name: String
8214 },
8215 parse: function() {
8216 this.scanner.eat(FULLSTOP$3);
8217
8218 return {
8219 type: 'ClassSelector',
8220 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
8221 name: this.scanner.consume(IDENTIFIER$9)
8222 };
8223 },
8224 generate: function(processChunk, node) {
8225 processChunk('.');
8226 processChunk(node.name);
8227 }
8228 };
8229
8230 var TYPE$h = tokenizer$1.TYPE;
8231
8232 var PLUSSIGN$5 = TYPE$h.PlusSign;
8233 var SOLIDUS$2 = TYPE$h.Solidus;
8234 var GREATERTHANSIGN$2 = TYPE$h.GreaterThanSign;
8235 var TILDE$2 = TYPE$h.Tilde;
8236
8237 // + | > | ~ | /deep/
8238 var Combinator = {
8239 name: 'Combinator',
8240 structure: {
8241 name: String
8242 },
8243 parse: function() {
8244 var start = this.scanner.tokenStart;
8245
8246 switch (this.scanner.tokenType) {
8247 case GREATERTHANSIGN$2:
8248 case PLUSSIGN$5:
8249 case TILDE$2:
8250 this.scanner.next();
8251 break;
8252
8253 case SOLIDUS$2:
8254 this.scanner.next();
8255 this.scanner.expectIdentifier('deep');
8256 this.scanner.eat(SOLIDUS$2);
8257 break;
8258
8259 default:
8260 this.scanner.error('Combinator is expected');
8261 }
8262
8263 return {
8264 type: 'Combinator',
8265 loc: this.getLocation(start, this.scanner.tokenStart),
8266 name: this.scanner.substrToCursor(start)
8267 };
8268 },
8269 generate: function(processChunk, node) {
8270 processChunk(node.name);
8271 }
8272 };
8273
8274 var TYPE$i = tokenizer$1.TYPE;
8275
8276 var ASTERISK$3 = TYPE$i.Asterisk;
8277 var SOLIDUS$3 = TYPE$i.Solidus;
8278
8279 // '/*' .* '*/'
8280 var Comment = {
8281 name: 'Comment',
8282 structure: {
8283 value: String
8284 },
8285 parse: function() {
8286 var start = this.scanner.tokenStart;
8287 var end = this.scanner.tokenEnd;
8288
8289 if ((end - start + 2) >= 2 &&
8290 this.scanner.source.charCodeAt(end - 2) === ASTERISK$3 &&
8291 this.scanner.source.charCodeAt(end - 1) === SOLIDUS$3) {
8292 end -= 2;
8293 }
8294
8295 this.scanner.next();
8296
8297 return {
8298 type: 'Comment',
8299 loc: this.getLocation(start, this.scanner.tokenStart),
8300 value: this.scanner.source.substring(start + 2, end)
8301 };
8302 },
8303 generate: function(processChunk, node) {
8304 processChunk('/*');
8305 processChunk(node.value);
8306 processChunk('*/');
8307 }
8308 };
8309
8310 var TYPE$j = tokenizer$1.TYPE;
8311
8312 var IDENTIFIER$a = TYPE$j.Identifier;
8313 var COLON$3 = TYPE$j.Colon;
8314 var EXCLAMATIONMARK$2 = TYPE$j.ExclamationMark;
8315 var SOLIDUS$4 = TYPE$j.Solidus;
8316 var ASTERISK$4 = TYPE$j.Asterisk;
8317 var DOLLARSIGN$1 = TYPE$j.DollarSign;
8318 var HYPHENMINUS$6 = TYPE$j.HyphenMinus;
8319 var SEMICOLON$4 = TYPE$j.Semicolon;
8320 var RIGHTCURLYBRACKET$3 = TYPE$j.RightCurlyBracket;
8321 var RIGHTPARENTHESIS$1 = TYPE$j.RightParenthesis;
8322 var PLUSSIGN$6 = TYPE$j.PlusSign;
8323 var NUMBERSIGN$2 = TYPE$j.NumberSign;
8324
8325 var Declaration = {
8326 name: 'Declaration',
8327 structure: {
8328 important: [Boolean, String],
8329 property: String,
8330 value: ['Value', 'Raw']
8331 },
8332 parse: function() {
8333 var start = this.scanner.tokenStart;
8334 var property = readProperty.call(this);
8335 var important = false;
8336 var value;
8337
8338 this.scanner.skipSC();
8339 this.scanner.eat(COLON$3);
8340
8341 if (isCustomProperty(property) ? this.parseCustomProperty : this.parseValue) {
8342 value = this.Value(property);
8343 } else {
8344 value = this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$2, SEMICOLON$4, false, false);
8345 }
8346
8347 if (this.scanner.tokenType === EXCLAMATIONMARK$2) {
8348 important = getImportant(this.scanner);
8349 this.scanner.skipSC();
8350 }
8351
8352 // TODO: include or not to include semicolon to range?
8353 // if (this.scanner.tokenType === SEMICOLON) {
8354 // this.scanner.next();
8355 // }
8356
8357 if (!this.scanner.eof &&
8358 this.scanner.tokenType !== SEMICOLON$4 &&
8359 this.scanner.tokenType !== RIGHTPARENTHESIS$1 &&
8360 this.scanner.tokenType !== RIGHTCURLYBRACKET$3) {
8361 this.scanner.error();
8362 }
8363
8364 return {
8365 type: 'Declaration',
8366 loc: this.getLocation(start, this.scanner.tokenStart),
8367 important: important,
8368 property: property,
8369 value: value
8370 };
8371 },
8372 generate: function(processChunk, node, item) {
8373 processChunk(node.property);
8374 processChunk(':');
8375 this.generate(processChunk, node.value);
8376
8377 if (node.important) {
8378 processChunk(node.important === true ? '!important' : '!' + node.important);
8379 }
8380
8381 if (item && item.next) {
8382 processChunk(';');
8383 }
8384 },
8385 walkContext: 'declaration'
8386 };
8387
8388 function isCustomProperty(name) {
8389 return name.length >= 2 &&
8390 name.charCodeAt(0) === HYPHENMINUS$6 &&
8391 name.charCodeAt(1) === HYPHENMINUS$6;
8392 }
8393
8394 function readProperty() {
8395 var start = this.scanner.tokenStart;
8396 var prefix = 0;
8397
8398 // hacks
8399 switch (this.scanner.tokenType) {
8400 case ASTERISK$4:
8401 case DOLLARSIGN$1:
8402 case PLUSSIGN$6:
8403 case NUMBERSIGN$2:
8404 prefix = 1;
8405 break;
8406
8407 // TODO: not sure we should support this hack
8408 case SOLIDUS$4:
8409 prefix = this.scanner.lookupType(1) === SOLIDUS$4 ? 2 : 1;
8410 break;
8411 }
8412
8413 if (this.scanner.lookupType(prefix) === HYPHENMINUS$6) {
8414 prefix++;
8415 }
8416
8417 if (prefix) {
8418 this.scanner.skip(prefix);
8419 }
8420
8421 this.scanner.eat(IDENTIFIER$a);
8422
8423 return this.scanner.substrToCursor(start);
8424 }
8425
8426 // ! ws* important
8427 function getImportant(scanner) {
8428 scanner.eat(EXCLAMATIONMARK$2);
8429 scanner.skipSC();
8430
8431 var important = scanner.consume(IDENTIFIER$a);
8432
8433 // store original value in case it differ from `important`
8434 // for better original source restoring and hacks like `!ie` support
8435 return important === 'important' ? true : important;
8436 }
8437
8438 var TYPE$k = tokenizer$1.TYPE;
8439
8440 var WHITESPACE$5 = TYPE$k.WhiteSpace;
8441 var COMMENT$5 = TYPE$k.Comment;
8442 var SEMICOLON$5 = TYPE$k.Semicolon;
8443
8444 function consumeRaw$3(startToken) {
8445 return this.Raw(startToken, 0, SEMICOLON$5, true, true);
8446 }
8447
8448 var DeclarationList = {
8449 name: 'DeclarationList',
8450 structure: {
8451 children: [['Declaration']]
8452 },
8453 parse: function() {
8454 var children = new list();
8455
8456 scan:
8457 while (!this.scanner.eof) {
8458 switch (this.scanner.tokenType) {
8459 case WHITESPACE$5:
8460 case COMMENT$5:
8461 case SEMICOLON$5:
8462 this.scanner.next();
8463 break;
8464
8465 default:
8466 children.appendData(this.tolerantParse(this.Declaration, consumeRaw$3));
8467 }
8468 }
8469
8470 return {
8471 type: 'DeclarationList',
8472 loc: this.getLocationFromList(children),
8473 children: children
8474 };
8475 },
8476 generate: function(processChunk, node) {
8477 this.each(processChunk, node);
8478 }
8479 };
8480
8481 var NUMBER$5 = tokenizer$1.TYPE.Number;
8482
8483 // special reader for units to avoid adjoined IE hacks (i.e. '1px\9')
8484 function readUnit(scanner) {
8485 var unit = scanner.getTokenValue();
8486 var backSlashPos = unit.indexOf('\\');
8487
8488 if (backSlashPos > 0) {
8489 // patch token offset
8490 scanner.tokenStart += backSlashPos;
8491
8492 // return part before backslash
8493 return unit.substring(0, backSlashPos);
8494 }
8495
8496 // no backslash in unit name
8497 scanner.next();
8498
8499 return unit;
8500 }
8501
8502 // number ident
8503 var Dimension = {
8504 name: 'Dimension',
8505 structure: {
8506 value: String,
8507 unit: String
8508 },
8509 parse: function() {
8510 var start = this.scanner.tokenStart;
8511 var value = this.scanner.consume(NUMBER$5);
8512 var unit = readUnit(this.scanner);
8513
8514 return {
8515 type: 'Dimension',
8516 loc: this.getLocation(start, this.scanner.tokenStart),
8517 value: value,
8518 unit: unit
8519 };
8520 },
8521 generate: function(processChunk, node) {
8522 processChunk(node.value);
8523 processChunk(node.unit);
8524 }
8525 };
8526
8527 var TYPE$l = tokenizer$1.TYPE;
8528 var RIGHTPARENTHESIS$2 = TYPE$l.RightParenthesis;
8529
8530 // <function-token> <sequence> ')'
8531 var _Function = {
8532 name: 'Function',
8533 structure: {
8534 name: String,
8535 children: [[]]
8536 },
8537 parse: function(readSequence, recognizer) {
8538 var start = this.scanner.tokenStart;
8539 var name = this.scanner.consumeFunctionName();
8540 var nameLowerCase = name.toLowerCase();
8541 var children;
8542
8543 children = recognizer.hasOwnProperty(nameLowerCase)
8544 ? recognizer[nameLowerCase].call(this, recognizer)
8545 : readSequence.call(this, recognizer);
8546
8547 this.scanner.eat(RIGHTPARENTHESIS$2);
8548
8549 return {
8550 type: 'Function',
8551 loc: this.getLocation(start, this.scanner.tokenStart),
8552 name: name,
8553 children: children
8554 };
8555 },
8556 generate: function(processChunk, node) {
8557 processChunk(node.name);
8558 processChunk('(');
8559 this.each(processChunk, node);
8560 processChunk(')');
8561 },
8562 walkContext: 'function'
8563 };
8564
8565 var isHex$1 = tokenizer$1.isHex;
8566 var TYPE$m = tokenizer$1.TYPE;
8567
8568 var IDENTIFIER$b = TYPE$m.Identifier;
8569 var NUMBER$6 = TYPE$m.Number;
8570 var NUMBERSIGN$3 = TYPE$m.NumberSign;
8571
8572 function consumeHexSequence(scanner, required) {
8573 if (!isHex$1(scanner.source.charCodeAt(scanner.tokenStart))) {
8574 if (required) {
8575 scanner.error('Unexpected input', scanner.tokenStart);
8576 } else {
8577 return;
8578 }
8579 }
8580
8581 for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
8582 var code = scanner.source.charCodeAt(pos);
8583
8584 // break on non-hex char
8585 if (!isHex$1(code)) {
8586 // break token, exclude symbol
8587 scanner.tokenStart = pos;
8588 return;
8589 }
8590 }
8591
8592 // token is full hex sequence, go to next token
8593 scanner.next();
8594 }
8595
8596 // # ident
8597 var HexColor = {
8598 name: 'HexColor',
8599 structure: {
8600 value: String
8601 },
8602 parse: function() {
8603 var start = this.scanner.tokenStart;
8604
8605 this.scanner.eat(NUMBERSIGN$3);
8606
8607 scan:
8608 switch (this.scanner.tokenType) {
8609 case NUMBER$6:
8610 consumeHexSequence(this.scanner, true);
8611
8612 // if token is identifier then number consists of hex only,
8613 // try to add identifier to result
8614 if (this.scanner.tokenType === IDENTIFIER$b) {
8615 consumeHexSequence(this.scanner, false);
8616 }
8617
8618 break;
8619
8620 case IDENTIFIER$b:
8621 consumeHexSequence(this.scanner, true);
8622 break;
8623
8624 default:
8625 this.scanner.error('Number or identifier is expected');
8626 }
8627
8628 return {
8629 type: 'HexColor',
8630 loc: this.getLocation(start, this.scanner.tokenStart),
8631 value: this.scanner.substrToCursor(start + 1) // skip #
8632 };
8633 },
8634 generate: function(processChunk, node) {
8635 processChunk('#');
8636 processChunk(node.value);
8637 }
8638 };
8639
8640 var TYPE$n = tokenizer$1.TYPE;
8641 var IDENTIFIER$c = TYPE$n.Identifier;
8642
8643 var Identifier = {
8644 name: 'Identifier',
8645 structure: {
8646 name: String
8647 },
8648 parse: function() {
8649 return {
8650 type: 'Identifier',
8651 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
8652 name: this.scanner.consume(IDENTIFIER$c)
8653 };
8654 },
8655 generate: function(processChunk, node) {
8656 processChunk(node.name);
8657 }
8658 };
8659
8660 var TYPE$o = tokenizer$1.TYPE;
8661 var IDENTIFIER$d = TYPE$o.Identifier;
8662 var NUMBERSIGN$4 = TYPE$o.NumberSign;
8663
8664 // '#' ident
8665 var IdSelector = {
8666 name: 'IdSelector',
8667 structure: {
8668 name: String
8669 },
8670 parse: function() {
8671 this.scanner.eat(NUMBERSIGN$4);
8672
8673 return {
8674 type: 'IdSelector',
8675 loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
8676 name: this.scanner.consume(IDENTIFIER$d)
8677 };
8678 },
8679 generate: function(processChunk, node) {
8680 processChunk('#');
8681 processChunk(node.name);
8682 }
8683 };
8684
8685 var TYPE$p = tokenizer$1.TYPE;
8686
8687 var IDENTIFIER$e = TYPE$p.Identifier;
8688 var NUMBER$7 = TYPE$p.Number;
8689 var LEFTPARENTHESIS$4 = TYPE$p.LeftParenthesis;
8690 var RIGHTPARENTHESIS$3 = TYPE$p.RightParenthesis;
8691 var COLON$4 = TYPE$p.Colon;
8692 var SOLIDUS$5 = TYPE$p.Solidus;
8693
8694 var MediaFeature = {
8695 name: 'MediaFeature',
8696 structure: {
8697 name: String,
8698 value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
8699 },
8700 parse: function() {
8701 var start = this.scanner.tokenStart;
8702 var name;
8703 var value = null;
8704
8705 this.scanner.eat(LEFTPARENTHESIS$4);
8706 this.scanner.skipSC();
8707
8708 name = this.scanner.consume(IDENTIFIER$e);
8709 this.scanner.skipSC();
8710
8711 if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
8712 this.scanner.eat(COLON$4);
8713 this.scanner.skipSC();
8714
8715 switch (this.scanner.tokenType) {
8716 case NUMBER$7:
8717 if (this.scanner.lookupType(1) === IDENTIFIER$e) {
8718 value = this.Dimension();
8719 } else if (this.scanner.lookupNonWSType(1) === SOLIDUS$5) {
8720 value = this.Ratio();
8721 } else {
8722 value = this.Number();
8723 }
8724
8725 break;
8726
8727 case IDENTIFIER$e:
8728 value = this.Identifier();
8729
8730 break;
8731
8732 default:
8733 this.scanner.error('Number, dimension, ratio or identifier is expected');
8734 }
8735
8736 this.scanner.skipSC();
8737 }
8738
8739 this.scanner.eat(RIGHTPARENTHESIS$3);
8740
8741 return {
8742 type: 'MediaFeature',
8743 loc: this.getLocation(start, this.scanner.tokenStart),
8744 name: name,
8745 value: value
8746 };
8747 },
8748 generate: function(processChunk, node) {
8749 processChunk('(');
8750 processChunk(node.name);
8751 if (node.value !== null) {
8752 processChunk(':');
8753 this.generate(processChunk, node.value);
8754 }
8755 processChunk(')');
8756 }
8757 };
8758
8759 var TYPE$q = tokenizer$1.TYPE;
8760
8761 var WHITESPACE$6 = TYPE$q.WhiteSpace;
8762 var COMMENT$6 = TYPE$q.Comment;
8763 var IDENTIFIER$f = TYPE$q.Identifier;
8764 var LEFTPARENTHESIS$5 = TYPE$q.LeftParenthesis;
8765
8766 var MediaQuery = {
8767 name: 'MediaQuery',
8768 structure: {
8769 children: [['Identifier', 'MediaFeature', 'WhiteSpace']]
8770 },
8771 parse: function() {
8772 this.scanner.skipSC();
8773
8774 var children = new list();
8775 var child = null;
8776 var space = null;
8777
8778 scan:
8779 while (!this.scanner.eof) {
8780 switch (this.scanner.tokenType) {
8781 case COMMENT$6:
8782 this.scanner.next();
8783 continue;
8784
8785 case WHITESPACE$6:
8786 space = this.WhiteSpace();
8787 continue;
8788
8789 case IDENTIFIER$f:
8790 child = this.Identifier();
8791 break;
8792
8793 case LEFTPARENTHESIS$5:
8794 child = this.MediaFeature();
8795 break;
8796
8797 default:
8798 break scan;
8799 }
8800
8801 if (space !== null) {
8802 children.appendData(space);
8803 space = null;
8804 }
8805
8806 children.appendData(child);
8807 }
8808
8809 if (child === null) {
8810 this.scanner.error('Identifier or parenthesis is expected');
8811 }
8812
8813 return {
8814 type: 'MediaQuery',
8815 loc: this.getLocationFromList(children),
8816 children: children
8817 };
8818 },
8819 generate: function(processChunk, node) {
8820 this.each(processChunk, node);
8821 }
8822 };
8823
8824 var COMMA$2 = tokenizer$1.TYPE.Comma;
8825
8826 var MediaQueryList = {
8827 name: 'MediaQueryList',
8828 structure: {
8829 children: [['MediaQuery']]
8830 },
8831 parse: function(relative) {
8832 var children = new list();
8833
8834 this.scanner.skipSC();
8835
8836 while (!this.scanner.eof) {
8837 children.appendData(this.MediaQuery(relative));
8838
8839 if (this.scanner.tokenType !== COMMA$2) {
8840 break;
8841 }
8842
8843 this.scanner.next();
8844 }
8845
8846 return {
8847 type: 'MediaQueryList',
8848 loc: this.getLocationFromList(children),
8849 children: children
8850 };
8851 },
8852 generate: function(processChunk, node) {
8853 this.eachComma(processChunk, node);
8854 }
8855 };
8856
8857 // https://drafts.csswg.org/css-syntax-3/#the-anb-type
8858 var Nth = {
8859 name: 'Nth',
8860 structure: {
8861 nth: ['AnPlusB', 'Identifier'],
8862 selector: ['SelectorList', null]
8863 },
8864 parse: function(allowOfClause) {
8865 this.scanner.skipSC();
8866
8867 var start = this.scanner.tokenStart;
8868 var end = start;
8869 var selector = null;
8870 var query;
8871
8872 if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
8873 query = this.Identifier();
8874 } else {
8875 query = this.AnPlusB();
8876 }
8877
8878 this.scanner.skipSC();
8879
8880 if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
8881 this.scanner.next();
8882
8883 selector = this.SelectorList();
8884
8885 if (this.needPositions) {
8886 end = selector.children.last().loc.end.offset;
8887 }
8888 } else {
8889 if (this.needPositions) {
8890 end = query.loc.end.offset;
8891 }
8892 }
8893
8894 return {
8895 type: 'Nth',
8896 loc: this.getLocation(start, end),
8897 nth: query,
8898 selector: selector
8899 };
8900 },
8901 generate: function(processChunk, node) {
8902 this.generate(processChunk, node.nth);
8903 if (node.selector !== null) {
8904 processChunk(' of ');
8905 this.generate(processChunk, node.selector);
8906 }
8907 }
8908 };
8909
8910 var NUMBER$8 = tokenizer$1.TYPE.Number;
8911
8912 var _Number = {
8913 name: 'Number',
8914 structure: {
8915 value: String
8916 },
8917 parse: function() {
8918 return {
8919 type: 'Number',
8920 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
8921 value: this.scanner.consume(NUMBER$8)
8922 };
8923 },
8924 generate: function(processChunk, node) {
8925 processChunk(node.value);
8926 }
8927 };
8928
8929 // '/' | '*' | ',' | ':' | '+' | '-'
8930 var Operator = {
8931 name: 'Operator',
8932 structure: {
8933 value: String
8934 },
8935 parse: function() {
8936 var start = this.scanner.tokenStart;
8937
8938 this.scanner.next();
8939
8940 return {
8941 type: 'Operator',
8942 loc: this.getLocation(start, this.scanner.tokenStart),
8943 value: this.scanner.substrToCursor(start)
8944 };
8945 },
8946 generate: function(processChunk, node) {
8947 processChunk(node.value);
8948 }
8949 };
8950
8951 var TYPE$r = tokenizer$1.TYPE;
8952 var LEFTPARENTHESIS$6 = TYPE$r.LeftParenthesis;
8953 var RIGHTPARENTHESIS$4 = TYPE$r.RightParenthesis;
8954
8955 var Parentheses = {
8956 name: 'Parentheses',
8957 structure: {
8958 children: [[]]
8959 },
8960 parse: function(readSequence, recognizer) {
8961 var start = this.scanner.tokenStart;
8962 var children = null;
8963
8964 this.scanner.eat(LEFTPARENTHESIS$6);
8965 children = readSequence.call(this, recognizer);
8966 this.scanner.eat(RIGHTPARENTHESIS$4);
8967
8968 return {
8969 type: 'Parentheses',
8970 loc: this.getLocation(start, this.scanner.tokenStart),
8971 children: children
8972 };
8973 },
8974 generate: function(processChunk, node) {
8975 processChunk('(');
8976 this.each(processChunk, node);
8977 processChunk(')');
8978 }
8979 };
8980
8981 var TYPE$s = tokenizer$1.TYPE;
8982
8983 var NUMBER$9 = TYPE$s.Number;
8984 var PERCENTSIGN$1 = TYPE$s.PercentSign;
8985
8986 var Percentage = {
8987 name: 'Percentage',
8988 structure: {
8989 value: String
8990 },
8991 parse: function() {
8992 var start = this.scanner.tokenStart;
8993 var number = this.scanner.consume(NUMBER$9);
8994
8995 this.scanner.eat(PERCENTSIGN$1);
8996
8997 return {
8998 type: 'Percentage',
8999 loc: this.getLocation(start, this.scanner.tokenStart),
9000 value: number
9001 };
9002 },
9003 generate: function(processChunk, node) {
9004 processChunk(node.value);
9005 processChunk('%');
9006 }
9007 };
9008
9009 var TYPE$t = tokenizer$1.TYPE;
9010
9011 var IDENTIFIER$g = TYPE$t.Identifier;
9012 var FUNCTION$4 = TYPE$t.Function;
9013 var COLON$5 = TYPE$t.Colon;
9014 var RIGHTPARENTHESIS$5 = TYPE$t.RightParenthesis;
9015
9016 // : ident [ '(' .. ')' ]?
9017 var PseudoClassSelector = {
9018 name: 'PseudoClassSelector',
9019 structure: {
9020 name: String,
9021 children: [['Raw'], null]
9022 },
9023 parse: function() {
9024 var start = this.scanner.tokenStart;
9025 var children = null;
9026 var name;
9027 var nameLowerCase;
9028
9029 this.scanner.eat(COLON$5);
9030
9031 if (this.scanner.tokenType === FUNCTION$4) {
9032 name = this.scanner.consumeFunctionName();
9033 nameLowerCase = name.toLowerCase();
9034
9035 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
9036 this.scanner.skipSC();
9037 children = this.pseudo[nameLowerCase].call(this);
9038 this.scanner.skipSC();
9039 } else {
9040 children = new list().appendData(
9041 this.Raw(this.scanner.currentToken, 0, 0, false, false)
9042 );
9043 }
9044
9045 this.scanner.eat(RIGHTPARENTHESIS$5);
9046 } else {
9047 name = this.scanner.consume(IDENTIFIER$g);
9048 }
9049
9050 return {
9051 type: 'PseudoClassSelector',
9052 loc: this.getLocation(start, this.scanner.tokenStart),
9053 name: name,
9054 children: children
9055 };
9056 },
9057 generate: function(processChunk, node) {
9058 processChunk(':');
9059 processChunk(node.name);
9060
9061 if (node.children !== null) {
9062 processChunk('(');
9063 this.each(processChunk, node);
9064 processChunk(')');
9065 }
9066 },
9067 walkContext: 'function'
9068 };
9069
9070 var TYPE$u = tokenizer$1.TYPE;
9071
9072 var IDENTIFIER$h = TYPE$u.Identifier;
9073 var FUNCTION$5 = TYPE$u.Function;
9074 var COLON$6 = TYPE$u.Colon;
9075 var RIGHTPARENTHESIS$6 = TYPE$u.RightParenthesis;
9076
9077 // :: ident [ '(' .. ')' ]?
9078 var PseudoElementSelector = {
9079 name: 'PseudoElementSelector',
9080 structure: {
9081 name: String,
9082 children: [['Raw'], null]
9083 },
9084 parse: function() {
9085 var start = this.scanner.tokenStart;
9086 var children = null;
9087 var name;
9088 var nameLowerCase;
9089
9090 this.scanner.eat(COLON$6);
9091 this.scanner.eat(COLON$6);
9092
9093 if (this.scanner.tokenType === FUNCTION$5) {
9094 name = this.scanner.consumeFunctionName();
9095 nameLowerCase = name.toLowerCase();
9096
9097 if (this.pseudo.hasOwnProperty(nameLowerCase)) {
9098 this.scanner.skipSC();
9099 children = this.pseudo[nameLowerCase].call(this);
9100 this.scanner.skipSC();
9101 } else {
9102 children = new list().appendData(
9103 this.Raw(this.scanner.currentToken, 0, 0, false, false)
9104 );
9105 }
9106
9107 this.scanner.eat(RIGHTPARENTHESIS$6);
9108 } else {
9109 name = this.scanner.consume(IDENTIFIER$h);
9110 }
9111
9112 return {
9113 type: 'PseudoElementSelector',
9114 loc: this.getLocation(start, this.scanner.tokenStart),
9115 name: name,
9116 children: children
9117 };
9118 },
9119 generate: function(processChunk, node) {
9120 processChunk('::');
9121 processChunk(node.name);
9122
9123 if (node.children !== null) {
9124 processChunk('(');
9125 this.each(processChunk, node);
9126 processChunk(')');
9127 }
9128 },
9129 walkContext: 'function'
9130 };
9131
9132 var isNumber$3 = tokenizer$1.isNumber;
9133 var TYPE$v = tokenizer$1.TYPE;
9134 var NUMBER$a = TYPE$v.Number;
9135 var SOLIDUS$6 = TYPE$v.Solidus;
9136 var FULLSTOP$4 = TYPE$v.FullStop;
9137
9138 // Terms of <ratio> should to be a positive number (not zero or negative)
9139 // (see https://drafts.csswg.org/mediaqueries-3/#values)
9140 // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
9141 // and this is using by various sites. Therefore we relax checking on parse
9142 // to test a term is unsigned number without exponent part.
9143 // Additional checks may to be applied on lexer validation.
9144 function consumeNumber(scanner) {
9145 var value = scanner.consumeNonWS(NUMBER$a);
9146
9147 for (var i = 0; i < value.length; i++) {
9148 var code = value.charCodeAt(i);
9149 if (!isNumber$3(code) && code !== FULLSTOP$4) {
9150 scanner.error('Unsigned number is expected', scanner.tokenStart - value.length + i);
9151 }
9152 }
9153
9154 if (Number(value) === 0) {
9155 scanner.error('Zero number is not allowed', scanner.tokenStart - value.length);
9156 }
9157
9158 return value;
9159 }
9160
9161 // <positive-integer> S* '/' S* <positive-integer>
9162 var Ratio = {
9163 name: 'Ratio',
9164 structure: {
9165 left: String,
9166 right: String
9167 },
9168 parse: function() {
9169 var start = this.scanner.tokenStart;
9170 var left = consumeNumber(this.scanner);
9171 var right;
9172
9173 this.scanner.eatNonWS(SOLIDUS$6);
9174 right = consumeNumber(this.scanner);
9175
9176 return {
9177 type: 'Ratio',
9178 loc: this.getLocation(start, this.scanner.tokenStart),
9179 left: left,
9180 right: right
9181 };
9182 },
9183 generate: function(processChunk, node) {
9184 processChunk(node.left);
9185 processChunk('/');
9186 processChunk(node.right);
9187 }
9188 };
9189
9190 var Raw = {
9191 name: 'Raw',
9192 structure: {
9193 value: String
9194 },
9195 parse: function(startToken, endTokenType1, endTokenType2, includeTokenType2, excludeWhiteSpace) {
9196 var startOffset = this.scanner.getTokenStart(startToken);
9197 var endOffset;
9198
9199 this.scanner.skip(
9200 this.scanner.getRawLength(
9201 startToken,
9202 endTokenType1,
9203 endTokenType2,
9204 includeTokenType2
9205 )
9206 );
9207
9208 if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
9209 endOffset = this.scanner.getOffsetExcludeWS();
9210 } else {
9211 endOffset = this.scanner.tokenStart;
9212 }
9213
9214 return {
9215 type: 'Raw',
9216 loc: this.getLocation(startOffset, endOffset),
9217 value: this.scanner.source.substring(startOffset, endOffset)
9218 };
9219 },
9220 generate: function(processChunk, node) {
9221 processChunk(node.value);
9222 }
9223 };
9224
9225 var TYPE$w = tokenizer$1.TYPE;
9226
9227 var LEFTCURLYBRACKET$5 = TYPE$w.LeftCurlyBracket;
9228
9229 function consumeRaw$4(startToken) {
9230 return this.Raw(startToken, LEFTCURLYBRACKET$5, 0, false, true);
9231 }
9232
9233 var Rule = {
9234 name: 'Rule',
9235 structure: {
9236 selector: ['SelectorList', 'Raw'],
9237 block: ['Block']
9238 },
9239 parse: function() {
9240 var startToken = this.scanner.currentToken;
9241 var startOffset = this.scanner.tokenStart;
9242 var selector = this.parseSelector
9243 ? this.tolerantParse(this.SelectorList, consumeRaw$4)
9244 : consumeRaw$4.call(this, startToken);
9245 var block = this.Block(this.Declaration);
9246
9247 return {
9248 type: 'Rule',
9249 loc: this.getLocation(startOffset, this.scanner.tokenStart),
9250 selector: selector,
9251 block: block
9252 };
9253 },
9254 generate: function(processChunk, node) {
9255 this.generate(processChunk, node.selector);
9256 this.generate(processChunk, node.block);
9257 },
9258 walkContext: 'rule'
9259 };
9260
9261 var Selector = {
9262 name: 'Selector',
9263 structure: {
9264 children: [[
9265 'TypeSelector',
9266 'IdSelector',
9267 'ClassSelector',
9268 'AttributeSelector',
9269 'PseudoClassSelector',
9270 'PseudoElementSelector',
9271 'Combinator',
9272 'WhiteSpace'
9273 ]]
9274 },
9275 parse: function() {
9276 var children = this.readSequence(this.scope.Selector);
9277
9278 // nothing were consumed
9279 if (children.isEmpty()) {
9280 this.scanner.error('Selector is expected');
9281 }
9282
9283 return {
9284 type: 'Selector',
9285 loc: this.getLocationFromList(children),
9286 children: children
9287 };
9288 },
9289 generate: function(processChunk, node) {
9290 this.each(processChunk, node);
9291 }
9292 };
9293
9294 var TYPE$x = tokenizer$1.TYPE;
9295
9296 var COMMA$3 = TYPE$x.Comma;
9297 var LEFTCURLYBRACKET$6 = TYPE$x.LeftCurlyBracket;
9298
9299 var SelectorList = {
9300 name: 'SelectorList',
9301 structure: {
9302 children: [['Selector', 'Raw']]
9303 },
9304 parse: function() {
9305 var children = new list();
9306
9307 while (!this.scanner.eof) {
9308 children.appendData(this.parseSelector
9309 ? this.Selector()
9310 : this.Raw(this.scanner.currentToken, COMMA$3, LEFTCURLYBRACKET$6, false, false)
9311 );
9312
9313 if (this.scanner.tokenType === COMMA$3) {
9314 this.scanner.next();
9315 continue;
9316 }
9317
9318 break;
9319 }
9320
9321 return {
9322 type: 'SelectorList',
9323 loc: this.getLocationFromList(children),
9324 children: children
9325 };
9326 },
9327 generate: function(processChunk, node) {
9328 this.eachComma(processChunk, node);
9329 },
9330 walkContext: 'selector'
9331 };
9332
9333 var STRING$5 = tokenizer$1.TYPE.String;
9334
9335 var _String = {
9336 name: 'String',
9337 structure: {
9338 value: String
9339 },
9340 parse: function() {
9341 return {
9342 type: 'String',
9343 loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
9344 value: this.scanner.consume(STRING$5)
9345 };
9346 },
9347 generate: function(processChunk, node) {
9348 processChunk(node.value);
9349 }
9350 };
9351
9352 var TYPE$y = tokenizer$1.TYPE;
9353
9354 var WHITESPACE$7 = TYPE$y.WhiteSpace;
9355 var COMMENT$7 = TYPE$y.Comment;
9356 var EXCLAMATIONMARK$3 = TYPE$y.ExclamationMark;
9357 var ATRULE$4 = TYPE$y.Atrule;
9358 var CDO$3 = TYPE$y.CDO;
9359 var CDC$3 = TYPE$y.CDC;
9360
9361 function consumeRaw$5(startToken) {
9362 return this.Raw(startToken, 0, 0, false, false);
9363 }
9364
9365 var StyleSheet = {
9366 name: 'StyleSheet',
9367 structure: {
9368 children: [['Comment', 'Atrule', 'Rule', 'Raw']]
9369 },
9370 parse: function() {
9371 var start = this.scanner.tokenStart;
9372 var children = new list();
9373 var child;
9374
9375 scan:
9376 while (!this.scanner.eof) {
9377 switch (this.scanner.tokenType) {
9378 case WHITESPACE$7:
9379 this.scanner.next();
9380 continue;
9381
9382 case COMMENT$7:
9383 // ignore comments except exclamation comments (i.e. /*! .. */) on top level
9384 if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
9385 this.scanner.next();
9386 continue;
9387 }
9388
9389 child = this.Comment();
9390 break;
9391
9392 case CDO$3: // <!--
9393 child = this.CDO();
9394 break;
9395
9396 case CDC$3: // -->
9397 child = this.CDC();
9398 break;
9399
9400 // CSS Syntax Module Level 3
9401 // §2.2 Error handling
9402 // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
9403 case ATRULE$4:
9404 child = this.Atrule();
9405 break;
9406
9407 // Anything else starts a qualified rule ...
9408 default:
9409 child = this.tolerantParse(this.Rule, consumeRaw$5);
9410 }
9411
9412 children.appendData(child);
9413 }
9414
9415 return {
9416 type: 'StyleSheet',
9417 loc: this.getLocation(start, this.scanner.tokenStart),
9418 children: children
9419 };
9420 },
9421 generate: function(processChunk, node) {
9422 this.each(processChunk, node);
9423 },
9424 walkContext: 'stylesheet'
9425 };
9426
9427 var TYPE$z = tokenizer$1.TYPE;
9428
9429 var IDENTIFIER$i = TYPE$z.Identifier;
9430 var ASTERISK$5 = TYPE$z.Asterisk;
9431 var VERTICALLINE$2 = TYPE$z.VerticalLine;
9432
9433 function eatIdentifierOrAsterisk() {
9434 if (this.scanner.tokenType !== IDENTIFIER$i &&
9435 this.scanner.tokenType !== ASTERISK$5) {
9436 this.scanner.error('Identifier or asterisk is expected');
9437 }
9438
9439 this.scanner.next();
9440 }
9441
9442 // ident
9443 // ident|ident
9444 // ident|*
9445 // *
9446 // *|ident
9447 // *|*
9448 // |ident
9449 // |*
9450 var TypeSelector = {
9451 name: 'TypeSelector',
9452 structure: {
9453 name: String
9454 },
9455 parse: function() {
9456 var start = this.scanner.tokenStart;
9457
9458 if (this.scanner.tokenType === VERTICALLINE$2) {
9459 this.scanner.next();
9460 eatIdentifierOrAsterisk.call(this);
9461 } else {
9462 eatIdentifierOrAsterisk.call(this);
9463
9464 if (this.scanner.tokenType === VERTICALLINE$2) {
9465 this.scanner.next();
9466 eatIdentifierOrAsterisk.call(this);
9467 }
9468 }
9469
9470 return {
9471 type: 'TypeSelector',
9472 loc: this.getLocation(start, this.scanner.tokenStart),
9473 name: this.scanner.substrToCursor(start)
9474 };
9475 },
9476 generate: function(processChunk, node) {
9477 processChunk(node.name);
9478 }
9479 };
9480
9481 var isHex$2 = tokenizer$1.isHex;
9482 var TYPE$A = tokenizer$1.TYPE;
9483
9484 var IDENTIFIER$j = TYPE$A.Identifier;
9485 var NUMBER$b = TYPE$A.Number;
9486 var PLUSSIGN$7 = TYPE$A.PlusSign;
9487 var HYPHENMINUS$7 = TYPE$A.HyphenMinus;
9488 var FULLSTOP$5 = TYPE$A.FullStop;
9489 var QUESTIONMARK = TYPE$A.QuestionMark;
9490
9491 function scanUnicodeNumber(scanner) {
9492 for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
9493 var code = scanner.source.charCodeAt(pos);
9494
9495 // break on fullstop or hyperminus/plussign after exponent
9496 if (code === FULLSTOP$5 || code === PLUSSIGN$7) {
9497 // break token, exclude symbol
9498 scanner.tokenStart = pos;
9499 return false;
9500 }
9501 }
9502
9503 return true;
9504 }
9505
9506 // https://drafts.csswg.org/css-syntax-3/#urange
9507 function scanUnicodeRange(scanner) {
9508 var hexStart = scanner.tokenStart + 1; // skip +
9509 var hexLength = 0;
9510
9511 scan: {
9512 if (scanner.tokenType === NUMBER$b) {
9513 if (scanner.source.charCodeAt(scanner.tokenStart) !== FULLSTOP$5 && scanUnicodeNumber(scanner)) {
9514 scanner.next();
9515 } else if (scanner.source.charCodeAt(scanner.tokenStart) !== HYPHENMINUS$7) {
9516 break scan;
9517 }
9518 } else {
9519 scanner.next(); // PLUSSIGN
9520 }
9521
9522 if (scanner.tokenType === HYPHENMINUS$7) {
9523 scanner.next();
9524 }
9525
9526 if (scanner.tokenType === NUMBER$b) {
9527 scanner.next();
9528 }
9529
9530 if (scanner.tokenType === IDENTIFIER$j) {
9531 scanner.next();
9532 }
9533
9534 if (scanner.tokenStart === hexStart) {
9535 scanner.error('Unexpected input', hexStart);
9536 }
9537 }
9538
9539 // validate for U+x{1,6} or U+x{1,6}-x{1,6}
9540 // where x is [0-9a-fA-F]
9541 for (var i = hexStart, wasHyphenMinus = false; i < scanner.tokenStart; i++) {
9542 var code = scanner.source.charCodeAt(i);
9543
9544 if (isHex$2(code) === false && (code !== HYPHENMINUS$7 || wasHyphenMinus)) {
9545 scanner.error('Unexpected input', i);
9546 }
9547
9548 if (code === HYPHENMINUS$7) {
9549 // hex sequence shouldn't be an empty
9550 if (hexLength === 0) {
9551 scanner.error('Unexpected input', i);
9552 }
9553
9554 wasHyphenMinus = true;
9555 hexLength = 0;
9556 } else {
9557 hexLength++;
9558
9559 // too long hex sequence
9560 if (hexLength > 6) {
9561 scanner.error('Too long hex sequence', i);
9562 }
9563 }
9564
9565 }
9566
9567 // check we have a non-zero sequence
9568 if (hexLength === 0) {
9569 scanner.error('Unexpected input', i - 1);
9570 }
9571
9572 // U+abc???
9573 if (!wasHyphenMinus) {
9574 // consume as many U+003F QUESTION MARK (?) code points as possible
9575 for (; hexLength < 6 && !scanner.eof; scanner.next()) {
9576 if (scanner.tokenType !== QUESTIONMARK) {
9577 break;
9578 }
9579
9580 hexLength++;
9581 }
9582 }
9583 }
9584
9585 var UnicodeRange = {
9586 name: 'UnicodeRange',
9587 structure: {
9588 value: String
9589 },
9590 parse: function() {
9591 var start = this.scanner.tokenStart;
9592
9593 this.scanner.next(); // U or u
9594 scanUnicodeRange(this.scanner);
9595
9596 return {
9597 type: 'UnicodeRange',
9598 loc: this.getLocation(start, this.scanner.tokenStart),
9599 value: this.scanner.substrToCursor(start)
9600 };
9601 },
9602 generate: function(processChunk, node) {
9603 processChunk(node.value);
9604 }
9605 };
9606
9607 var TYPE$B = tokenizer$1.TYPE;
9608
9609 var STRING$6 = TYPE$B.String;
9610 var URL$4 = TYPE$B.Url;
9611 var RAW$2 = TYPE$B.Raw;
9612 var RIGHTPARENTHESIS$7 = TYPE$B.RightParenthesis;
9613
9614 // url '(' S* (string | raw) S* ')'
9615 var Url = {
9616 name: 'Url',
9617 structure: {
9618 value: ['String', 'Raw']
9619 },
9620 parse: function() {
9621 var start = this.scanner.tokenStart;
9622 var value;
9623
9624 this.scanner.eat(URL$4);
9625 this.scanner.skipSC();
9626
9627 switch (this.scanner.tokenType) {
9628 case STRING$6:
9629 value = this.String();
9630 break;
9631
9632 case RAW$2:
9633 value = this.Raw(this.scanner.currentToken, 0, RAW$2, true, false);
9634 break;
9635
9636 default:
9637 this.scanner.error('String or Raw is expected');
9638 }
9639
9640 this.scanner.skipSC();
9641 this.scanner.eat(RIGHTPARENTHESIS$7);
9642
9643 return {
9644 type: 'Url',
9645 loc: this.getLocation(start, this.scanner.tokenStart),
9646 value: value
9647 };
9648 },
9649 generate: function(processChunk, node) {
9650 processChunk('url');
9651 processChunk('(');
9652 this.generate(processChunk, node.value);
9653 processChunk(')');
9654 }
9655 };
9656
9657 var endsWith$1 = tokenizer$1.endsWith;
9658 var TYPE$C = tokenizer$1.TYPE;
9659
9660 var WHITESPACE$8 = TYPE$C.WhiteSpace;
9661 var COMMENT$8 = TYPE$C.Comment;
9662 var FUNCTION$6 = TYPE$C.Function;
9663 var COLON$7 = TYPE$C.Colon;
9664 var SEMICOLON$6 = TYPE$C.Semicolon;
9665 var EXCLAMATIONMARK$4 = TYPE$C.ExclamationMark;
9666
9667 // 'progid:' ws* 'DXImageTransform.Microsoft.' ident ws* '(' .* ')'
9668 function checkProgid(scanner) {
9669 var offset = 0;
9670
9671 for (var type; type = scanner.lookupType(offset); offset++) {
9672 if (type !== WHITESPACE$8 && type !== COMMENT$8) {
9673 break;
9674 }
9675 }
9676
9677 if (scanner.lookupValue(offset, 'alpha(') ||
9678 scanner.lookupValue(offset, 'chroma(') ||
9679 scanner.lookupValue(offset, 'dropshadow(')) {
9680 if (scanner.lookupType(offset) !== FUNCTION$6) {
9681 return false;
9682 }
9683 } else {
9684 if (scanner.lookupValue(offset, 'progid') === false ||
9685 scanner.lookupType(offset + 1) !== COLON$7) {
9686 return false;
9687 }
9688 }
9689
9690 return true;
9691 }
9692
9693 var Value = {
9694 name: 'Value',
9695 structure: {
9696 children: [[]]
9697 },
9698 parse: function(property) {
9699 // special parser for filter property since it can contains non-standart syntax for old IE
9700 if (property !== null && endsWith$1(property, 'filter') && checkProgid(this.scanner)) {
9701 this.scanner.skipSC();
9702 return this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$4, SEMICOLON$6, false, false);
9703 }
9704
9705 var start = this.scanner.tokenStart;
9706 var children = this.readSequence(this.scope.Value);
9707
9708 return {
9709 type: 'Value',
9710 loc: this.getLocation(start, this.scanner.tokenStart),
9711 children: children
9712 };
9713 },
9714 generate: function(processChunk, node) {
9715 this.each(processChunk, node);
9716 }
9717 };
9718
9719 var WHITESPACE$9 = tokenizer$1.TYPE.WhiteSpace;
9720 var SPACE$2 = Object.freeze({
9721 type: 'WhiteSpace',
9722 loc: null,
9723 value: ' '
9724 });
9725
9726 var WhiteSpace = {
9727 name: 'WhiteSpace',
9728 structure: {
9729 value: String
9730 },
9731 parse: function() {
9732 this.scanner.eat(WHITESPACE$9);
9733 return SPACE$2;
9734
9735 // return {
9736 // type: 'WhiteSpace',
9737 // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
9738 // value: this.scanner.consume(WHITESPACE)
9739 // };
9740 },
9741 generate: function(processChunk, node) {
9742 processChunk(node.value);
9743 }
9744 };
9745
9746 var node = {
9747 AnPlusB: AnPlusB,
9748 Atrule: Atrule,
9749 AtruleExpression: AtruleExpression,
9750 AttributeSelector: AttributeSelector,
9751 Block: Block,
9752 Brackets: Brackets,
9753 CDC: CDC_1,
9754 CDO: CDO_1,
9755 ClassSelector: ClassSelector,
9756 Combinator: Combinator,
9757 Comment: Comment,
9758 Declaration: Declaration,
9759 DeclarationList: DeclarationList,
9760 Dimension: Dimension,
9761 Function: _Function,
9762 HexColor: HexColor,
9763 Identifier: Identifier,
9764 IdSelector: IdSelector,
9765 MediaFeature: MediaFeature,
9766 MediaQuery: MediaQuery,
9767 MediaQueryList: MediaQueryList,
9768 Nth: Nth,
9769 Number: _Number,
9770 Operator: Operator,
9771 Parentheses: Parentheses,
9772 Percentage: Percentage,
9773 PseudoClassSelector: PseudoClassSelector,
9774 PseudoElementSelector: PseudoElementSelector,
9775 Ratio: Ratio,
9776 Raw: Raw,
9777 Rule: Rule,
9778 Selector: Selector,
9779 SelectorList: SelectorList,
9780 String: _String,
9781 StyleSheet: StyleSheet,
9782 TypeSelector: TypeSelector,
9783 UnicodeRange: UnicodeRange,
9784 Url: Url,
9785 Value: Value,
9786 WhiteSpace: WhiteSpace
9787 };
9788
9789 var parser = {
9790 parseContext: {
9791 default: 'StyleSheet',
9792 stylesheet: 'StyleSheet',
9793 atrule: 'Atrule',
9794 atruleExpression: function(options) {
9795 return this.AtruleExpression(options.atrule ? String(options.atrule) : null);
9796 },
9797 mediaQueryList: 'MediaQueryList',
9798 mediaQuery: 'MediaQuery',
9799 rule: 'Rule',
9800 selectorList: 'SelectorList',
9801 selector: 'Selector',
9802 block: function() {
9803 return this.Block(this.Declaration);
9804 },
9805 declarationList: 'DeclarationList',
9806 declaration: 'Declaration',
9807 value: function(options) {
9808 return this.Value(options.property ? String(options.property) : null);
9809 }
9810 },
9811 scope: scope,
9812 atrule: atrule,
9813 pseudo: pseudo,
9814 node: node
9815 };
9816
9817 var parser$1 = create(parser);
9818
9819 function walk(ast, { enter, leave }) {
9820 visit(ast, null, enter, leave);
9821 }
9822
9823 let shouldSkip = false;
9824 const context = { skip: () => shouldSkip = true };
9825
9826 const childKeys = {};
9827
9828 const toString$1 = Object.prototype.toString;
9829
9830 function isArray$1(thing) {
9831 return toString$1.call(thing) === '[object Array]';
9832 }
9833
9834 function visit(node, parent, enter, leave, prop, index) {
9835 if (!node) return;
9836
9837 if (enter) {
9838 const _shouldSkip = shouldSkip;
9839 shouldSkip = false;
9840 enter.call(context, node, parent, prop, index);
9841 const skipped = shouldSkip;
9842 shouldSkip = _shouldSkip;
9843
9844 if (skipped) return;
9845 }
9846
9847 const keys = node.type && childKeys[node.type] || (
9848 childKeys[node.type] = Object.keys(node).filter(key => typeof node[key] === 'object')
9849 );
9850
9851 for (let i = 0; i < keys.length; i += 1) {
9852 const key = keys[i];
9853 const value = node[key];
9854
9855 if (isArray$1(value)) {
9856 for (let j = 0; j < value.length; j += 1) {
9857 value[j] && value[j].type && visit(value[j], node, enter, leave, key, j);
9858 }
9859 }
9860
9861 else if (value && value.type) {
9862 visit(value, node, enter, leave, key, null);
9863 }
9864 }
9865
9866 if (leave) {
9867 leave(node, parent, prop, index);
9868 }
9869 }
9870
9871 function read_style(parser, start, attributes) {
9872 const content_start = parser.index;
9873 const styles = parser.read_until(/<\/style>/);
9874 const content_end = parser.index;
9875 let ast;
9876 try {
9877 ast = parser$1(styles, {
9878 positions: true,
9879 offset: content_start,
9880 });
9881 }
9882 catch (err) {
9883 if (err.name === 'CssSyntaxError') {
9884 parser.error({
9885 code: `css-syntax-error`,
9886 message: err.message
9887 }, err.offset);
9888 }
9889 else {
9890 throw err;
9891 }
9892 }
9893 ast = JSON.parse(JSON.stringify(ast));
9894 // tidy up AST
9895 walk(ast, {
9896 enter: (node) => {
9897 // replace `ref:a` nodes
9898 if (node.type === 'Selector') {
9899 for (let i = 0; i < node.children.length; i += 1) {
9900 const a = node.children[i];
9901 const b = node.children[i + 1];
9902 if (is_ref_selector(a, b)) {
9903 parser.error({
9904 code: `invalid-ref-selector`,
9905 message: 'ref selectors are no longer supported'
9906 }, a.loc.start.offset);
9907 }
9908 }
9909 }
9910 if (node.loc) {
9911 node.start = node.loc.start.offset;
9912 node.end = node.loc.end.offset;
9913 delete node.loc;
9914 }
9915 }
9916 });
9917 parser.eat('</style>', true);
9918 const end = parser.index;
9919 return {
9920 start,
9921 end,
9922 attributes,
9923 children: ast.children,
9924 content: {
9925 start: content_start,
9926 end: content_end,
9927 styles,
9928 },
9929 };
9930 }
9931 function is_ref_selector(a, b) {
9932 if (!b)
9933 return false;
9934 return (a.type === 'TypeSelector' &&
9935 a.name === 'ref' &&
9936 b.type === 'PseudoClassSelector');
9937 }
9938
9939 // https://dev.w3.org/html5/html-author/charref
9940 var entities = {
9941 CounterClockwiseContourIntegral: 8755,
9942 ClockwiseContourIntegral: 8754,
9943 DoubleLongLeftRightArrow: 10234,
9944 DiacriticalDoubleAcute: 733,
9945 NotSquareSupersetEqual: 8931,
9946 CloseCurlyDoubleQuote: 8221,
9947 DoubleContourIntegral: 8751,
9948 FilledVerySmallSquare: 9642,
9949 NegativeVeryThinSpace: 8203,
9950 NotPrecedesSlantEqual: 8928,
9951 NotRightTriangleEqual: 8941,
9952 NotSucceedsSlantEqual: 8929,
9953 CapitalDifferentialD: 8517,
9954 DoubleLeftRightArrow: 8660,
9955 DoubleLongRightArrow: 10233,
9956 EmptyVerySmallSquare: 9643,
9957 NestedGreaterGreater: 8811,
9958 NotDoubleVerticalBar: 8742,
9959 NotLeftTriangleEqual: 8940,
9960 NotSquareSubsetEqual: 8930,
9961 OpenCurlyDoubleQuote: 8220,
9962 ReverseUpEquilibrium: 10607,
9963 DoubleLongLeftArrow: 10232,
9964 DownLeftRightVector: 10576,
9965 LeftArrowRightArrow: 8646,
9966 NegativeMediumSpace: 8203,
9967 RightArrowLeftArrow: 8644,
9968 SquareSupersetEqual: 8850,
9969 leftrightsquigarrow: 8621,
9970 DownRightTeeVector: 10591,
9971 DownRightVectorBar: 10583,
9972 LongLeftRightArrow: 10231,
9973 Longleftrightarrow: 10234,
9974 NegativeThickSpace: 8203,
9975 PrecedesSlantEqual: 8828,
9976 ReverseEquilibrium: 8651,
9977 RightDoubleBracket: 10215,
9978 RightDownTeeVector: 10589,
9979 RightDownVectorBar: 10581,
9980 RightTriangleEqual: 8885,
9981 SquareIntersection: 8851,
9982 SucceedsSlantEqual: 8829,
9983 blacktriangleright: 9656,
9984 longleftrightarrow: 10231,
9985 DoubleUpDownArrow: 8661,
9986 DoubleVerticalBar: 8741,
9987 DownLeftTeeVector: 10590,
9988 DownLeftVectorBar: 10582,
9989 FilledSmallSquare: 9724,
9990 GreaterSlantEqual: 10878,
9991 LeftDoubleBracket: 10214,
9992 LeftDownTeeVector: 10593,
9993 LeftDownVectorBar: 10585,
9994 LeftTriangleEqual: 8884,
9995 NegativeThinSpace: 8203,
9996 NotReverseElement: 8716,
9997 NotTildeFullEqual: 8775,
9998 RightAngleBracket: 10217,
9999 RightUpDownVector: 10575,
10000 SquareSubsetEqual: 8849,
10001 VerticalSeparator: 10072,
10002 blacktriangledown: 9662,
10003 blacktriangleleft: 9666,
10004 leftrightharpoons: 8651,
10005 rightleftharpoons: 8652,
10006 twoheadrightarrow: 8608,
10007 DiacriticalAcute: 180,
10008 DiacriticalGrave: 96,
10009 DiacriticalTilde: 732,
10010 DoubleRightArrow: 8658,
10011 DownArrowUpArrow: 8693,
10012 EmptySmallSquare: 9723,
10013 GreaterEqualLess: 8923,
10014 GreaterFullEqual: 8807,
10015 LeftAngleBracket: 10216,
10016 LeftUpDownVector: 10577,
10017 LessEqualGreater: 8922,
10018 NonBreakingSpace: 160,
10019 NotRightTriangle: 8939,
10020 NotSupersetEqual: 8841,
10021 RightTriangleBar: 10704,
10022 RightUpTeeVector: 10588,
10023 RightUpVectorBar: 10580,
10024 UnderParenthesis: 9181,
10025 UpArrowDownArrow: 8645,
10026 circlearrowright: 8635,
10027 downharpoonright: 8642,
10028 ntrianglerighteq: 8941,
10029 rightharpoondown: 8641,
10030 rightrightarrows: 8649,
10031 twoheadleftarrow: 8606,
10032 vartriangleright: 8883,
10033 CloseCurlyQuote: 8217,
10034 ContourIntegral: 8750,
10035 DoubleDownArrow: 8659,
10036 DoubleLeftArrow: 8656,
10037 DownRightVector: 8641,
10038 LeftRightVector: 10574,
10039 LeftTriangleBar: 10703,
10040 LeftUpTeeVector: 10592,
10041 LeftUpVectorBar: 10584,
10042 LowerRightArrow: 8600,
10043 NotGreaterEqual: 8817,
10044 NotGreaterTilde: 8821,
10045 NotLeftTriangle: 8938,
10046 OverParenthesis: 9180,
10047 RightDownVector: 8642,
10048 ShortRightArrow: 8594,
10049 UpperRightArrow: 8599,
10050 bigtriangledown: 9661,
10051 circlearrowleft: 8634,
10052 curvearrowright: 8631,
10053 downharpoonleft: 8643,
10054 leftharpoondown: 8637,
10055 leftrightarrows: 8646,
10056 nLeftrightarrow: 8654,
10057 nleftrightarrow: 8622,
10058 ntrianglelefteq: 8940,
10059 rightleftarrows: 8644,
10060 rightsquigarrow: 8605,
10061 rightthreetimes: 8908,
10062 straightepsilon: 1013,
10063 trianglerighteq: 8885,
10064 vartriangleleft: 8882,
10065 DiacriticalDot: 729,
10066 DoubleRightTee: 8872,
10067 DownLeftVector: 8637,
10068 GreaterGreater: 10914,
10069 HorizontalLine: 9472,
10070 InvisibleComma: 8291,
10071 InvisibleTimes: 8290,
10072 LeftDownVector: 8643,
10073 LeftRightArrow: 8596,
10074 Leftrightarrow: 8660,
10075 LessSlantEqual: 10877,
10076 LongRightArrow: 10230,
10077 Longrightarrow: 10233,
10078 LowerLeftArrow: 8601,
10079 NestedLessLess: 8810,
10080 NotGreaterLess: 8825,
10081 NotLessGreater: 8824,
10082 NotSubsetEqual: 8840,
10083 NotVerticalBar: 8740,
10084 OpenCurlyQuote: 8216,
10085 ReverseElement: 8715,
10086 RightTeeVector: 10587,
10087 RightVectorBar: 10579,
10088 ShortDownArrow: 8595,
10089 ShortLeftArrow: 8592,
10090 SquareSuperset: 8848,
10091 TildeFullEqual: 8773,
10092 UpperLeftArrow: 8598,
10093 ZeroWidthSpace: 8203,
10094 curvearrowleft: 8630,
10095 doublebarwedge: 8966,
10096 downdownarrows: 8650,
10097 hookrightarrow: 8618,
10098 leftleftarrows: 8647,
10099 leftrightarrow: 8596,
10100 leftthreetimes: 8907,
10101 longrightarrow: 10230,
10102 looparrowright: 8620,
10103 nshortparallel: 8742,
10104 ntriangleright: 8939,
10105 rightarrowtail: 8611,
10106 rightharpoonup: 8640,
10107 trianglelefteq: 8884,
10108 upharpoonright: 8638,
10109 ApplyFunction: 8289,
10110 DifferentialD: 8518,
10111 DoubleLeftTee: 10980,
10112 DoubleUpArrow: 8657,
10113 LeftTeeVector: 10586,
10114 LeftVectorBar: 10578,
10115 LessFullEqual: 8806,
10116 LongLeftArrow: 10229,
10117 Longleftarrow: 10232,
10118 NotTildeEqual: 8772,
10119 NotTildeTilde: 8777,
10120 Poincareplane: 8460,
10121 PrecedesEqual: 10927,
10122 PrecedesTilde: 8830,
10123 RightArrowBar: 8677,
10124 RightTeeArrow: 8614,
10125 RightTriangle: 8883,
10126 RightUpVector: 8638,
10127 SucceedsEqual: 10928,
10128 SucceedsTilde: 8831,
10129 SupersetEqual: 8839,
10130 UpEquilibrium: 10606,
10131 VerticalTilde: 8768,
10132 VeryThinSpace: 8202,
10133 bigtriangleup: 9651,
10134 blacktriangle: 9652,
10135 divideontimes: 8903,
10136 fallingdotseq: 8786,
10137 hookleftarrow: 8617,
10138 leftarrowtail: 8610,
10139 leftharpoonup: 8636,
10140 longleftarrow: 10229,
10141 looparrowleft: 8619,
10142 measuredangle: 8737,
10143 ntriangleleft: 8938,
10144 shortparallel: 8741,
10145 smallsetminus: 8726,
10146 triangleright: 9657,
10147 upharpoonleft: 8639,
10148 DownArrowBar: 10515,
10149 DownTeeArrow: 8615,
10150 ExponentialE: 8519,
10151 GreaterEqual: 8805,
10152 GreaterTilde: 8819,
10153 HilbertSpace: 8459,
10154 HumpDownHump: 8782,
10155 Intersection: 8898,
10156 LeftArrowBar: 8676,
10157 LeftTeeArrow: 8612,
10158 LeftTriangle: 8882,
10159 LeftUpVector: 8639,
10160 NotCongruent: 8802,
10161 NotLessEqual: 8816,
10162 NotLessTilde: 8820,
10163 Proportional: 8733,
10164 RightCeiling: 8969,
10165 RoundImplies: 10608,
10166 ShortUpArrow: 8593,
10167 SquareSubset: 8847,
10168 UnderBracket: 9141,
10169 VerticalLine: 124,
10170 blacklozenge: 10731,
10171 exponentiale: 8519,
10172 risingdotseq: 8787,
10173 triangledown: 9663,
10174 triangleleft: 9667,
10175 CircleMinus: 8854,
10176 CircleTimes: 8855,
10177 Equilibrium: 8652,
10178 GreaterLess: 8823,
10179 LeftCeiling: 8968,
10180 LessGreater: 8822,
10181 MediumSpace: 8287,
10182 NotPrecedes: 8832,
10183 NotSucceeds: 8833,
10184 OverBracket: 9140,
10185 RightVector: 8640,
10186 Rrightarrow: 8667,
10187 RuleDelayed: 10740,
10188 SmallCircle: 8728,
10189 SquareUnion: 8852,
10190 SubsetEqual: 8838,
10191 UpDownArrow: 8597,
10192 Updownarrow: 8661,
10193 VerticalBar: 8739,
10194 backepsilon: 1014,
10195 blacksquare: 9642,
10196 circledcirc: 8858,
10197 circleddash: 8861,
10198 curlyeqprec: 8926,
10199 curlyeqsucc: 8927,
10200 diamondsuit: 9830,
10201 eqslantless: 10901,
10202 expectation: 8496,
10203 nRightarrow: 8655,
10204 nrightarrow: 8603,
10205 preccurlyeq: 8828,
10206 precnapprox: 10937,
10207 quaternions: 8461,
10208 straightphi: 981,
10209 succcurlyeq: 8829,
10210 succnapprox: 10938,
10211 thickapprox: 8776,
10212 updownarrow: 8597,
10213 Bernoullis: 8492,
10214 CirclePlus: 8853,
10215 EqualTilde: 8770,
10216 Fouriertrf: 8497,
10217 ImaginaryI: 8520,
10218 Laplacetrf: 8466,
10219 LeftVector: 8636,
10220 Lleftarrow: 8666,
10221 NotElement: 8713,
10222 NotGreater: 8815,
10223 Proportion: 8759,
10224 RightArrow: 8594,
10225 RightFloor: 8971,
10226 Rightarrow: 8658,
10227 TildeEqual: 8771,
10228 TildeTilde: 8776,
10229 UnderBrace: 9183,
10230 UpArrowBar: 10514,
10231 UpTeeArrow: 8613,
10232 circledast: 8859,
10233 complement: 8705,
10234 curlywedge: 8911,
10235 eqslantgtr: 10902,
10236 gtreqqless: 10892,
10237 lessapprox: 10885,
10238 lesseqqgtr: 10891,
10239 lmoustache: 9136,
10240 longmapsto: 10236,
10241 mapstodown: 8615,
10242 mapstoleft: 8612,
10243 nLeftarrow: 8653,
10244 nleftarrow: 8602,
10245 precapprox: 10935,
10246 rightarrow: 8594,
10247 rmoustache: 9137,
10248 sqsubseteq: 8849,
10249 sqsupseteq: 8850,
10250 subsetneqq: 10955,
10251 succapprox: 10936,
10252 supsetneqq: 10956,
10253 upuparrows: 8648,
10254 varepsilon: 949,
10255 varnothing: 8709,
10256 Backslash: 8726,
10257 CenterDot: 183,
10258 CircleDot: 8857,
10259 Congruent: 8801,
10260 Coproduct: 8720,
10261 DoubleDot: 168,
10262 DownArrow: 8595,
10263 DownBreve: 785,
10264 Downarrow: 8659,
10265 HumpEqual: 8783,
10266 LeftArrow: 8592,
10267 LeftFloor: 8970,
10268 Leftarrow: 8656,
10269 LessTilde: 8818,
10270 Mellintrf: 8499,
10271 MinusPlus: 8723,
10272 NotCupCap: 8813,
10273 NotExists: 8708,
10274 OverBrace: 9182,
10275 PlusMinus: 177,
10276 Therefore: 8756,
10277 ThinSpace: 8201,
10278 TripleDot: 8411,
10279 UnionPlus: 8846,
10280 backprime: 8245,
10281 backsimeq: 8909,
10282 bigotimes: 10754,
10283 centerdot: 183,
10284 checkmark: 10003,
10285 complexes: 8450,
10286 dotsquare: 8865,
10287 downarrow: 8595,
10288 gtrapprox: 10886,
10289 gtreqless: 8923,
10290 heartsuit: 9829,
10291 leftarrow: 8592,
10292 lesseqgtr: 8922,
10293 nparallel: 8742,
10294 nshortmid: 8740,
10295 nsubseteq: 8840,
10296 nsupseteq: 8841,
10297 pitchfork: 8916,
10298 rationals: 8474,
10299 spadesuit: 9824,
10300 subseteqq: 10949,
10301 subsetneq: 8842,
10302 supseteqq: 10950,
10303 supsetneq: 8843,
10304 therefore: 8756,
10305 triangleq: 8796,
10306 varpropto: 8733,
10307 DDotrahd: 10513,
10308 DotEqual: 8784,
10309 Integral: 8747,
10310 LessLess: 10913,
10311 NotEqual: 8800,
10312 NotTilde: 8769,
10313 PartialD: 8706,
10314 Precedes: 8826,
10315 RightTee: 8866,
10316 Succeeds: 8827,
10317 SuchThat: 8715,
10318 Superset: 8835,
10319 Uarrocir: 10569,
10320 UnderBar: 818,
10321 andslope: 10840,
10322 angmsdaa: 10664,
10323 angmsdab: 10665,
10324 angmsdac: 10666,
10325 angmsdad: 10667,
10326 angmsdae: 10668,
10327 angmsdaf: 10669,
10328 angmsdag: 10670,
10329 angmsdah: 10671,
10330 angrtvbd: 10653,
10331 approxeq: 8778,
10332 awconint: 8755,
10333 backcong: 8780,
10334 barwedge: 8965,
10335 bbrktbrk: 9142,
10336 bigoplus: 10753,
10337 bigsqcup: 10758,
10338 biguplus: 10756,
10339 bigwedge: 8896,
10340 boxminus: 8863,
10341 boxtimes: 8864,
10342 capbrcup: 10825,
10343 circledR: 174,
10344 circledS: 9416,
10345 cirfnint: 10768,
10346 clubsuit: 9827,
10347 cupbrcap: 10824,
10348 curlyvee: 8910,
10349 cwconint: 8754,
10350 doteqdot: 8785,
10351 dotminus: 8760,
10352 drbkarow: 10512,
10353 dzigrarr: 10239,
10354 elinters: 9191,
10355 emptyset: 8709,
10356 eqvparsl: 10725,
10357 fpartint: 10765,
10358 geqslant: 10878,
10359 gesdotol: 10884,
10360 gnapprox: 10890,
10361 hksearow: 10533,
10362 hkswarow: 10534,
10363 imagline: 8464,
10364 imagpart: 8465,
10365 infintie: 10717,
10366 integers: 8484,
10367 intercal: 8890,
10368 intlarhk: 10775,
10369 laemptyv: 10676,
10370 ldrushar: 10571,
10371 leqslant: 10877,
10372 lesdotor: 10883,
10373 llcorner: 8990,
10374 lnapprox: 10889,
10375 lrcorner: 8991,
10376 lurdshar: 10570,
10377 mapstoup: 8613,
10378 multimap: 8888,
10379 naturals: 8469,
10380 otimesas: 10806,
10381 parallel: 8741,
10382 plusacir: 10787,
10383 pointint: 10773,
10384 precneqq: 10933,
10385 precnsim: 8936,
10386 profalar: 9006,
10387 profline: 8978,
10388 profsurf: 8979,
10389 raemptyv: 10675,
10390 realpart: 8476,
10391 rppolint: 10770,
10392 rtriltri: 10702,
10393 scpolint: 10771,
10394 setminus: 8726,
10395 shortmid: 8739,
10396 smeparsl: 10724,
10397 sqsubset: 8847,
10398 sqsupset: 8848,
10399 subseteq: 8838,
10400 succneqq: 10934,
10401 succnsim: 8937,
10402 supseteq: 8839,
10403 thetasym: 977,
10404 thicksim: 8764,
10405 timesbar: 10801,
10406 triangle: 9653,
10407 triminus: 10810,
10408 trpezium: 9186,
10409 ulcorner: 8988,
10410 urcorner: 8989,
10411 varkappa: 1008,
10412 varsigma: 962,
10413 vartheta: 977,
10414 Because: 8757,
10415 Cayleys: 8493,
10416 Cconint: 8752,
10417 Cedilla: 184,
10418 Diamond: 8900,
10419 DownTee: 8868,
10420 Element: 8712,
10421 Epsilon: 917,
10422 Implies: 8658,
10423 LeftTee: 8867,
10424 NewLine: 10,
10425 NoBreak: 8288,
10426 NotLess: 8814,
10427 Omicron: 927,
10428 OverBar: 175,
10429 Product: 8719,
10430 UpArrow: 8593,
10431 Uparrow: 8657,
10432 Upsilon: 933,
10433 alefsym: 8501,
10434 angrtvb: 8894,
10435 angzarr: 9084,
10436 asympeq: 8781,
10437 backsim: 8765,
10438 because: 8757,
10439 bemptyv: 10672,
10440 between: 8812,
10441 bigcirc: 9711,
10442 bigodot: 10752,
10443 bigstar: 9733,
10444 boxplus: 8862,
10445 ccupssm: 10832,
10446 cemptyv: 10674,
10447 cirscir: 10690,
10448 coloneq: 8788,
10449 congdot: 10861,
10450 cudarrl: 10552,
10451 cudarrr: 10549,
10452 cularrp: 10557,
10453 curarrm: 10556,
10454 dbkarow: 10511,
10455 ddagger: 8225,
10456 ddotseq: 10871,
10457 demptyv: 10673,
10458 diamond: 8900,
10459 digamma: 989,
10460 dotplus: 8724,
10461 dwangle: 10662,
10462 epsilon: 949,
10463 eqcolon: 8789,
10464 equivDD: 10872,
10465 gesdoto: 10882,
10466 gtquest: 10876,
10467 gtrless: 8823,
10468 harrcir: 10568,
10469 intprod: 10812,
10470 isindot: 8949,
10471 larrbfs: 10527,
10472 larrsim: 10611,
10473 lbrksld: 10639,
10474 lbrkslu: 10637,
10475 ldrdhar: 10599,
10476 lesdoto: 10881,
10477 lessdot: 8918,
10478 lessgtr: 8822,
10479 lesssim: 8818,
10480 lotimes: 10804,
10481 lozenge: 9674,
10482 ltquest: 10875,
10483 luruhar: 10598,
10484 maltese: 10016,
10485 minusdu: 10794,
10486 napprox: 8777,
10487 natural: 9838,
10488 nearrow: 8599,
10489 nexists: 8708,
10490 notinva: 8713,
10491 notinvb: 8951,
10492 notinvc: 8950,
10493 notniva: 8716,
10494 notnivb: 8958,
10495 notnivc: 8957,
10496 npolint: 10772,
10497 nsqsube: 8930,
10498 nsqsupe: 8931,
10499 nvinfin: 10718,
10500 nwarrow: 8598,
10501 olcross: 10683,
10502 omicron: 959,
10503 orderof: 8500,
10504 orslope: 10839,
10505 pertenk: 8241,
10506 planckh: 8462,
10507 pluscir: 10786,
10508 plussim: 10790,
10509 plustwo: 10791,
10510 precsim: 8830,
10511 quatint: 10774,
10512 questeq: 8799,
10513 rarrbfs: 10528,
10514 rarrsim: 10612,
10515 rbrksld: 10638,
10516 rbrkslu: 10640,
10517 rdldhar: 10601,
10518 realine: 8475,
10519 rotimes: 10805,
10520 ruluhar: 10600,
10521 searrow: 8600,
10522 simplus: 10788,
10523 simrarr: 10610,
10524 subedot: 10947,
10525 submult: 10945,
10526 subplus: 10943,
10527 subrarr: 10617,
10528 succsim: 8831,
10529 supdsub: 10968,
10530 supedot: 10948,
10531 suphsub: 10967,
10532 suplarr: 10619,
10533 supmult: 10946,
10534 supplus: 10944,
10535 swarrow: 8601,
10536 topfork: 10970,
10537 triplus: 10809,
10538 tritime: 10811,
10539 uparrow: 8593,
10540 upsilon: 965,
10541 uwangle: 10663,
10542 vzigzag: 10650,
10543 zigrarr: 8669,
10544 Aacute: 193,
10545 Abreve: 258,
10546 Agrave: 192,
10547 Assign: 8788,
10548 Atilde: 195,
10549 Barwed: 8966,
10550 Bumpeq: 8782,
10551 Cacute: 262,
10552 Ccaron: 268,
10553 Ccedil: 199,
10554 Colone: 10868,
10555 Conint: 8751,
10556 CupCap: 8781,
10557 Dagger: 8225,
10558 Dcaron: 270,
10559 DotDot: 8412,
10560 Dstrok: 272,
10561 Eacute: 201,
10562 Ecaron: 282,
10563 Egrave: 200,
10564 Exists: 8707,
10565 ForAll: 8704,
10566 Gammad: 988,
10567 Gbreve: 286,
10568 Gcedil: 290,
10569 HARDcy: 1066,
10570 Hstrok: 294,
10571 Iacute: 205,
10572 Igrave: 204,
10573 Itilde: 296,
10574 Jsercy: 1032,
10575 Kcedil: 310,
10576 Lacute: 313,
10577 Lambda: 923,
10578 Lcaron: 317,
10579 Lcedil: 315,
10580 Lmidot: 319,
10581 Lstrok: 321,
10582 Nacute: 323,
10583 Ncaron: 327,
10584 Ncedil: 325,
10585 Ntilde: 209,
10586 Oacute: 211,
10587 Odblac: 336,
10588 Ograve: 210,
10589 Oslash: 216,
10590 Otilde: 213,
10591 Otimes: 10807,
10592 Racute: 340,
10593 Rarrtl: 10518,
10594 Rcaron: 344,
10595 Rcedil: 342,
10596 SHCHcy: 1065,
10597 SOFTcy: 1068,
10598 Sacute: 346,
10599 Scaron: 352,
10600 Scedil: 350,
10601 Square: 9633,
10602 Subset: 8912,
10603 Supset: 8913,
10604 Tcaron: 356,
10605 Tcedil: 354,
10606 Tstrok: 358,
10607 Uacute: 218,
10608 Ubreve: 364,
10609 Udblac: 368,
10610 Ugrave: 217,
10611 Utilde: 360,
10612 Vdashl: 10982,
10613 Verbar: 8214,
10614 Vvdash: 8874,
10615 Yacute: 221,
10616 Zacute: 377,
10617 Zcaron: 381,
10618 aacute: 225,
10619 abreve: 259,
10620 agrave: 224,
10621 andand: 10837,
10622 angmsd: 8737,
10623 angsph: 8738,
10624 apacir: 10863,
10625 approx: 8776,
10626 atilde: 227,
10627 barvee: 8893,
10628 barwed: 8965,
10629 becaus: 8757,
10630 bernou: 8492,
10631 bigcap: 8898,
10632 bigcup: 8899,
10633 bigvee: 8897,
10634 bkarow: 10509,
10635 bottom: 8869,
10636 bowtie: 8904,
10637 boxbox: 10697,
10638 bprime: 8245,
10639 brvbar: 166,
10640 bullet: 8226,
10641 bumpeq: 8783,
10642 cacute: 263,
10643 capand: 10820,
10644 capcap: 10827,
10645 capcup: 10823,
10646 capdot: 10816,
10647 ccaron: 269,
10648 ccedil: 231,
10649 circeq: 8791,
10650 cirmid: 10991,
10651 colone: 8788,
10652 commat: 64,
10653 compfn: 8728,
10654 conint: 8750,
10655 coprod: 8720,
10656 copysr: 8471,
10657 cularr: 8630,
10658 cupcap: 10822,
10659 cupcup: 10826,
10660 cupdot: 8845,
10661 curarr: 8631,
10662 curren: 164,
10663 cylcty: 9005,
10664 dagger: 8224,
10665 daleth: 8504,
10666 dcaron: 271,
10667 dfisht: 10623,
10668 divide: 247,
10669 divonx: 8903,
10670 dlcorn: 8990,
10671 dlcrop: 8973,
10672 dollar: 36,
10673 drcorn: 8991,
10674 drcrop: 8972,
10675 dstrok: 273,
10676 eacute: 233,
10677 easter: 10862,
10678 ecaron: 283,
10679 ecolon: 8789,
10680 egrave: 232,
10681 egsdot: 10904,
10682 elsdot: 10903,
10683 emptyv: 8709,
10684 emsp13: 8196,
10685 emsp14: 8197,
10686 eparsl: 10723,
10687 eqcirc: 8790,
10688 equals: 61,
10689 equest: 8799,
10690 female: 9792,
10691 ffilig: 64259,
10692 ffllig: 64260,
10693 forall: 8704,
10694 frac12: 189,
10695 frac13: 8531,
10696 frac14: 188,
10697 frac15: 8533,
10698 frac16: 8537,
10699 frac18: 8539,
10700 frac23: 8532,
10701 frac25: 8534,
10702 frac34: 190,
10703 frac35: 8535,
10704 frac38: 8540,
10705 frac45: 8536,
10706 frac56: 8538,
10707 frac58: 8541,
10708 frac78: 8542,
10709 gacute: 501,
10710 gammad: 989,
10711 gbreve: 287,
10712 gesdot: 10880,
10713 gesles: 10900,
10714 gtlPar: 10645,
10715 gtrarr: 10616,
10716 gtrdot: 8919,
10717 gtrsim: 8819,
10718 hairsp: 8202,
10719 hamilt: 8459,
10720 hardcy: 1098,
10721 hearts: 9829,
10722 hellip: 8230,
10723 hercon: 8889,
10724 homtht: 8763,
10725 horbar: 8213,
10726 hslash: 8463,
10727 hstrok: 295,
10728 hybull: 8259,
10729 hyphen: 8208,
10730 iacute: 237,
10731 igrave: 236,
10732 iiiint: 10764,
10733 iinfin: 10716,
10734 incare: 8453,
10735 inodot: 305,
10736 intcal: 8890,
10737 iquest: 191,
10738 isinsv: 8947,
10739 itilde: 297,
10740 jsercy: 1112,
10741 kappav: 1008,
10742 kcedil: 311,
10743 kgreen: 312,
10744 lAtail: 10523,
10745 lacute: 314,
10746 lagran: 8466,
10747 lambda: 955,
10748 langle: 10216,
10749 larrfs: 10525,
10750 larrhk: 8617,
10751 larrlp: 8619,
10752 larrpl: 10553,
10753 larrtl: 8610,
10754 latail: 10521,
10755 lbrace: 123,
10756 lbrack: 91,
10757 lcaron: 318,
10758 lcedil: 316,
10759 ldquor: 8222,
10760 lesdot: 10879,
10761 lesges: 10899,
10762 lfisht: 10620,
10763 lfloor: 8970,
10764 lharul: 10602,
10765 llhard: 10603,
10766 lmidot: 320,
10767 lmoust: 9136,
10768 loplus: 10797,
10769 lowast: 8727,
10770 lowbar: 95,
10771 lparlt: 10643,
10772 lrhard: 10605,
10773 lsaquo: 8249,
10774 lsquor: 8218,
10775 lstrok: 322,
10776 lthree: 8907,
10777 ltimes: 8905,
10778 ltlarr: 10614,
10779 ltrPar: 10646,
10780 mapsto: 8614,
10781 marker: 9646,
10782 mcomma: 10793,
10783 midast: 42,
10784 midcir: 10992,
10785 middot: 183,
10786 minusb: 8863,
10787 minusd: 8760,
10788 mnplus: 8723,
10789 models: 8871,
10790 mstpos: 8766,
10791 nVDash: 8879,
10792 nVdash: 8878,
10793 nacute: 324,
10794 ncaron: 328,
10795 ncedil: 326,
10796 nearhk: 10532,
10797 nequiv: 8802,
10798 nesear: 10536,
10799 nexist: 8708,
10800 nltrie: 8940,
10801 nprcue: 8928,
10802 nrtrie: 8941,
10803 nsccue: 8929,
10804 nsimeq: 8772,
10805 ntilde: 241,
10806 numero: 8470,
10807 nvDash: 8877,
10808 nvHarr: 10500,
10809 nvdash: 8876,
10810 nvlArr: 10498,
10811 nvrArr: 10499,
10812 nwarhk: 10531,
10813 nwnear: 10535,
10814 oacute: 243,
10815 odblac: 337,
10816 odsold: 10684,
10817 ograve: 242,
10818 ominus: 8854,
10819 origof: 8886,
10820 oslash: 248,
10821 otilde: 245,
10822 otimes: 8855,
10823 parsim: 10995,
10824 percnt: 37,
10825 period: 46,
10826 permil: 8240,
10827 phmmat: 8499,
10828 planck: 8463,
10829 plankv: 8463,
10830 plusdo: 8724,
10831 plusdu: 10789,
10832 plusmn: 177,
10833 preceq: 10927,
10834 primes: 8473,
10835 prnsim: 8936,
10836 propto: 8733,
10837 prurel: 8880,
10838 puncsp: 8200,
10839 qprime: 8279,
10840 rAtail: 10524,
10841 racute: 341,
10842 rangle: 10217,
10843 rarrap: 10613,
10844 rarrfs: 10526,
10845 rarrhk: 8618,
10846 rarrlp: 8620,
10847 rarrpl: 10565,
10848 rarrtl: 8611,
10849 ratail: 10522,
10850 rbrace: 125,
10851 rbrack: 93,
10852 rcaron: 345,
10853 rcedil: 343,
10854 rdquor: 8221,
10855 rfisht: 10621,
10856 rfloor: 8971,
10857 rharul: 10604,
10858 rmoust: 9137,
10859 roplus: 10798,
10860 rpargt: 10644,
10861 rsaquo: 8250,
10862 rsquor: 8217,
10863 rthree: 8908,
10864 rtimes: 8906,
10865 sacute: 347,
10866 scaron: 353,
10867 scedil: 351,
10868 scnsim: 8937,
10869 searhk: 10533,
10870 seswar: 10537,
10871 sfrown: 8994,
10872 shchcy: 1097,
10873 sigmaf: 962,
10874 sigmav: 962,
10875 simdot: 10858,
10876 smashp: 10803,
10877 softcy: 1100,
10878 solbar: 9023,
10879 spades: 9824,
10880 sqsube: 8849,
10881 sqsupe: 8850,
10882 square: 9633,
10883 squarf: 9642,
10884 ssetmn: 8726,
10885 ssmile: 8995,
10886 sstarf: 8902,
10887 subdot: 10941,
10888 subset: 8834,
10889 subsim: 10951,
10890 subsub: 10965,
10891 subsup: 10963,
10892 succeq: 10928,
10893 supdot: 10942,
10894 supset: 8835,
10895 supsim: 10952,
10896 supsub: 10964,
10897 supsup: 10966,
10898 swarhk: 10534,
10899 swnwar: 10538,
10900 target: 8982,
10901 tcaron: 357,
10902 tcedil: 355,
10903 telrec: 8981,
10904 there4: 8756,
10905 thetav: 977,
10906 thinsp: 8201,
10907 thksim: 8764,
10908 timesb: 8864,
10909 timesd: 10800,
10910 topbot: 9014,
10911 topcir: 10993,
10912 tprime: 8244,
10913 tridot: 9708,
10914 tstrok: 359,
10915 uacute: 250,
10916 ubreve: 365,
10917 udblac: 369,
10918 ufisht: 10622,
10919 ugrave: 249,
10920 ulcorn: 8988,
10921 ulcrop: 8975,
10922 urcorn: 8989,
10923 urcrop: 8974,
10924 utilde: 361,
10925 vangrt: 10652,
10926 varphi: 966,
10927 varrho: 1009,
10928 veebar: 8891,
10929 vellip: 8942,
10930 verbar: 124,
10931 wedbar: 10847,
10932 wedgeq: 8793,
10933 weierp: 8472,
10934 wreath: 8768,
10935 xoplus: 10753,
10936 xotime: 10754,
10937 xsqcup: 10758,
10938 xuplus: 10756,
10939 xwedge: 8896,
10940 yacute: 253,
10941 zacute: 378,
10942 zcaron: 382,
10943 zeetrf: 8488,
10944 AElig: 198,
10945 Acirc: 194,
10946 Alpha: 913,
10947 Amacr: 256,
10948 Aogon: 260,
10949 Aring: 197,
10950 Breve: 728,
10951 Ccirc: 264,
10952 Colon: 8759,
10953 Cross: 10799,
10954 Dashv: 10980,
10955 Delta: 916,
10956 Ecirc: 202,
10957 Emacr: 274,
10958 Eogon: 280,
10959 Equal: 10869,
10960 Gamma: 915,
10961 Gcirc: 284,
10962 Hacek: 711,
10963 Hcirc: 292,
10964 IJlig: 306,
10965 Icirc: 206,
10966 Imacr: 298,
10967 Iogon: 302,
10968 Iukcy: 1030,
10969 Jcirc: 308,
10970 Jukcy: 1028,
10971 Kappa: 922,
10972 OElig: 338,
10973 Ocirc: 212,
10974 Omacr: 332,
10975 Omega: 937,
10976 Prime: 8243,
10977 RBarr: 10512,
10978 Scirc: 348,
10979 Sigma: 931,
10980 THORN: 222,
10981 TRADE: 8482,
10982 TSHcy: 1035,
10983 Theta: 920,
10984 Tilde: 8764,
10985 Ubrcy: 1038,
10986 Ucirc: 219,
10987 Umacr: 362,
10988 Union: 8899,
10989 Uogon: 370,
10990 UpTee: 8869,
10991 Uring: 366,
10992 VDash: 8875,
10993 Vdash: 8873,
10994 Wcirc: 372,
10995 Wedge: 8896,
10996 Ycirc: 374,
10997 acirc: 226,
10998 acute: 180,
10999 aelig: 230,
11000 aleph: 8501,
11001 alpha: 945,
11002 amacr: 257,
11003 amalg: 10815,
11004 angle: 8736,
11005 angrt: 8735,
11006 angst: 8491,
11007 aogon: 261,
11008 aring: 229,
11009 asymp: 8776,
11010 awint: 10769,
11011 bcong: 8780,
11012 bdquo: 8222,
11013 bepsi: 1014,
11014 blank: 9251,
11015 blk12: 9618,
11016 blk14: 9617,
11017 blk34: 9619,
11018 block: 9608,
11019 boxDL: 9559,
11020 boxDR: 9556,
11021 boxDl: 9558,
11022 boxDr: 9555,
11023 boxHD: 9574,
11024 boxHU: 9577,
11025 boxHd: 9572,
11026 boxHu: 9575,
11027 boxUL: 9565,
11028 boxUR: 9562,
11029 boxUl: 9564,
11030 boxUr: 9561,
11031 boxVH: 9580,
11032 boxVL: 9571,
11033 boxVR: 9568,
11034 boxVh: 9579,
11035 boxVl: 9570,
11036 boxVr: 9567,
11037 boxdL: 9557,
11038 boxdR: 9554,
11039 boxdl: 9488,
11040 boxdr: 9484,
11041 boxhD: 9573,
11042 boxhU: 9576,
11043 boxhd: 9516,
11044 boxhu: 9524,
11045 boxuL: 9563,
11046 boxuR: 9560,
11047 boxul: 9496,
11048 boxur: 9492,
11049 boxvH: 9578,
11050 boxvL: 9569,
11051 boxvR: 9566,
11052 boxvh: 9532,
11053 boxvl: 9508,
11054 boxvr: 9500,
11055 breve: 728,
11056 bsemi: 8271,
11057 bsime: 8909,
11058 bsolb: 10693,
11059 bumpE: 10926,
11060 bumpe: 8783,
11061 caret: 8257,
11062 caron: 711,
11063 ccaps: 10829,
11064 ccirc: 265,
11065 ccups: 10828,
11066 cedil: 184,
11067 check: 10003,
11068 clubs: 9827,
11069 colon: 58,
11070 comma: 44,
11071 crarr: 8629,
11072 cross: 10007,
11073 csube: 10961,
11074 csupe: 10962,
11075 ctdot: 8943,
11076 cuepr: 8926,
11077 cuesc: 8927,
11078 cupor: 10821,
11079 cuvee: 8910,
11080 cuwed: 8911,
11081 cwint: 8753,
11082 dashv: 8867,
11083 dblac: 733,
11084 ddarr: 8650,
11085 delta: 948,
11086 dharl: 8643,
11087 dharr: 8642,
11088 diams: 9830,
11089 disin: 8946,
11090 doteq: 8784,
11091 dtdot: 8945,
11092 dtrif: 9662,
11093 duarr: 8693,
11094 duhar: 10607,
11095 eDDot: 10871,
11096 ecirc: 234,
11097 efDot: 8786,
11098 emacr: 275,
11099 empty: 8709,
11100 eogon: 281,
11101 eplus: 10865,
11102 epsiv: 949,
11103 eqsim: 8770,
11104 equiv: 8801,
11105 erDot: 8787,
11106 erarr: 10609,
11107 esdot: 8784,
11108 exist: 8707,
11109 fflig: 64256,
11110 filig: 64257,
11111 fllig: 64258,
11112 fltns: 9649,
11113 forkv: 10969,
11114 frasl: 8260,
11115 frown: 8994,
11116 gamma: 947,
11117 gcirc: 285,
11118 gescc: 10921,
11119 gimel: 8503,
11120 gneqq: 8809,
11121 gnsim: 8935,
11122 grave: 96,
11123 gsime: 10894,
11124 gsiml: 10896,
11125 gtcir: 10874,
11126 gtdot: 8919,
11127 harrw: 8621,
11128 hcirc: 293,
11129 hoarr: 8703,
11130 icirc: 238,
11131 iexcl: 161,
11132 iiint: 8749,
11133 iiota: 8489,
11134 ijlig: 307,
11135 imacr: 299,
11136 image: 8465,
11137 imath: 305,
11138 imped: 437,
11139 infin: 8734,
11140 iogon: 303,
11141 iprod: 10812,
11142 isinE: 8953,
11143 isins: 8948,
11144 isinv: 8712,
11145 iukcy: 1110,
11146 jcirc: 309,
11147 jmath: 567,
11148 jukcy: 1108,
11149 kappa: 954,
11150 lAarr: 8666,
11151 lBarr: 10510,
11152 langd: 10641,
11153 laquo: 171,
11154 larrb: 8676,
11155 lbarr: 10508,
11156 lbbrk: 10098,
11157 lbrke: 10635,
11158 lceil: 8968,
11159 ldquo: 8220,
11160 lescc: 10920,
11161 lhard: 8637,
11162 lharu: 8636,
11163 lhblk: 9604,
11164 llarr: 8647,
11165 lltri: 9722,
11166 lneqq: 8808,
11167 lnsim: 8934,
11168 loang: 10220,
11169 loarr: 8701,
11170 lobrk: 10214,
11171 lopar: 10629,
11172 lrarr: 8646,
11173 lrhar: 8651,
11174 lrtri: 8895,
11175 lsime: 10893,
11176 lsimg: 10895,
11177 lsquo: 8216,
11178 ltcir: 10873,
11179 ltdot: 8918,
11180 ltrie: 8884,
11181 ltrif: 9666,
11182 mDDot: 8762,
11183 mdash: 8212,
11184 micro: 181,
11185 minus: 8722,
11186 mumap: 8888,
11187 nabla: 8711,
11188 napos: 329,
11189 natur: 9838,
11190 ncong: 8775,
11191 ndash: 8211,
11192 neArr: 8663,
11193 nearr: 8599,
11194 ngsim: 8821,
11195 nhArr: 8654,
11196 nharr: 8622,
11197 nhpar: 10994,
11198 nlArr: 8653,
11199 nlarr: 8602,
11200 nless: 8814,
11201 nlsim: 8820,
11202 nltri: 8938,
11203 notin: 8713,
11204 notni: 8716,
11205 nprec: 8832,
11206 nrArr: 8655,
11207 nrarr: 8603,
11208 nrtri: 8939,
11209 nsime: 8772,
11210 nsmid: 8740,
11211 nspar: 8742,
11212 nsube: 8840,
11213 nsucc: 8833,
11214 nsupe: 8841,
11215 numsp: 8199,
11216 nwArr: 8662,
11217 nwarr: 8598,
11218 ocirc: 244,
11219 odash: 8861,
11220 oelig: 339,
11221 ofcir: 10687,
11222 ohbar: 10677,
11223 olarr: 8634,
11224 olcir: 10686,
11225 oline: 8254,
11226 omacr: 333,
11227 omega: 969,
11228 operp: 10681,
11229 oplus: 8853,
11230 orarr: 8635,
11231 order: 8500,
11232 ovbar: 9021,
11233 parsl: 11005,
11234 phone: 9742,
11235 plusb: 8862,
11236 pluse: 10866,
11237 pound: 163,
11238 prcue: 8828,
11239 prime: 8242,
11240 prnap: 10937,
11241 prsim: 8830,
11242 quest: 63,
11243 rAarr: 8667,
11244 rBarr: 10511,
11245 radic: 8730,
11246 rangd: 10642,
11247 range: 10661,
11248 raquo: 187,
11249 rarrb: 8677,
11250 rarrc: 10547,
11251 rarrw: 8605,
11252 ratio: 8758,
11253 rbarr: 10509,
11254 rbbrk: 10099,
11255 rbrke: 10636,
11256 rceil: 8969,
11257 rdquo: 8221,
11258 reals: 8477,
11259 rhard: 8641,
11260 rharu: 8640,
11261 rlarr: 8644,
11262 rlhar: 8652,
11263 rnmid: 10990,
11264 roang: 10221,
11265 roarr: 8702,
11266 robrk: 10215,
11267 ropar: 10630,
11268 rrarr: 8649,
11269 rsquo: 8217,
11270 rtrie: 8885,
11271 rtrif: 9656,
11272 sbquo: 8218,
11273 sccue: 8829,
11274 scirc: 349,
11275 scnap: 10938,
11276 scsim: 8831,
11277 sdotb: 8865,
11278 sdote: 10854,
11279 seArr: 8664,
11280 searr: 8600,
11281 setmn: 8726,
11282 sharp: 9839,
11283 sigma: 963,
11284 simeq: 8771,
11285 simgE: 10912,
11286 simlE: 10911,
11287 simne: 8774,
11288 slarr: 8592,
11289 smile: 8995,
11290 sqcap: 8851,
11291 sqcup: 8852,
11292 sqsub: 8847,
11293 sqsup: 8848,
11294 srarr: 8594,
11295 starf: 9733,
11296 strns: 175,
11297 subnE: 10955,
11298 subne: 8842,
11299 supnE: 10956,
11300 supne: 8843,
11301 swArr: 8665,
11302 swarr: 8601,
11303 szlig: 223,
11304 theta: 952,
11305 thkap: 8776,
11306 thorn: 254,
11307 tilde: 732,
11308 times: 215,
11309 trade: 8482,
11310 trisb: 10701,
11311 tshcy: 1115,
11312 twixt: 8812,
11313 ubrcy: 1118,
11314 ucirc: 251,
11315 udarr: 8645,
11316 udhar: 10606,
11317 uharl: 8639,
11318 uharr: 8638,
11319 uhblk: 9600,
11320 ultri: 9720,
11321 umacr: 363,
11322 uogon: 371,
11323 uplus: 8846,
11324 upsih: 978,
11325 uring: 367,
11326 urtri: 9721,
11327 utdot: 8944,
11328 utrif: 9652,
11329 uuarr: 8648,
11330 vBarv: 10985,
11331 vDash: 8872,
11332 varpi: 982,
11333 vdash: 8866,
11334 veeeq: 8794,
11335 vltri: 8882,
11336 vprop: 8733,
11337 vrtri: 8883,
11338 wcirc: 373,
11339 wedge: 8743,
11340 xcirc: 9711,
11341 xdtri: 9661,
11342 xhArr: 10234,
11343 xharr: 10231,
11344 xlArr: 10232,
11345 xlarr: 10229,
11346 xodot: 10752,
11347 xrArr: 10233,
11348 xrarr: 10230,
11349 xutri: 9651,
11350 ycirc: 375,
11351 Aopf: 120120,
11352 Ascr: 119964,
11353 Auml: 196,
11354 Barv: 10983,
11355 Beta: 914,
11356 Bopf: 120121,
11357 Bscr: 8492,
11358 CHcy: 1063,
11359 COPY: 169,
11360 Cdot: 266,
11361 Copf: 8450,
11362 Cscr: 119966,
11363 DJcy: 1026,
11364 DScy: 1029,
11365 DZcy: 1039,
11366 Darr: 8609,
11367 Dopf: 120123,
11368 Dscr: 119967,
11369 Edot: 278,
11370 Eopf: 120124,
11371 Escr: 8496,
11372 Esim: 10867,
11373 Euml: 203,
11374 Fopf: 120125,
11375 Fscr: 8497,
11376 GJcy: 1027,
11377 Gdot: 288,
11378 Gopf: 120126,
11379 Gscr: 119970,
11380 Hopf: 8461,
11381 Hscr: 8459,
11382 IEcy: 1045,
11383 IOcy: 1025,
11384 Idot: 304,
11385 Iopf: 120128,
11386 Iota: 921,
11387 Iscr: 8464,
11388 Iuml: 207,
11389 Jopf: 120129,
11390 Jscr: 119973,
11391 KHcy: 1061,
11392 KJcy: 1036,
11393 Kopf: 120130,
11394 Kscr: 119974,
11395 LJcy: 1033,
11396 Lang: 10218,
11397 Larr: 8606,
11398 Lopf: 120131,
11399 Lscr: 8466,
11400 Mopf: 120132,
11401 Mscr: 8499,
11402 NJcy: 1034,
11403 Nopf: 8469,
11404 Nscr: 119977,
11405 Oopf: 120134,
11406 Oscr: 119978,
11407 Ouml: 214,
11408 Popf: 8473,
11409 Pscr: 119979,
11410 QUOT: 34,
11411 Qopf: 8474,
11412 Qscr: 119980,
11413 Rang: 10219,
11414 Rarr: 8608,
11415 Ropf: 8477,
11416 Rscr: 8475,
11417 SHcy: 1064,
11418 Sopf: 120138,
11419 Sqrt: 8730,
11420 Sscr: 119982,
11421 Star: 8902,
11422 TScy: 1062,
11423 Topf: 120139,
11424 Tscr: 119983,
11425 Uarr: 8607,
11426 Uopf: 120140,
11427 Upsi: 978,
11428 Uscr: 119984,
11429 Uuml: 220,
11430 Vbar: 10987,
11431 Vert: 8214,
11432 Vopf: 120141,
11433 Vscr: 119985,
11434 Wopf: 120142,
11435 Wscr: 119986,
11436 Xopf: 120143,
11437 Xscr: 119987,
11438 YAcy: 1071,
11439 YIcy: 1031,
11440 YUcy: 1070,
11441 Yopf: 120144,
11442 Yscr: 119988,
11443 Yuml: 376,
11444 ZHcy: 1046,
11445 Zdot: 379,
11446 Zeta: 918,
11447 Zopf: 8484,
11448 Zscr: 119989,
11449 andd: 10844,
11450 andv: 10842,
11451 ange: 10660,
11452 aopf: 120146,
11453 apid: 8779,
11454 apos: 39,
11455 ascr: 119990,
11456 auml: 228,
11457 bNot: 10989,
11458 bbrk: 9141,
11459 beta: 946,
11460 beth: 8502,
11461 bnot: 8976,
11462 bopf: 120147,
11463 boxH: 9552,
11464 boxV: 9553,
11465 boxh: 9472,
11466 boxv: 9474,
11467 bscr: 119991,
11468 bsim: 8765,
11469 bsol: 92,
11470 bull: 8226,
11471 bump: 8782,
11472 cdot: 267,
11473 cent: 162,
11474 chcy: 1095,
11475 cirE: 10691,
11476 circ: 710,
11477 cire: 8791,
11478 comp: 8705,
11479 cong: 8773,
11480 copf: 120148,
11481 copy: 169,
11482 cscr: 119992,
11483 csub: 10959,
11484 csup: 10960,
11485 dArr: 8659,
11486 dHar: 10597,
11487 darr: 8595,
11488 dash: 8208,
11489 diam: 8900,
11490 djcy: 1106,
11491 dopf: 120149,
11492 dscr: 119993,
11493 dscy: 1109,
11494 dsol: 10742,
11495 dtri: 9663,
11496 dzcy: 1119,
11497 eDot: 8785,
11498 ecir: 8790,
11499 edot: 279,
11500 emsp: 8195,
11501 ensp: 8194,
11502 eopf: 120150,
11503 epar: 8917,
11504 epsi: 1013,
11505 escr: 8495,
11506 esim: 8770,
11507 euml: 235,
11508 euro: 8364,
11509 excl: 33,
11510 flat: 9837,
11511 fnof: 402,
11512 fopf: 120151,
11513 fork: 8916,
11514 fscr: 119995,
11515 gdot: 289,
11516 geqq: 8807,
11517 gjcy: 1107,
11518 gnap: 10890,
11519 gneq: 10888,
11520 gopf: 120152,
11521 gscr: 8458,
11522 gsim: 8819,
11523 gtcc: 10919,
11524 hArr: 8660,
11525 half: 189,
11526 harr: 8596,
11527 hbar: 8463,
11528 hopf: 120153,
11529 hscr: 119997,
11530 iecy: 1077,
11531 imof: 8887,
11532 iocy: 1105,
11533 iopf: 120154,
11534 iota: 953,
11535 iscr: 119998,
11536 isin: 8712,
11537 iuml: 239,
11538 jopf: 120155,
11539 jscr: 119999,
11540 khcy: 1093,
11541 kjcy: 1116,
11542 kopf: 120156,
11543 kscr: 120000,
11544 lArr: 8656,
11545 lHar: 10594,
11546 lang: 10216,
11547 larr: 8592,
11548 late: 10925,
11549 lcub: 123,
11550 ldca: 10550,
11551 ldsh: 8626,
11552 leqq: 8806,
11553 ljcy: 1113,
11554 lnap: 10889,
11555 lneq: 10887,
11556 lopf: 120157,
11557 lozf: 10731,
11558 lpar: 40,
11559 lscr: 120001,
11560 lsim: 8818,
11561 lsqb: 91,
11562 ltcc: 10918,
11563 ltri: 9667,
11564 macr: 175,
11565 male: 9794,
11566 malt: 10016,
11567 mlcp: 10971,
11568 mldr: 8230,
11569 mopf: 120158,
11570 mscr: 120002,
11571 nbsp: 160,
11572 ncap: 10819,
11573 ncup: 10818,
11574 ngeq: 8817,
11575 ngtr: 8815,
11576 nisd: 8954,
11577 njcy: 1114,
11578 nldr: 8229,
11579 nleq: 8816,
11580 nmid: 8740,
11581 nopf: 120159,
11582 npar: 8742,
11583 nscr: 120003,
11584 nsim: 8769,
11585 nsub: 8836,
11586 nsup: 8837,
11587 ntgl: 8825,
11588 ntlg: 8824,
11589 oast: 8859,
11590 ocir: 8858,
11591 odiv: 10808,
11592 odot: 8857,
11593 ogon: 731,
11594 oint: 8750,
11595 omid: 10678,
11596 oopf: 120160,
11597 opar: 10679,
11598 ordf: 170,
11599 ordm: 186,
11600 oror: 10838,
11601 oscr: 8500,
11602 osol: 8856,
11603 ouml: 246,
11604 para: 182,
11605 part: 8706,
11606 perp: 8869,
11607 phiv: 966,
11608 plus: 43,
11609 popf: 120161,
11610 prap: 10935,
11611 prec: 8826,
11612 prnE: 10933,
11613 prod: 8719,
11614 prop: 8733,
11615 pscr: 120005,
11616 qint: 10764,
11617 qopf: 120162,
11618 qscr: 120006,
11619 quot: 34,
11620 rArr: 8658,
11621 rHar: 10596,
11622 race: 10714,
11623 rang: 10217,
11624 rarr: 8594,
11625 rcub: 125,
11626 rdca: 10551,
11627 rdsh: 8627,
11628 real: 8476,
11629 rect: 9645,
11630 rhov: 1009,
11631 ring: 730,
11632 ropf: 120163,
11633 rpar: 41,
11634 rscr: 120007,
11635 rsqb: 93,
11636 rtri: 9657,
11637 scap: 10936,
11638 scnE: 10934,
11639 sdot: 8901,
11640 sect: 167,
11641 semi: 59,
11642 sext: 10038,
11643 shcy: 1096,
11644 sime: 8771,
11645 simg: 10910,
11646 siml: 10909,
11647 smid: 8739,
11648 smte: 10924,
11649 solb: 10692,
11650 sopf: 120164,
11651 spar: 8741,
11652 squf: 9642,
11653 sscr: 120008,
11654 star: 9734,
11655 subE: 10949,
11656 sube: 8838,
11657 succ: 8827,
11658 sung: 9834,
11659 sup1: 185,
11660 sup2: 178,
11661 sup3: 179,
11662 supE: 10950,
11663 supe: 8839,
11664 tbrk: 9140,
11665 tdot: 8411,
11666 tint: 8749,
11667 toea: 10536,
11668 topf: 120165,
11669 tosa: 10537,
11670 trie: 8796,
11671 tscr: 120009,
11672 tscy: 1094,
11673 uArr: 8657,
11674 uHar: 10595,
11675 uarr: 8593,
11676 uopf: 120166,
11677 upsi: 965,
11678 uscr: 120010,
11679 utri: 9653,
11680 uuml: 252,
11681 vArr: 8661,
11682 vBar: 10984,
11683 varr: 8597,
11684 vert: 124,
11685 vopf: 120167,
11686 vscr: 120011,
11687 wopf: 120168,
11688 wscr: 120012,
11689 xcap: 8898,
11690 xcup: 8899,
11691 xmap: 10236,
11692 xnis: 8955,
11693 xopf: 120169,
11694 xscr: 120013,
11695 xvee: 8897,
11696 yacy: 1103,
11697 yicy: 1111,
11698 yopf: 120170,
11699 yscr: 120014,
11700 yucy: 1102,
11701 yuml: 255,
11702 zdot: 380,
11703 zeta: 950,
11704 zhcy: 1078,
11705 zopf: 120171,
11706 zscr: 120015,
11707 zwnj: 8204,
11708 AMP: 38,
11709 Acy: 1040,
11710 Afr: 120068,
11711 And: 10835,
11712 Bcy: 1041,
11713 Bfr: 120069,
11714 Cap: 8914,
11715 Cfr: 8493,
11716 Chi: 935,
11717 Cup: 8915,
11718 Dcy: 1044,
11719 Del: 8711,
11720 Dfr: 120071,
11721 Dot: 168,
11722 ENG: 330,
11723 ETH: 208,
11724 Ecy: 1069,
11725 Efr: 120072,
11726 Eta: 919,
11727 Fcy: 1060,
11728 Ffr: 120073,
11729 Gcy: 1043,
11730 Gfr: 120074,
11731 Hat: 94,
11732 Hfr: 8460,
11733 Icy: 1048,
11734 Ifr: 8465,
11735 Int: 8748,
11736 Jcy: 1049,
11737 Jfr: 120077,
11738 Kcy: 1050,
11739 Kfr: 120078,
11740 Lcy: 1051,
11741 Lfr: 120079,
11742 Lsh: 8624,
11743 Map: 10501,
11744 Mcy: 1052,
11745 Mfr: 120080,
11746 Ncy: 1053,
11747 Nfr: 120081,
11748 Not: 10988,
11749 Ocy: 1054,
11750 Ofr: 120082,
11751 Pcy: 1055,
11752 Pfr: 120083,
11753 Phi: 934,
11754 Psi: 936,
11755 Qfr: 120084,
11756 REG: 174,
11757 Rcy: 1056,
11758 Rfr: 8476,
11759 Rho: 929,
11760 Rsh: 8625,
11761 Scy: 1057,
11762 Sfr: 120086,
11763 Sub: 8912,
11764 Sum: 8721,
11765 Sup: 8913,
11766 Tab: 9,
11767 Tau: 932,
11768 Tcy: 1058,
11769 Tfr: 120087,
11770 Ucy: 1059,
11771 Ufr: 120088,
11772 Vcy: 1042,
11773 Vee: 8897,
11774 Vfr: 120089,
11775 Wfr: 120090,
11776 Xfr: 120091,
11777 Ycy: 1067,
11778 Yfr: 120092,
11779 Zcy: 1047,
11780 Zfr: 8488,
11781 acd: 8767,
11782 acy: 1072,
11783 afr: 120094,
11784 amp: 38,
11785 and: 8743,
11786 ang: 8736,
11787 apE: 10864,
11788 ape: 8778,
11789 ast: 42,
11790 bcy: 1073,
11791 bfr: 120095,
11792 bot: 8869,
11793 cap: 8745,
11794 cfr: 120096,
11795 chi: 967,
11796 cir: 9675,
11797 cup: 8746,
11798 dcy: 1076,
11799 deg: 176,
11800 dfr: 120097,
11801 die: 168,
11802 div: 247,
11803 dot: 729,
11804 ecy: 1101,
11805 efr: 120098,
11806 egs: 10902,
11807 ell: 8467,
11808 els: 10901,
11809 eng: 331,
11810 eta: 951,
11811 eth: 240,
11812 fcy: 1092,
11813 ffr: 120099,
11814 gEl: 10892,
11815 gap: 10886,
11816 gcy: 1075,
11817 gel: 8923,
11818 geq: 8805,
11819 ges: 10878,
11820 gfr: 120100,
11821 ggg: 8921,
11822 glE: 10898,
11823 gla: 10917,
11824 glj: 10916,
11825 gnE: 8809,
11826 gne: 10888,
11827 hfr: 120101,
11828 icy: 1080,
11829 iff: 8660,
11830 ifr: 120102,
11831 int: 8747,
11832 jcy: 1081,
11833 jfr: 120103,
11834 kcy: 1082,
11835 kfr: 120104,
11836 lEg: 10891,
11837 lap: 10885,
11838 lat: 10923,
11839 lcy: 1083,
11840 leg: 8922,
11841 leq: 8804,
11842 les: 10877,
11843 lfr: 120105,
11844 lgE: 10897,
11845 lnE: 8808,
11846 lne: 10887,
11847 loz: 9674,
11848 lrm: 8206,
11849 lsh: 8624,
11850 map: 8614,
11851 mcy: 1084,
11852 mfr: 120106,
11853 mho: 8487,
11854 mid: 8739,
11855 nap: 8777,
11856 ncy: 1085,
11857 nfr: 120107,
11858 nge: 8817,
11859 ngt: 8815,
11860 nis: 8956,
11861 niv: 8715,
11862 nle: 8816,
11863 nlt: 8814,
11864 not: 172,
11865 npr: 8832,
11866 nsc: 8833,
11867 num: 35,
11868 ocy: 1086,
11869 ofr: 120108,
11870 ogt: 10689,
11871 ohm: 8486,
11872 olt: 10688,
11873 ord: 10845,
11874 orv: 10843,
11875 par: 8741,
11876 pcy: 1087,
11877 pfr: 120109,
11878 phi: 966,
11879 piv: 982,
11880 prE: 10931,
11881 pre: 10927,
11882 psi: 968,
11883 qfr: 120110,
11884 rcy: 1088,
11885 reg: 174,
11886 rfr: 120111,
11887 rho: 961,
11888 rlm: 8207,
11889 rsh: 8625,
11890 scE: 10932,
11891 sce: 10928,
11892 scy: 1089,
11893 sfr: 120112,
11894 shy: 173,
11895 sim: 8764,
11896 smt: 10922,
11897 sol: 47,
11898 squ: 9633,
11899 sub: 8834,
11900 sum: 8721,
11901 sup: 8835,
11902 tau: 964,
11903 tcy: 1090,
11904 tfr: 120113,
11905 top: 8868,
11906 ucy: 1091,
11907 ufr: 120114,
11908 uml: 168,
11909 vcy: 1074,
11910 vee: 8744,
11911 vfr: 120115,
11912 wfr: 120116,
11913 xfr: 120117,
11914 ycy: 1099,
11915 yen: 165,
11916 yfr: 120118,
11917 zcy: 1079,
11918 zfr: 120119,
11919 zwj: 8205,
11920 DD: 8517,
11921 GT: 62,
11922 Gg: 8921,
11923 Gt: 8811,
11924 Im: 8465,
11925 LT: 60,
11926 Ll: 8920,
11927 Lt: 8810,
11928 Mu: 924,
11929 Nu: 925,
11930 Or: 10836,
11931 Pi: 928,
11932 Pr: 10939,
11933 Re: 8476,
11934 Sc: 10940,
11935 Xi: 926,
11936 ac: 8766,
11937 af: 8289,
11938 ap: 8776,
11939 dd: 8518,
11940 ee: 8519,
11941 eg: 10906,
11942 el: 10905,
11943 gE: 8807,
11944 ge: 8805,
11945 gg: 8811,
11946 gl: 8823,
11947 gt: 62,
11948 ic: 8291,
11949 ii: 8520,
11950 in: 8712,
11951 it: 8290,
11952 lE: 8806,
11953 le: 8804,
11954 lg: 8822,
11955 ll: 8810,
11956 lt: 60,
11957 mp: 8723,
11958 mu: 956,
11959 ne: 8800,
11960 ni: 8715,
11961 nu: 957,
11962 oS: 9416,
11963 or: 8744,
11964 pi: 960,
11965 pm: 177,
11966 pr: 8826,
11967 rx: 8478,
11968 sc: 8827,
11969 wp: 8472,
11970 wr: 8768,
11971 xi: 958,
11972 };
11973
11974 const windows_1252 = [
11975 8364,
11976 129,
11977 8218,
11978 402,
11979 8222,
11980 8230,
11981 8224,
11982 8225,
11983 710,
11984 8240,
11985 352,
11986 8249,
11987 338,
11988 141,
11989 381,
11990 143,
11991 144,
11992 8216,
11993 8217,
11994 8220,
11995 8221,
11996 8226,
11997 8211,
11998 8212,
11999 732,
12000 8482,
12001 353,
12002 8250,
12003 339,
12004 157,
12005 382,
12006 376,
12007 ];
12008 const entity_pattern = new RegExp(`&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(entities).join('|')}))(?:;|\\b)`, 'g');
12009 function decode_character_references(html) {
12010 return html.replace(entity_pattern, (match, entity) => {
12011 let code;
12012 // Handle named entities
12013 if (entity[0] !== '#') {
12014 code = entities[entity];
12015 }
12016 else if (entity[1] === 'x') {
12017 code = parseInt(entity.substring(2), 16);
12018 }
12019 else {
12020 code = parseInt(entity.substring(1), 10);
12021 }
12022 if (!code) {
12023 return match;
12024 }
12025 return String.fromCodePoint(validate_code(code));
12026 });
12027 }
12028 const NUL = 0;
12029 // some code points are verboten. If we were inserting HTML, the browser would replace the illegal
12030 // code points with alternatives in some cases - since we're bypassing that mechanism, we need
12031 // to replace them ourselves
12032 //
12033 // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters
12034 function validate_code(code) {
12035 // line feed becomes generic whitespace
12036 if (code === 10) {
12037 return 32;
12038 }
12039 // ASCII range. (Why someone would use HTML entities for ASCII characters I don't know, but...)
12040 if (code < 128) {
12041 return code;
12042 }
12043 // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need
12044 // to correct the mistake or we'll end up with missing € signs and so on
12045 if (code <= 159) {
12046 return windows_1252[code - 128];
12047 }
12048 // basic multilingual plane
12049 if (code < 55296) {
12050 return code;
12051 }
12052 // UTF-16 surrogate halves
12053 if (code <= 57343) {
12054 return NUL;
12055 }
12056 // rest of the basic multilingual plane
12057 if (code <= 65535) {
12058 return code;
12059 }
12060 // supplementary multilingual plane 0x10000 - 0x1ffff
12061 if (code >= 65536 && code <= 131071) {
12062 return code;
12063 }
12064 // supplementary ideographic plane 0x20000 - 0x2ffff
12065 if (code >= 131072 && code <= 196607) {
12066 return code;
12067 }
12068 return NUL;
12069 }
12070
12071 // Adapted from https://github.com/acornjs/acorn/blob/6584815dca7440e00de841d1dad152302fdd7ca5/src/tokenize.js
12072 // Reproduced under MIT License https://github.com/acornjs/acorn/blob/master/LICENSE
12073 function full_char_code_at(str, i) {
12074 const code = str.charCodeAt(i);
12075 if (code <= 0xd7ff || code >= 0xe000)
12076 return code;
12077 const next = str.charCodeAt(i + 1);
12078 return (code << 10) + next - 0x35fdc00;
12079 }
12080
12081 const globals = new Set([
12082 'alert',
12083 'Array',
12084 'Boolean',
12085 'confirm',
12086 'console',
12087 'Date',
12088 'decodeURI',
12089 'decodeURIComponent',
12090 'document',
12091 'encodeURI',
12092 'encodeURIComponent',
12093 'Error',
12094 'EvalError',
12095 'Infinity',
12096 'InternalError',
12097 'Intl',
12098 'isFinite',
12099 'isNaN',
12100 'JSON',
12101 'Map',
12102 'Math',
12103 'NaN',
12104 'Number',
12105 'Object',
12106 'parseFloat',
12107 'parseInt',
12108 'process',
12109 'Promise',
12110 'prompt',
12111 'RangeError',
12112 'ReferenceError',
12113 'RegExp',
12114 'Set',
12115 'String',
12116 'SyntaxError',
12117 'TypeError',
12118 'undefined',
12119 'URIError',
12120 'window'
12121 ]);
12122 const reserved = new Set([
12123 'arguments',
12124 'await',
12125 'break',
12126 'case',
12127 'catch',
12128 'class',
12129 'const',
12130 'continue',
12131 'debugger',
12132 'default',
12133 'delete',
12134 'do',
12135 'else',
12136 'enum',
12137 'eval',
12138 'export',
12139 'extends',
12140 'false',
12141 'finally',
12142 'for',
12143 'function',
12144 'if',
12145 'implements',
12146 'import',
12147 'in',
12148 'instanceof',
12149 'interface',
12150 'let',
12151 'new',
12152 'null',
12153 'package',
12154 'private',
12155 'protected',
12156 'public',
12157 'return',
12158 'static',
12159 'super',
12160 'switch',
12161 'this',
12162 'throw',
12163 'true',
12164 'try',
12165 'typeof',
12166 'var',
12167 'void',
12168 'while',
12169 'with',
12170 'yield',
12171 ]);
12172 const void_element_names = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
12173 function is_void(name) {
12174 return void_element_names.test(name) || name.toLowerCase() === '!doctype';
12175 }
12176 function is_valid(str) {
12177 let i = 0;
12178 while (i < str.length) {
12179 const code = full_char_code_at(str, i);
12180 if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true))
12181 return false;
12182 i += code <= 0xffff ? 1 : 2;
12183 }
12184 return true;
12185 }
12186 function quote_name_if_necessary(name) {
12187 if (!is_valid(name))
12188 return `"${name}"`;
12189 return name;
12190 }
12191 function quote_prop_if_necessary(name) {
12192 if (!is_valid(name))
12193 return `["${name}"]`;
12194 return `.${name}`;
12195 }
12196 function sanitize(name) {
12197 return name
12198 .replace(/[^a-zA-Z0-9_]+/g, '_')
12199 .replace(/^_/, '')
12200 .replace(/_$/, '')
12201 .replace(/^[0-9]/, '_$&');
12202 }
12203
12204 function fuzzymatch(name, names) {
12205 const set = new FuzzySet(names);
12206 const matches = set.get(name);
12207 return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null;
12208 }
12209 // adapted from https://github.com/Glench/fuzzyset.js/blob/master/lib/fuzzyset.js
12210 // BSD Licensed
12211 const GRAM_SIZE_LOWER = 2;
12212 const GRAM_SIZE_UPPER = 3;
12213 // return an edit distance from 0 to 1
12214 function _distance(str1, str2) {
12215 if (str1 === null && str2 === null)
12216 throw 'Trying to compare two null values';
12217 if (str1 === null || str2 === null)
12218 return 0;
12219 str1 = String(str1);
12220 str2 = String(str2);
12221 const distance = levenshtein(str1, str2);
12222 if (str1.length > str2.length) {
12223 return 1 - distance / str1.length;
12224 }
12225 else {
12226 return 1 - distance / str2.length;
12227 }
12228 }
12229 // helper functions
12230 function levenshtein(str1, str2) {
12231 const current = [];
12232 let prev;
12233 let value;
12234 for (let i = 0; i <= str2.length; i++) {
12235 for (let j = 0; j <= str1.length; j++) {
12236 if (i && j) {
12237 if (str1.charAt(j - 1) === str2.charAt(i - 1)) {
12238 value = prev;
12239 }
12240 else {
12241 value = Math.min(current[j], current[j - 1], prev) + 1;
12242 }
12243 }
12244 else {
12245 value = i + j;
12246 }
12247 prev = current[j];
12248 current[j] = value;
12249 }
12250 }
12251 return current.pop();
12252 }
12253 const non_word_regex = /[^\w, ]+/;
12254 function iterate_grams(value, gram_size = 2) {
12255 const simplified = '-' + value.toLowerCase().replace(non_word_regex, '') + '-';
12256 const len_diff = gram_size - simplified.length;
12257 const results = [];
12258 if (len_diff > 0) {
12259 for (let i = 0; i < len_diff; ++i) {
12260 value += '-';
12261 }
12262 }
12263 for (let i = 0; i < simplified.length - gram_size + 1; ++i) {
12264 results.push(simplified.slice(i, i + gram_size));
12265 }
12266 return results;
12267 }
12268 function gram_counter(value, gram_size = 2) {
12269 // return an object where key=gram, value=number of occurrences
12270 const result = {};
12271 const grams = iterate_grams(value, gram_size);
12272 let i = 0;
12273 for (i; i < grams.length; ++i) {
12274 if (grams[i] in result) {
12275 result[grams[i]] += 1;
12276 }
12277 else {
12278 result[grams[i]] = 1;
12279 }
12280 }
12281 return result;
12282 }
12283 function sort_descending(a, b) {
12284 return b[0] - a[0];
12285 }
12286 class FuzzySet {
12287 constructor(arr) {
12288 this.exact_set = {};
12289 this.match_dict = {};
12290 this.items = {};
12291 // initialization
12292 for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) {
12293 this.items[i] = [];
12294 }
12295 // add all the items to the set
12296 for (let i = 0; i < arr.length; ++i) {
12297 this.add(arr[i]);
12298 }
12299 }
12300 add(value) {
12301 const normalized_value = value.toLowerCase();
12302 if (normalized_value in this.exact_set) {
12303 return false;
12304 }
12305 let i = GRAM_SIZE_LOWER;
12306 for (i; i < GRAM_SIZE_UPPER + 1; ++i) {
12307 this._add(value, i);
12308 }
12309 }
12310 _add(value, gram_size) {
12311 const normalized_value = value.toLowerCase();
12312 const items = this.items[gram_size] || [];
12313 const index = items.length;
12314 items.push(0);
12315 const gram_counts = gram_counter(normalized_value, gram_size);
12316 let sum_of_square_gram_counts = 0;
12317 let gram;
12318 let gram_count;
12319 for (gram in gram_counts) {
12320 gram_count = gram_counts[gram];
12321 sum_of_square_gram_counts += Math.pow(gram_count, 2);
12322 if (gram in this.match_dict) {
12323 this.match_dict[gram].push([index, gram_count]);
12324 }
12325 else {
12326 this.match_dict[gram] = [[index, gram_count]];
12327 }
12328 }
12329 const vector_normal = Math.sqrt(sum_of_square_gram_counts);
12330 items[index] = [vector_normal, normalized_value];
12331 this.items[gram_size] = items;
12332 this.exact_set[normalized_value] = value;
12333 }
12334 get(value) {
12335 const normalized_value = value.toLowerCase();
12336 const result = this.exact_set[normalized_value];
12337 if (result) {
12338 return [[1, result]];
12339 }
12340 let results = [];
12341 // start with high gram size and if there are no results, go to lower gram sizes
12342 for (let gram_size = GRAM_SIZE_UPPER; gram_size >= GRAM_SIZE_LOWER; --gram_size) {
12343 results = this.__get(value, gram_size);
12344 if (results) {
12345 return results;
12346 }
12347 }
12348 return null;
12349 }
12350 __get(value, gram_size) {
12351 const normalized_value = value.toLowerCase();
12352 const matches = {};
12353 const gram_counts = gram_counter(normalized_value, gram_size);
12354 const items = this.items[gram_size];
12355 let sum_of_square_gram_counts = 0;
12356 let gram;
12357 let gram_count;
12358 let i;
12359 let index;
12360 let other_gram_count;
12361 for (gram in gram_counts) {
12362 gram_count = gram_counts[gram];
12363 sum_of_square_gram_counts += Math.pow(gram_count, 2);
12364 if (gram in this.match_dict) {
12365 for (i = 0; i < this.match_dict[gram].length; ++i) {
12366 index = this.match_dict[gram][i][0];
12367 other_gram_count = this.match_dict[gram][i][1];
12368 if (index in matches) {
12369 matches[index] += gram_count * other_gram_count;
12370 }
12371 else {
12372 matches[index] = gram_count * other_gram_count;
12373 }
12374 }
12375 }
12376 }
12377 const vector_normal = Math.sqrt(sum_of_square_gram_counts);
12378 let results = [];
12379 let match_score;
12380 // build a results list of [score, str]
12381 for (const match_index in matches) {
12382 match_score = matches[match_index];
12383 results.push([
12384 match_score / (vector_normal * items[match_index][0]),
12385 items[match_index][1],
12386 ]);
12387 }
12388 results.sort(sort_descending);
12389 let new_results = [];
12390 const end_index = Math.min(50, results.length);
12391 // truncate somewhat arbitrarily to 50
12392 for (let i = 0; i < end_index; ++i) {
12393 new_results.push([
12394 _distance(results[i][1], normalized_value),
12395 results[i][1],
12396 ]);
12397 }
12398 results = new_results;
12399 results.sort(sort_descending);
12400 new_results = [];
12401 for (let i = 0; i < results.length; ++i) {
12402 if (results[i][0] == results[0][0]) {
12403 new_results.push([results[i][0], this.exact_set[results[i][1]]]);
12404 }
12405 }
12406 return new_results;
12407 }
12408 }
12409
12410 function list$1(items, conjunction = 'or') {
12411 if (items.length === 1)
12412 return items[0];
12413 return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[items.length - 1]}`;
12414 }
12415
12416 // eslint-disable-next-line no-useless-escape
12417 const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
12418 const meta_tags = new Map([
12419 ['svelte:head', 'Head'],
12420 ['svelte:options', 'Options'],
12421 ['svelte:window', 'Window'],
12422 ['svelte:body', 'Body']
12423 ]);
12424 const valid_meta_tags = Array.from(meta_tags.keys()).concat('svelte:self', 'svelte:component');
12425 const specials = new Map([
12426 [
12427 'script',
12428 {
12429 read: read_script,
12430 property: 'js',
12431 },
12432 ],
12433 [
12434 'style',
12435 {
12436 read: read_style,
12437 property: 'css',
12438 },
12439 ],
12440 ]);
12441 // eslint-disable-next-line no-useless-escape
12442 const SELF = /^svelte:self(?=[\s\/>])/;
12443 // eslint-disable-next-line no-useless-escape
12444 const COMPONENT = /^svelte:component(?=[\s\/>])/;
12445 // based on http://developers.whatwg.org/syntax.html#syntax-tag-omission
12446 const disallowed_contents = new Map([
12447 ['li', new Set(['li'])],
12448 ['dt', new Set(['dt', 'dd'])],
12449 ['dd', new Set(['dt', 'dd'])],
12450 [
12451 'p',
12452 new Set('address article aside blockquote div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul'.split(' ')),
12453 ],
12454 ['rt', new Set(['rt', 'rp'])],
12455 ['rp', new Set(['rt', 'rp'])],
12456 ['optgroup', new Set(['optgroup'])],
12457 ['option', new Set(['option', 'optgroup'])],
12458 ['thead', new Set(['tbody', 'tfoot'])],
12459 ['tbody', new Set(['tbody', 'tfoot'])],
12460 ['tfoot', new Set(['tbody'])],
12461 ['tr', new Set(['tr', 'tbody'])],
12462 ['td', new Set(['td', 'th', 'tr'])],
12463 ['th', new Set(['td', 'th', 'tr'])],
12464 ]);
12465 function parent_is_head(stack) {
12466 let i = stack.length;
12467 while (i--) {
12468 const { type } = stack[i];
12469 if (type === 'Head')
12470 return true;
12471 if (type === 'Element' || type === 'InlineComponent')
12472 return false;
12473 }
12474 return false;
12475 }
12476 function tag(parser) {
12477 const start = parser.index++;
12478 let parent = parser.current();
12479 if (parser.eat('!--')) {
12480 const data = parser.read_until(/-->/);
12481 parser.eat('-->', true, 'comment was left open, expected -->');
12482 parser.current().children.push({
12483 start,
12484 end: parser.index,
12485 type: 'Comment',
12486 data,
12487 });
12488 return;
12489 }
12490 const is_closing_tag = parser.eat('/');
12491 const name = read_tag_name(parser);
12492 if (meta_tags.has(name)) {
12493 const slug = meta_tags.get(name).toLowerCase();
12494 if (is_closing_tag) {
12495 if ((name === 'svelte:window' || name === 'svelte:body') &&
12496 parser.current().children.length) {
12497 parser.error({
12498 code: `invalid-${name.slice(7)}-content`,
12499 message: `<${name}> cannot have children`
12500 }, parser.current().children[0].start);
12501 }
12502 }
12503 else {
12504 if (name in parser.meta_tags) {
12505 parser.error({
12506 code: `duplicate-${slug}`,
12507 message: `A component can only have one <${name}> tag`
12508 }, start);
12509 }
12510 if (parser.stack.length > 1) {
12511 parser.error({
12512 code: `invalid-${slug}-placement`,
12513 message: `<${name}> tags cannot be inside elements or blocks`
12514 }, start);
12515 }
12516 parser.meta_tags[name] = true;
12517 }
12518 }
12519 const type = meta_tags.has(name)
12520 ? meta_tags.get(name)
12521 : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent'
12522 : name === 'title' && parent_is_head(parser.stack) ? 'Title'
12523 : name === 'slot' && !parser.customElement ? 'Slot' : 'Element';
12524 const element = {
12525 start,
12526 end: null,
12527 type,
12528 name,
12529 attributes: [],
12530 children: [],
12531 };
12532 parser.allow_whitespace();
12533 if (is_closing_tag) {
12534 if (is_void(name)) {
12535 parser.error({
12536 code: `invalid-void-content`,
12537 message: `<${name}> is a void element and cannot have children, or a closing tag`
12538 }, start);
12539 }
12540 parser.eat('>', true);
12541 // close any elements that don't have their own closing tags, e.g. <div><p></div>
12542 while (parent.name !== name) {
12543 if (parent.type !== 'Element')
12544 parser.error({
12545 code: `invalid-closing-tag`,
12546 message: `</${name}> attempted to close an element that was not open`
12547 }, start);
12548 parent.end = start;
12549 parser.stack.pop();
12550 parent = parser.current();
12551 }
12552 parent.end = parser.index;
12553 parser.stack.pop();
12554 return;
12555 }
12556 else if (disallowed_contents.has(parent.name)) {
12557 // can this be a child of the parent element, or does it implicitly
12558 // close it, like `<li>one<li>two`?
12559 if (disallowed_contents.get(parent.name).has(name)) {
12560 parent.end = start;
12561 parser.stack.pop();
12562 }
12563 }
12564 const unique_names = new Set();
12565 let attribute;
12566 while ((attribute = read_attribute(parser, unique_names))) {
12567 element.attributes.push(attribute);
12568 parser.allow_whitespace();
12569 }
12570 if (name === 'svelte:component') {
12571 const index = element.attributes.findIndex(attr => attr.type === 'Attribute' && attr.name === 'this');
12572 if (!~index) {
12573 parser.error({
12574 code: `missing-component-definition`,
12575 message: `<svelte:component> must have a 'this' attribute`
12576 }, start);
12577 }
12578 const definition = element.attributes.splice(index, 1)[0];
12579 if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') {
12580 parser.error({
12581 code: `invalid-component-definition`,
12582 message: `invalid component definition`
12583 }, definition.start);
12584 }
12585 element.expression = definition.value[0].expression;
12586 }
12587 // special cases – top-level <script> and <style>
12588 if (specials.has(name) && parser.stack.length === 1) {
12589 const special = specials.get(name);
12590 parser.eat('>', true);
12591 const content = special.read(parser, start, element.attributes);
12592 if (content)
12593 parser[special.property].push(content);
12594 return;
12595 }
12596 parser.current().children.push(element);
12597 const self_closing = parser.eat('/') || is_void(name);
12598 parser.eat('>', true);
12599 if (self_closing) {
12600 // don't push self-closing elements onto the stack
12601 element.end = parser.index;
12602 }
12603 else if (name === 'textarea') {
12604 // special case
12605 element.children = read_sequence(parser, () => parser.template.slice(parser.index, parser.index + 11) === '</textarea>');
12606 parser.read(/<\/textarea>/);
12607 element.end = parser.index;
12608 }
12609 else if (name === 'script') {
12610 // special case
12611 const start = parser.index;
12612 const data = parser.read_until(/<\/script>/);
12613 const end = parser.index;
12614 element.children.push({ start, end, type: 'Text', data });
12615 parser.eat('</script>', true);
12616 element.end = parser.index;
12617 }
12618 else if (name === 'style') {
12619 // special case
12620 const start = parser.index;
12621 const data = parser.read_until(/<\/style>/);
12622 const end = parser.index;
12623 element.children.push({ start, end, type: 'Text', data });
12624 parser.eat('</style>', true);
12625 }
12626 else {
12627 parser.stack.push(element);
12628 }
12629 }
12630 function read_tag_name(parser) {
12631 const start = parser.index;
12632 if (parser.read(SELF)) {
12633 // check we're inside a block, otherwise this
12634 // will cause infinite recursion
12635 let i = parser.stack.length;
12636 let legal = false;
12637 while (i--) {
12638 const fragment = parser.stack[i];
12639 if (fragment.type === 'IfBlock' || fragment.type === 'EachBlock') {
12640 legal = true;
12641 break;
12642 }
12643 }
12644 if (!legal) {
12645 parser.error({
12646 code: `invalid-self-placement`,
12647 message: `<svelte:self> components can only exist inside if-blocks or each-blocks`
12648 }, start);
12649 }
12650 return 'svelte:self';
12651 }
12652 if (parser.read(COMPONENT))
12653 return 'svelte:component';
12654 const name = parser.read_until(/(\s|\/|>)/);
12655 if (meta_tags.has(name))
12656 return name;
12657 if (name.startsWith('svelte:')) {
12658 const match = fuzzymatch(name.slice(7), valid_meta_tags);
12659 let message = `Valid <svelte:...> tag names are ${list$1(valid_meta_tags)}`;
12660 if (match)
12661 message += ` (did you mean '${match}'?)`;
12662 parser.error({
12663 code: 'invalid-tag-name',
12664 message
12665 }, start);
12666 }
12667 if (!valid_tag_name.test(name)) {
12668 parser.error({
12669 code: `invalid-tag-name`,
12670 message: `Expected valid tag name`
12671 }, start);
12672 }
12673 return name;
12674 }
12675 function read_attribute(parser, unique_names) {
12676 const start = parser.index;
12677 if (parser.eat('{')) {
12678 parser.allow_whitespace();
12679 if (parser.eat('...')) {
12680 const expression = read_expression(parser);
12681 parser.allow_whitespace();
12682 parser.eat('}', true);
12683 return {
12684 start,
12685 end: parser.index,
12686 type: 'Spread',
12687 expression
12688 };
12689 }
12690 else {
12691 const value_start = parser.index;
12692 const name = parser.read_identifier();
12693 parser.allow_whitespace();
12694 parser.eat('}', true);
12695 return {
12696 start,
12697 end: parser.index,
12698 type: 'Attribute',
12699 name,
12700 value: [{
12701 start: value_start,
12702 end: value_start + name.length,
12703 type: 'AttributeShorthand',
12704 expression: {
12705 start: value_start,
12706 end: value_start + name.length,
12707 type: 'Identifier',
12708 name
12709 }
12710 }]
12711 };
12712 }
12713 }
12714 // eslint-disable-next-line no-useless-escape
12715 const name = parser.read_until(/[\s=\/>"']/);
12716 if (!name)
12717 return null;
12718 let end = parser.index;
12719 parser.allow_whitespace();
12720 const colon_index = name.indexOf(':');
12721 const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index));
12722 if (unique_names.has(name)) {
12723 parser.error({
12724 code: `duplicate-attribute`,
12725 message: 'Attributes need to be unique'
12726 }, start);
12727 }
12728 if (type !== "EventHandler") {
12729 unique_names.add(name);
12730 }
12731 let value = true;
12732 if (parser.eat('=')) {
12733 parser.allow_whitespace();
12734 value = read_attribute_value(parser);
12735 end = parser.index;
12736 }
12737 else if (parser.match_regex(/["']/)) {
12738 parser.error({
12739 code: `unexpected-token`,
12740 message: `Expected =`
12741 }, parser.index);
12742 }
12743 if (type) {
12744 const [directive_name, ...modifiers] = name.slice(colon_index + 1).split('|');
12745 if (type === 'Ref') {
12746 parser.error({
12747 code: `invalid-ref-directive`,
12748 message: `The ref directive is no longer supported — use \`bind:this={${directive_name}}\` instead`
12749 }, start);
12750 }
12751 if (value[0]) {
12752 if (value.length > 1 || value[0].type === 'Text') {
12753 parser.error({
12754 code: `invalid-directive-value`,
12755 message: `Directive value must be a JavaScript expression enclosed in curly braces`
12756 }, value[0].start);
12757 }
12758 }
12759 const directive = {
12760 start,
12761 end,
12762 type,
12763 name: directive_name,
12764 modifiers,
12765 expression: (value[0] && value[0].expression) || null
12766 };
12767 if (type === 'Transition') {
12768 const direction = name.slice(0, colon_index);
12769 directive.intro = direction === 'in' || direction === 'transition';
12770 directive.outro = direction === 'out' || direction === 'transition';
12771 }
12772 if (!directive.expression && (type === 'Binding' || type === 'Class')) {
12773 directive.expression = {
12774 start: directive.start + colon_index + 1,
12775 end: directive.end,
12776 type: 'Identifier',
12777 name: directive.name
12778 };
12779 }
12780 return directive;
12781 }
12782 return {
12783 start,
12784 end,
12785 type: 'Attribute',
12786 name,
12787 value,
12788 };
12789 }
12790 function get_directive_type(name) {
12791 if (name === 'use')
12792 return 'Action';
12793 if (name === 'animate')
12794 return 'Animation';
12795 if (name === 'bind')
12796 return 'Binding';
12797 if (name === 'class')
12798 return 'Class';
12799 if (name === 'on')
12800 return 'EventHandler';
12801 if (name === 'let')
12802 return 'Let';
12803 if (name === 'ref')
12804 return 'Ref';
12805 if (name === 'in' || name === 'out' || name === 'transition')
12806 return 'Transition';
12807 }
12808 function read_attribute_value(parser) {
12809 const quote_mark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null;
12810 const regex = (quote_mark === `'` ? /'/ :
12811 quote_mark === `"` ? /"/ :
12812 /(\/>|[\s"'=<>`])/);
12813 const value = read_sequence(parser, () => !!parser.match_regex(regex));
12814 if (quote_mark)
12815 parser.index += 1;
12816 return value;
12817 }
12818 function read_sequence(parser, done) {
12819 let current_chunk = {
12820 start: parser.index,
12821 end: null,
12822 type: 'Text',
12823 raw: '',
12824 data: null
12825 };
12826 function flush() {
12827 if (current_chunk.raw) {
12828 current_chunk.data = decode_character_references(current_chunk.raw);
12829 current_chunk.end = parser.index;
12830 chunks.push(current_chunk);
12831 }
12832 }
12833 const chunks = [];
12834 while (parser.index < parser.template.length) {
12835 const index = parser.index;
12836 if (done()) {
12837 flush();
12838 return chunks;
12839 }
12840 else if (parser.eat('{')) {
12841 flush();
12842 parser.allow_whitespace();
12843 const expression = read_expression(parser);
12844 parser.allow_whitespace();
12845 parser.eat('}', true);
12846 chunks.push({
12847 start: index,
12848 end: parser.index,
12849 type: 'MustacheTag',
12850 expression,
12851 });
12852 current_chunk = {
12853 start: parser.index,
12854 end: null,
12855 type: 'Text',
12856 raw: '',
12857 data: null
12858 };
12859 }
12860 else {
12861 current_chunk.raw += parser.template[parser.index++];
12862 }
12863 }
12864 parser.error({
12865 code: `unexpected-eof`,
12866 message: `Unexpected end of input`
12867 });
12868 }
12869
12870 function error_on_assignment_pattern(parser) {
12871 if (parser.eat('=')) {
12872 parser.error({
12873 code: 'invalid-assignment-pattern',
12874 message: 'Assignment patterns are not supported'
12875 }, parser.index - 1);
12876 }
12877 }
12878 function error_on_rest_pattern_not_last(parser) {
12879 parser.error({
12880 code: 'rest-pattern-not-last',
12881 message: 'Rest destructuring expected to be last'
12882 }, parser.index);
12883 }
12884 function read_context(parser) {
12885 const context = {
12886 start: parser.index,
12887 end: null,
12888 type: null
12889 };
12890 if (parser.eat('[')) {
12891 context.type = 'ArrayPattern';
12892 context.elements = [];
12893 do {
12894 parser.allow_whitespace();
12895 const lastContext = context.elements[context.elements.length - 1];
12896 if (lastContext && lastContext.type === 'RestIdentifier') {
12897 error_on_rest_pattern_not_last(parser);
12898 }
12899 if (parser.template[parser.index] === ',') {
12900 context.elements.push(null);
12901 }
12902 else {
12903 context.elements.push(read_context(parser));
12904 parser.allow_whitespace();
12905 }
12906 } while (parser.eat(','));
12907 error_on_assignment_pattern(parser);
12908 parser.eat(']', true);
12909 context.end = parser.index;
12910 }
12911 else if (parser.eat('{')) {
12912 context.type = 'ObjectPattern';
12913 context.properties = [];
12914 do {
12915 parser.allow_whitespace();
12916 if (parser.eat('...')) {
12917 parser.allow_whitespace();
12918 const start = parser.index;
12919 const name = parser.read_identifier();
12920 const key = {
12921 start,
12922 end: parser.index,
12923 type: 'Identifier',
12924 name
12925 };
12926 const property = {
12927 start,
12928 end: parser.index,
12929 type: 'Property',
12930 kind: 'rest',
12931 shorthand: true,
12932 key,
12933 value: key
12934 };
12935 context.properties.push(property);
12936 parser.allow_whitespace();
12937 if (parser.eat(',')) {
12938 parser.error({
12939 code: `comma-after-rest`,
12940 message: `Comma is not permitted after the rest element`
12941 }, parser.index - 1);
12942 }
12943 break;
12944 }
12945 const start = parser.index;
12946 const name = parser.read_identifier();
12947 const key = {
12948 start,
12949 end: parser.index,
12950 type: 'Identifier',
12951 name
12952 };
12953 parser.allow_whitespace();
12954 const value = parser.eat(':')
12955 ? (parser.allow_whitespace(), read_context(parser))
12956 : key;
12957 const property = {
12958 start,
12959 end: value.end,
12960 type: 'Property',
12961 kind: 'init',
12962 shorthand: value.type === 'Identifier' && value.name === name,
12963 key,
12964 value
12965 };
12966 context.properties.push(property);
12967 parser.allow_whitespace();
12968 } while (parser.eat(','));
12969 error_on_assignment_pattern(parser);
12970 parser.eat('}', true);
12971 context.end = parser.index;
12972 }
12973 else if (parser.eat('...')) {
12974 const name = parser.read_identifier();
12975 if (name) {
12976 context.type = 'RestIdentifier';
12977 context.end = parser.index;
12978 context.name = name;
12979 }
12980 else {
12981 parser.error({
12982 code: 'invalid-context',
12983 message: 'Expected a rest pattern'
12984 });
12985 }
12986 }
12987 else {
12988 const name = parser.read_identifier();
12989 if (name) {
12990 context.type = 'Identifier';
12991 context.end = parser.index;
12992 context.name = name;
12993 }
12994 else {
12995 parser.error({
12996 code: 'invalid-context',
12997 message: 'Expected a name, array pattern or object pattern'
12998 });
12999 }
13000 error_on_assignment_pattern(parser);
13001 }
13002 return context;
13003 }
13004
13005 const whitespace = /[ \t\r\n]/;
13006 const dimensions = /^(?:offset|client)(?:Width|Height)$/;
13007
13008 function trim_start(str) {
13009 let i = 0;
13010 while (whitespace.test(str[i]))
13011 i += 1;
13012 return str.slice(i);
13013 }
13014 function trim_end(str) {
13015 let i = str.length;
13016 while (whitespace.test(str[i - 1]))
13017 i -= 1;
13018 return str.slice(0, i);
13019 }
13020
13021 function trim_whitespace(block, trim_before, trim_after) {
13022 if (!block.children || block.children.length === 0)
13023 return; // AwaitBlock
13024 const first_child = block.children[0];
13025 const last_child = block.children[block.children.length - 1];
13026 if (first_child.type === 'Text' && trim_before) {
13027 first_child.data = trim_start(first_child.data);
13028 if (!first_child.data)
13029 block.children.shift();
13030 }
13031 if (last_child.type === 'Text' && trim_after) {
13032 last_child.data = trim_end(last_child.data);
13033 if (!last_child.data)
13034 block.children.pop();
13035 }
13036 if (block.else) {
13037 trim_whitespace(block.else, trim_before, trim_after);
13038 }
13039 if (first_child.elseif) {
13040 trim_whitespace(first_child, trim_before, trim_after);
13041 }
13042 }
13043 function mustache(parser) {
13044 const start = parser.index;
13045 parser.index += 1;
13046 parser.allow_whitespace();
13047 // {/if}, {/each} or {/await}
13048 if (parser.eat('/')) {
13049 let block = parser.current();
13050 let expected;
13051 if (block.type === 'ElseBlock' || block.type === 'PendingBlock' || block.type === 'ThenBlock' || block.type === 'CatchBlock') {
13052 block.end = start;
13053 parser.stack.pop();
13054 block = parser.current();
13055 expected = 'await';
13056 }
13057 if (block.type === 'IfBlock') {
13058 expected = 'if';
13059 }
13060 else if (block.type === 'EachBlock') {
13061 expected = 'each';
13062 }
13063 else if (block.type === 'AwaitBlock') {
13064 expected = 'await';
13065 }
13066 else {
13067 parser.error({
13068 code: `unexpected-block-close`,
13069 message: `Unexpected block closing tag`
13070 });
13071 }
13072 parser.eat(expected, true);
13073 parser.allow_whitespace();
13074 parser.eat('}', true);
13075 while (block.elseif) {
13076 block.end = parser.index;
13077 parser.stack.pop();
13078 block = parser.current();
13079 if (block.else) {
13080 block.else.end = start;
13081 }
13082 }
13083 // strip leading/trailing whitespace as necessary
13084 const char_before = parser.template[block.start - 1];
13085 const char_after = parser.template[parser.index];
13086 const trim_before = !char_before || whitespace.test(char_before);
13087 const trim_after = !char_after || whitespace.test(char_after);
13088 trim_whitespace(block, trim_before, trim_after);
13089 block.end = parser.index;
13090 parser.stack.pop();
13091 }
13092 else if (parser.eat(':else')) {
13093 if (parser.eat('if')) {
13094 parser.error({
13095 code: 'invalid-elseif',
13096 message: `'elseif' should be 'else if'`
13097 });
13098 }
13099 parser.allow_whitespace();
13100 // :else if
13101 if (parser.eat('if')) {
13102 const block = parser.current();
13103 if (block.type !== 'IfBlock')
13104 parser.error({
13105 code: `invalid-elseif-placement`,
13106 message: 'Cannot have an {:else if ...} block outside an {#if ...} block'
13107 });
13108 parser.require_whitespace();
13109 const expression = read_expression(parser);
13110 parser.allow_whitespace();
13111 parser.eat('}', true);
13112 block.else = {
13113 start: parser.index,
13114 end: null,
13115 type: 'ElseBlock',
13116 children: [
13117 {
13118 start: parser.index,
13119 end: null,
13120 type: 'IfBlock',
13121 elseif: true,
13122 expression,
13123 children: [],
13124 },
13125 ],
13126 };
13127 parser.stack.push(block.else.children[0]);
13128 }
13129 // :else
13130 else {
13131 const block = parser.current();
13132 if (block.type !== 'IfBlock' && block.type !== 'EachBlock') {
13133 parser.error({
13134 code: `invalid-else-placement`,
13135 message: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block'
13136 });
13137 }
13138 parser.allow_whitespace();
13139 parser.eat('}', true);
13140 block.else = {
13141 start: parser.index,
13142 end: null,
13143 type: 'ElseBlock',
13144 children: [],
13145 };
13146 parser.stack.push(block.else);
13147 }
13148 }
13149 else if (parser.eat(':then')) {
13150 // TODO DRY out this and the next section
13151 const pending_block = parser.current();
13152 if (pending_block.type === 'PendingBlock') {
13153 pending_block.end = start;
13154 parser.stack.pop();
13155 const await_block = parser.current();
13156 if (!parser.eat('}')) {
13157 parser.require_whitespace();
13158 await_block.value = parser.read_identifier();
13159 parser.allow_whitespace();
13160 parser.eat('}', true);
13161 }
13162 const then_block = {
13163 start,
13164 end: null,
13165 type: 'ThenBlock',
13166 children: [],
13167 skip: false
13168 };
13169 await_block.then = then_block;
13170 parser.stack.push(then_block);
13171 }
13172 }
13173 else if (parser.eat(':catch')) {
13174 const then_block = parser.current();
13175 if (then_block.type === 'ThenBlock') {
13176 then_block.end = start;
13177 parser.stack.pop();
13178 const await_block = parser.current();
13179 if (!parser.eat('}')) {
13180 parser.require_whitespace();
13181 await_block.error = parser.read_identifier();
13182 parser.allow_whitespace();
13183 parser.eat('}', true);
13184 }
13185 const catch_block = {
13186 start,
13187 end: null,
13188 type: 'CatchBlock',
13189 children: [],
13190 skip: false
13191 };
13192 await_block.catch = catch_block;
13193 parser.stack.push(catch_block);
13194 }
13195 }
13196 else if (parser.eat('#')) {
13197 // {#if foo}, {#each foo} or {#await foo}
13198 let type;
13199 if (parser.eat('if')) {
13200 type = 'IfBlock';
13201 }
13202 else if (parser.eat('each')) {
13203 type = 'EachBlock';
13204 }
13205 else if (parser.eat('await')) {
13206 type = 'AwaitBlock';
13207 }
13208 else {
13209 parser.error({
13210 code: `expected-block-type`,
13211 message: `Expected if, each or await`
13212 });
13213 }
13214 parser.require_whitespace();
13215 const expression = read_expression(parser);
13216 const block = type === 'AwaitBlock' ?
13217 {
13218 start,
13219 end: null,
13220 type,
13221 expression,
13222 value: null,
13223 error: null,
13224 pending: {
13225 start: null,
13226 end: null,
13227 type: 'PendingBlock',
13228 children: [],
13229 skip: true
13230 },
13231 then: {
13232 start: null,
13233 end: null,
13234 type: 'ThenBlock',
13235 children: [],
13236 skip: true
13237 },
13238 catch: {
13239 start: null,
13240 end: null,
13241 type: 'CatchBlock',
13242 children: [],
13243 skip: true
13244 },
13245 } :
13246 {
13247 start,
13248 end: null,
13249 type,
13250 expression,
13251 children: [],
13252 };
13253 parser.allow_whitespace();
13254 // {#each} blocks must declare a context – {#each list as item}
13255 if (type === 'EachBlock') {
13256 parser.eat('as', true);
13257 parser.require_whitespace();
13258 block.context = read_context(parser);
13259 parser.allow_whitespace();
13260 if (parser.eat(',')) {
13261 parser.allow_whitespace();
13262 block.index = parser.read_identifier();
13263 if (!block.index)
13264 parser.error({
13265 code: `expected-name`,
13266 message: `Expected name`
13267 });
13268 parser.allow_whitespace();
13269 }
13270 if (parser.eat('(')) {
13271 parser.allow_whitespace();
13272 block.key = read_expression(parser);
13273 parser.allow_whitespace();
13274 parser.eat(')', true);
13275 parser.allow_whitespace();
13276 }
13277 }
13278 const await_block_shorthand = type === 'AwaitBlock' && parser.eat('then');
13279 if (await_block_shorthand) {
13280 parser.require_whitespace();
13281 block.value = parser.read_identifier();
13282 parser.allow_whitespace();
13283 }
13284 parser.eat('}', true);
13285 parser.current().children.push(block);
13286 parser.stack.push(block);
13287 if (type === 'AwaitBlock') {
13288 let child_block;
13289 if (await_block_shorthand) {
13290 block.then.skip = false;
13291 child_block = block.then;
13292 }
13293 else {
13294 block.pending.skip = false;
13295 child_block = block.pending;
13296 }
13297 child_block.start = parser.index;
13298 parser.stack.push(child_block);
13299 }
13300 }
13301 else if (parser.eat('@html')) {
13302 // {@html content} tag
13303 parser.require_whitespace();
13304 const expression = read_expression(parser);
13305 parser.allow_whitespace();
13306 parser.eat('}', true);
13307 parser.current().children.push({
13308 start,
13309 end: parser.index,
13310 type: 'RawMustacheTag',
13311 expression,
13312 });
13313 }
13314 else if (parser.eat('@debug')) {
13315 let identifiers;
13316 // Implies {@debug} which indicates "debug all"
13317 if (parser.read(/\s*}/)) {
13318 identifiers = [];
13319 }
13320 else {
13321 const expression = read_expression(parser);
13322 identifiers = expression.type === 'SequenceExpression'
13323 ? expression.expressions
13324 : [expression];
13325 identifiers.forEach(node => {
13326 if (node.type !== 'Identifier') {
13327 parser.error({
13328 code: 'invalid-debug-args',
13329 message: '{@debug ...} arguments must be identifiers, not arbitrary expressions'
13330 }, node.start);
13331 }
13332 });
13333 parser.allow_whitespace();
13334 parser.eat('}', true);
13335 }
13336 parser.current().children.push({
13337 start,
13338 end: parser.index,
13339 type: 'DebugTag',
13340 identifiers
13341 });
13342 }
13343 else {
13344 const expression = read_expression(parser);
13345 parser.allow_whitespace();
13346 parser.eat('}', true);
13347 parser.current().children.push({
13348 start,
13349 end: parser.index,
13350 type: 'MustacheTag',
13351 expression,
13352 });
13353 }
13354 }
13355
13356 function text(parser) {
13357 const start = parser.index;
13358 let data = '';
13359 while (parser.index < parser.template.length &&
13360 !parser.match('<') &&
13361 !parser.match('{')) {
13362 data += parser.template[parser.index++];
13363 }
13364 const node = {
13365 start,
13366 end: parser.index,
13367 type: 'Text',
13368 raw: data,
13369 data: decode_character_references(data),
13370 };
13371 parser.current().children.push(node);
13372 }
13373
13374 function fragment(parser) {
13375 if (parser.match('<')) {
13376 return tag;
13377 }
13378 if (parser.match('{')) {
13379 return mustache;
13380 }
13381 return text;
13382 }
13383
13384 function getLocator(source, options) {
13385 if (options === void 0) { options = {}; }
13386 var offsetLine = options.offsetLine || 0;
13387 var offsetColumn = options.offsetColumn || 0;
13388 var originalLines = source.split('\n');
13389 var start = 0;
13390 var lineRanges = originalLines.map(function (line, i) {
13391 var end = start + line.length + 1;
13392 var range = { start: start, end: end, line: i };
13393 start = end;
13394 return range;
13395 });
13396 var i = 0;
13397 function rangeContains(range, index) {
13398 return range.start <= index && index < range.end;
13399 }
13400 function getLocation(range, index) {
13401 return { line: offsetLine + range.line, column: offsetColumn + index - range.start, character: index };
13402 }
13403 function locate(search, startIndex) {
13404 if (typeof search === 'string') {
13405 search = source.indexOf(search, startIndex || 0);
13406 }
13407 var range = lineRanges[i];
13408 var d = search >= range.end ? 1 : -1;
13409 while (range) {
13410 if (rangeContains(range, search))
13411 return getLocation(range, search);
13412 i += d;
13413 range = lineRanges[i];
13414 }
13415 }
13416 return locate;
13417 }
13418 function locate(source, search, options) {
13419 if (typeof options === 'number') {
13420 throw new Error('locate takes a { startIndex, offsetLine, offsetColumn } object as the third argument');
13421 }
13422 return getLocator(source, options)(search, options && options.startIndex);
13423 }
13424
13425 function tabs_to_spaces(str) {
13426 return str.replace(/^\t+/, match => match.split('\t').join(' '));
13427 }
13428 function get_code_frame(source, line, column) {
13429 const lines = source.split('\n');
13430 const frame_start = Math.max(0, line - 2);
13431 const frame_end = Math.min(line + 3, lines.length);
13432 const digits = String(frame_end + 1).length;
13433 return lines
13434 .slice(frame_start, frame_end)
13435 .map((str, i) => {
13436 const isErrorLine = frame_start + i === line;
13437 let line_num = String(i + frame_start + 1);
13438 while (line_num.length < digits)
13439 line_num = ` ${line_num}`;
13440 if (isErrorLine) {
13441 const indicator = repeat(' ', digits + 2 + tabs_to_spaces(str.slice(0, column)).length) + '^';
13442 return `${line_num}: ${tabs_to_spaces(str)}\n${indicator}`;
13443 }
13444 return `${line_num}: ${tabs_to_spaces(str)}`;
13445 })
13446 .join('\n');
13447 }
13448
13449 class CompileError extends Error {
13450 toString() {
13451 return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`;
13452 }
13453 }
13454 function error$1(message, props) {
13455 const error = new CompileError(message);
13456 error.name = props.name;
13457 const start = locate(props.source, props.start, { offsetLine: 1 });
13458 const end = locate(props.source, props.end || props.start, { offsetLine: 1 });
13459 error.code = props.code;
13460 error.start = start;
13461 error.end = end;
13462 error.pos = props.start;
13463 error.filename = props.filename;
13464 error.frame = get_code_frame(props.source, start.line - 1, start.column);
13465 throw error;
13466 }
13467
13468 class Parser$2 {
13469 constructor(template, options) {
13470 this.index = 0;
13471 this.stack = [];
13472 this.css = [];
13473 this.js = [];
13474 this.meta_tags = {};
13475 if (typeof template !== 'string') {
13476 throw new TypeError('Template must be a string');
13477 }
13478 this.template = template.replace(/\s+$/, '');
13479 this.filename = options.filename;
13480 this.customElement = options.customElement;
13481 this.html = {
13482 start: null,
13483 end: null,
13484 type: 'Fragment',
13485 children: [],
13486 };
13487 this.stack.push(this.html);
13488 let state = fragment;
13489 while (this.index < this.template.length) {
13490 state = state(this) || fragment;
13491 }
13492 if (this.stack.length > 1) {
13493 const current = this.current();
13494 const type = current.type === 'Element' ? `<${current.name}>` : 'Block';
13495 const slug = current.type === 'Element' ? 'element' : 'block';
13496 this.error({
13497 code: `unclosed-${slug}`,
13498 message: `${type} was left open`
13499 }, current.start);
13500 }
13501 if (state !== fragment) {
13502 this.error({
13503 code: `unexpected-eof`,
13504 message: 'Unexpected end of input'
13505 });
13506 }
13507 if (this.html.children.length) {
13508 let start = this.html.children[0] && this.html.children[0].start;
13509 while (/\s/.test(template[start]))
13510 start += 1;
13511 let end = this.html.children[this.html.children.length - 1] && this.html.children[this.html.children.length - 1].end;
13512 while (/\s/.test(template[end - 1]))
13513 end -= 1;
13514 this.html.start = start;
13515 this.html.end = end;
13516 }
13517 else {
13518 this.html.start = this.html.end = null;
13519 }
13520 }
13521 current() {
13522 return this.stack[this.stack.length - 1];
13523 }
13524 acorn_error(err) {
13525 this.error({
13526 code: `parse-error`,
13527 message: err.message.replace(/ \(\d+:\d+\)$/, '')
13528 }, err.pos);
13529 }
13530 error({ code, message }, index = this.index) {
13531 error$1(message, {
13532 name: 'ParseError',
13533 code,
13534 source: this.template,
13535 start: index,
13536 filename: this.filename
13537 });
13538 }
13539 eat(str, required, message) {
13540 if (this.match(str)) {
13541 this.index += str.length;
13542 return true;
13543 }
13544 if (required) {
13545 this.error({
13546 code: `unexpected-${this.index === this.template.length ? 'eof' : 'token'}`,
13547 message: message || `Expected ${str}`
13548 });
13549 }
13550 return false;
13551 }
13552 match(str) {
13553 return this.template.slice(this.index, this.index + str.length) === str;
13554 }
13555 match_regex(pattern) {
13556 const match = pattern.exec(this.template.slice(this.index));
13557 if (!match || match.index !== 0)
13558 return null;
13559 return match[0];
13560 }
13561 allow_whitespace() {
13562 while (this.index < this.template.length &&
13563 whitespace.test(this.template[this.index])) {
13564 this.index++;
13565 }
13566 }
13567 read(pattern) {
13568 const result = this.match_regex(pattern);
13569 if (result)
13570 this.index += result.length;
13571 return result;
13572 }
13573 read_identifier() {
13574 const start = this.index;
13575 let i = this.index;
13576 const code = full_char_code_at(this.template, i);
13577 if (!isIdentifierStart(code, true))
13578 return null;
13579 i += code <= 0xffff ? 1 : 2;
13580 while (i < this.template.length) {
13581 const code = full_char_code_at(this.template, i);
13582 if (!isIdentifierChar(code, true))
13583 break;
13584 i += code <= 0xffff ? 1 : 2;
13585 }
13586 const identifier = this.template.slice(this.index, this.index = i);
13587 if (reserved.has(identifier)) {
13588 this.error({
13589 code: `unexpected-reserved-word`,
13590 message: `'${identifier}' is a reserved word in JavaScript and cannot be used here`
13591 }, start);
13592 }
13593 return identifier;
13594 }
13595 read_until(pattern) {
13596 if (this.index >= this.template.length)
13597 this.error({
13598 code: `unexpected-eof`,
13599 message: 'Unexpected end of input'
13600 });
13601 const start = this.index;
13602 const match = pattern.exec(this.template.slice(start));
13603 if (match) {
13604 this.index = start + match.index;
13605 return this.template.slice(start, this.index);
13606 }
13607 this.index = this.template.length;
13608 return this.template.slice(start);
13609 }
13610 require_whitespace() {
13611 if (!whitespace.test(this.template[this.index])) {
13612 this.error({
13613 code: `missing-whitespace`,
13614 message: `Expected whitespace`
13615 });
13616 }
13617 this.allow_whitespace();
13618 }
13619 }
13620 function parse$2(template, options = {}) {
13621 const parser = new Parser$2(template, options);
13622 // TODO we way want to allow multiple <style> tags —
13623 // one scoped, one global. for now, only allow one
13624 if (parser.css.length > 1) {
13625 parser.error({
13626 code: 'duplicate-style',
13627 message: 'You can only have one top-level <style> tag per component'
13628 }, parser.css[1].start);
13629 }
13630 const instance_scripts = parser.js.filter(script => script.context === 'default');
13631 const module_scripts = parser.js.filter(script => script.context === 'module');
13632 if (instance_scripts.length > 1) {
13633 parser.error({
13634 code: `invalid-script`,
13635 message: `A component can only have one instance-level <script> element`
13636 }, instance_scripts[1].start);
13637 }
13638 if (module_scripts.length > 1) {
13639 parser.error({
13640 code: `invalid-script`,
13641 message: `A component can only have one <script context="module"> element`
13642 }, module_scripts[1].start);
13643 }
13644 return {
13645 html: parser.html,
13646 css: parser.css[0],
13647 instance: instance_scripts[0],
13648 module: module_scripts[0]
13649 };
13650 }
13651
13652 const start = /\n(\t+)/;
13653 function deindent(strings, ...values) {
13654 const indentation = start.exec(strings[0])[1];
13655 const pattern = new RegExp(`^${indentation}`, 'gm');
13656 let result = strings[0].replace(start, '').replace(pattern, '');
13657 let current_indentation = get_current_indentation(result);
13658 for (let i = 1; i < strings.length; i += 1) {
13659 let expression = values[i - 1];
13660 const string = strings[i].replace(pattern, '');
13661 if (Array.isArray(expression)) {
13662 expression = expression.length ? expression.join('\n') : null;
13663 }
13664 // discard empty codebuilders
13665 if (expression && expression.is_empty && expression.is_empty()) {
13666 expression = null;
13667 }
13668 if (expression || expression === '') {
13669 const value = String(expression).replace(/\n/g, `\n${current_indentation}`);
13670 result += value + string;
13671 }
13672 else {
13673 let c = result.length;
13674 while (/\s/.test(result[c - 1]))
13675 c -= 1;
13676 result = result.slice(0, c) + string;
13677 }
13678 current_indentation = get_current_indentation(result);
13679 }
13680 return result.trim().replace(/\t+$/gm, '').replace(/{\n\n/gm, '{\n');
13681 }
13682 function get_current_indentation(str) {
13683 let a = str.length;
13684 while (a > 0 && str[a - 1] !== '\n')
13685 a -= 1;
13686 let b = a;
13687 while (b < str.length && /\s/.test(str[b]))
13688 b += 1;
13689 return str.slice(a, b);
13690 }
13691
13692 function stringify(data, options = {}) {
13693 return JSON.stringify(escape(data, options));
13694 }
13695 function escape(data, { only_escape_at_symbol = false } = {}) {
13696 return data.replace(only_escape_at_symbol ? /@+/g : /(@+|#+)/g, (match) => {
13697 return match + match[0];
13698 });
13699 }
13700 const escaped = {
13701 '&': '&amp;',
13702 '<': '&lt;',
13703 '>': '&gt;',
13704 };
13705 function escape_html(html) {
13706 return String(html).replace(/[&<>]/g, match => escaped[match]);
13707 }
13708 function escape_template(str) {
13709 return str.replace(/(\${|`|\\)/g, '\\$1');
13710 }
13711
13712 const whitespace$1 = /^\s+$/;
13713 class CodeBuilder {
13714 constructor(str = '') {
13715 this.root = { type: 'root', children: [], parent: null };
13716 this.current = this.last = this.root;
13717 this.add_line(str);
13718 }
13719 add_conditional(condition, body) {
13720 if (this.last.type === 'condition' && this.last.condition === condition) {
13721 if (body && !whitespace$1.test(body))
13722 this.last.children.push({ type: 'line', line: body });
13723 }
13724 else {
13725 const next = this.last = { type: 'condition', condition, parent: this.current, children: [] };
13726 this.current.children.push(next);
13727 if (body && !whitespace$1.test(body))
13728 next.children.push({ type: 'line', line: body });
13729 }
13730 }
13731 add_line(line) {
13732 if (line && !whitespace$1.test(line))
13733 this.current.children.push(this.last = { type: 'line', line });
13734 }
13735 add_block(block) {
13736 if (block && !whitespace$1.test(block))
13737 this.current.children.push(this.last = { type: 'line', line: block, block: true });
13738 }
13739 is_empty() { return !find_line(this.root); }
13740 push_condition(condition) {
13741 if (this.last.type === 'condition' && this.last.condition === condition) {
13742 this.current = this.last;
13743 }
13744 else {
13745 const next = this.last = { type: 'condition', condition, parent: this.current, children: [] };
13746 this.current.children.push(next);
13747 this.current = next;
13748 }
13749 }
13750 pop_condition() {
13751 if (!this.current.parent)
13752 throw new Error(`Popping a condition that maybe wasn't pushed.`);
13753 this.current = this.current.parent;
13754 }
13755 toString() {
13756 return chunk_to_string(this.root);
13757 }
13758 }
13759 function find_line(chunk) {
13760 for (const c of chunk.children) {
13761 if (c.type === 'line' || find_line(c))
13762 return true;
13763 }
13764 return false;
13765 }
13766 function chunk_to_string(chunk, level = 0, last_block, first) {
13767 if (chunk.type === 'line') {
13768 return `${last_block || (!first && chunk.block) ? '\n' : ''}${chunk.line.replace(/^/gm, repeat('\t', level))}`;
13769 }
13770 else if (chunk.type === 'condition') {
13771 let t = false;
13772 const lines = chunk.children.map((c, i) => {
13773 const str = chunk_to_string(c, level + 1, t, i === 0);
13774 t = c.type !== 'line' || c.block;
13775 return str;
13776 }).filter(l => !!l);
13777 if (!lines.length)
13778 return '';
13779 return `${last_block || (!first) ? '\n' : ''}${repeat('\t', level)}if (${chunk.condition}) {\n${lines.join('\n')}\n${repeat('\t', level)}}`;
13780 }
13781 else if (chunk.type === 'root') {
13782 let t = false;
13783 const lines = chunk.children.map((c, i) => {
13784 const str = chunk_to_string(c, 0, t, i === 0);
13785 t = c.type !== 'line' || c.block;
13786 return str;
13787 }).filter(l => !!l);
13788 if (!lines.length)
13789 return '';
13790 return lines.join('\n');
13791 }
13792 }
13793
13794 class Block$1 {
13795 constructor(options) {
13796 this.event_listeners = [];
13797 this.has_update_method = false;
13798 this.parent = options.parent;
13799 this.renderer = options.renderer;
13800 this.name = options.name;
13801 this.comment = options.comment;
13802 this.wrappers = [];
13803 // for keyed each blocks
13804 this.key = options.key;
13805 this.first = null;
13806 this.dependencies = new Set();
13807 this.bindings = options.bindings;
13808 this.builders = {
13809 init: new CodeBuilder(),
13810 create: new CodeBuilder(),
13811 claim: new CodeBuilder(),
13812 hydrate: new CodeBuilder(),
13813 mount: new CodeBuilder(),
13814 measure: new CodeBuilder(),
13815 fix: new CodeBuilder(),
13816 animate: new CodeBuilder(),
13817 intro: new CodeBuilder(),
13818 update: new CodeBuilder(),
13819 outro: new CodeBuilder(),
13820 destroy: new CodeBuilder(),
13821 };
13822 this.has_animation = false;
13823 this.has_intro_method = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros
13824 this.has_outro_method = false;
13825 this.outros = 0;
13826 this.get_unique_name = this.renderer.component.get_unique_name_maker();
13827 this.variables = new Map();
13828 this.aliases = new Map().set('ctx', this.get_unique_name('ctx'));
13829 if (this.key)
13830 this.aliases.set('key', this.get_unique_name('key'));
13831 }
13832 assign_variable_names() {
13833 const seen = new Set();
13834 const dupes = new Set();
13835 let i = this.wrappers.length;
13836 while (i--) {
13837 const wrapper = this.wrappers[i];
13838 if (!wrapper.var)
13839 continue;
13840 if (wrapper.parent && wrapper.parent.can_use_innerhtml)
13841 continue;
13842 if (seen.has(wrapper.var)) {
13843 dupes.add(wrapper.var);
13844 }
13845 seen.add(wrapper.var);
13846 }
13847 const counts = new Map();
13848 i = this.wrappers.length;
13849 while (i--) {
13850 const wrapper = this.wrappers[i];
13851 if (!wrapper.var)
13852 continue;
13853 if (dupes.has(wrapper.var)) {
13854 const i = counts.get(wrapper.var) || 0;
13855 counts.set(wrapper.var, i + 1);
13856 wrapper.var = this.get_unique_name(wrapper.var + i);
13857 }
13858 else {
13859 wrapper.var = this.get_unique_name(wrapper.var);
13860 }
13861 }
13862 }
13863 add_dependencies(dependencies) {
13864 dependencies.forEach(dependency => {
13865 this.dependencies.add(dependency);
13866 });
13867 this.has_update_method = true;
13868 }
13869 add_element(name, render_statement, claim_statement, parent_node, no_detach) {
13870 this.add_variable(name);
13871 this.builders.create.add_line(`${name} = ${render_statement};`);
13872 if (this.renderer.options.hydratable) {
13873 this.builders.claim.add_line(`${name} = ${claim_statement || render_statement};`);
13874 }
13875 if (parent_node) {
13876 this.builders.mount.add_line(`@append(${parent_node}, ${name});`);
13877 if (parent_node === '@_document.head' && !no_detach)
13878 this.builders.destroy.add_line(`@detach(${name});`);
13879 }
13880 else {
13881 this.builders.mount.add_line(`@insert(#target, ${name}, anchor);`);
13882 if (!no_detach)
13883 this.builders.destroy.add_conditional('detaching', `@detach(${name});`);
13884 }
13885 }
13886 add_intro(local) {
13887 this.has_intros = this.has_intro_method = true;
13888 if (!local && this.parent)
13889 this.parent.add_intro();
13890 }
13891 add_outro(local) {
13892 this.has_outros = this.has_outro_method = true;
13893 this.outros += 1;
13894 if (!local && this.parent)
13895 this.parent.add_outro();
13896 }
13897 add_animation() {
13898 this.has_animation = true;
13899 }
13900 add_variable(name, init) {
13901 if (name[0] === '#') {
13902 name = this.alias(name.slice(1));
13903 }
13904 if (this.variables.has(name) && this.variables.get(name) !== init) {
13905 throw new Error(`Variable '${name}' already initialised with a different value`);
13906 }
13907 this.variables.set(name, init);
13908 }
13909 alias(name) {
13910 if (!this.aliases.has(name)) {
13911 this.aliases.set(name, this.get_unique_name(name));
13912 }
13913 return this.aliases.get(name);
13914 }
13915 child(options) {
13916 return new Block$1(Object.assign({}, this, { key: null }, options, { parent: this }));
13917 }
13918 get_contents(local_key) {
13919 const { dev } = this.renderer.options;
13920 if (this.has_outros) {
13921 this.add_variable('#current');
13922 if (!this.builders.intro.is_empty()) {
13923 this.builders.intro.add_line(`#current = true;`);
13924 this.builders.mount.add_line(`#current = true;`);
13925 }
13926 if (!this.builders.outro.is_empty()) {
13927 this.builders.outro.add_line(`#current = false;`);
13928 }
13929 }
13930 if (this.autofocus) {
13931 this.builders.mount.add_line(`${this.autofocus}.focus();`);
13932 }
13933 this.render_listeners();
13934 const properties = new CodeBuilder();
13935 const method_name = (short, long) => dev ? `${short}: function ${this.get_unique_name(long)}` : short;
13936 if (local_key) {
13937 properties.add_block(`key: ${local_key},`);
13938 }
13939 if (this.first) {
13940 properties.add_block(`first: null,`);
13941 this.builders.hydrate.add_line(`this.first = ${this.first};`);
13942 }
13943 if (this.builders.create.is_empty() && this.builders.hydrate.is_empty()) {
13944 properties.add_line(`c: @noop,`);
13945 }
13946 else {
13947 const hydrate = !this.builders.hydrate.is_empty() && (this.renderer.options.hydratable
13948 ? `this.h()`
13949 : this.builders.hydrate);
13950 properties.add_block(deindent `
13951 ${method_name('c', 'create')}() {
13952 ${this.builders.create}
13953 ${hydrate}
13954 },
13955 `);
13956 }
13957 if (this.renderer.options.hydratable || !this.builders.claim.is_empty()) {
13958 if (this.builders.claim.is_empty() && this.builders.hydrate.is_empty()) {
13959 properties.add_line(`l: @noop,`);
13960 }
13961 else {
13962 properties.add_block(deindent `
13963 ${method_name('l', 'claim')}(nodes) {
13964 ${this.builders.claim}
13965 ${this.renderer.options.hydratable && !this.builders.hydrate.is_empty() && `this.h();`}
13966 },
13967 `);
13968 }
13969 }
13970 if (this.renderer.options.hydratable && !this.builders.hydrate.is_empty()) {
13971 properties.add_block(deindent `
13972 ${method_name('h', 'hydrate')}() {
13973 ${this.builders.hydrate}
13974 },
13975 `);
13976 }
13977 if (this.builders.mount.is_empty()) {
13978 properties.add_line(`m: @noop,`);
13979 }
13980 else {
13981 properties.add_block(deindent `
13982 ${method_name('m', 'mount')}(#target, anchor) {
13983 ${this.builders.mount}
13984 },
13985 `);
13986 }
13987 if (this.has_update_method || this.maintain_context) {
13988 if (this.builders.update.is_empty() && !this.maintain_context) {
13989 properties.add_line(`p: @noop,`);
13990 }
13991 else {
13992 properties.add_block(deindent `
13993 ${method_name('p', 'update')}(changed, ${this.maintain_context ? 'new_ctx' : 'ctx'}) {
13994 ${this.maintain_context && `ctx = new_ctx;`}
13995 ${this.builders.update}
13996 },
13997 `);
13998 }
13999 }
14000 if (this.has_animation) {
14001 properties.add_block(deindent `
14002 ${method_name('r', 'measure')}() {
14003 ${this.builders.measure}
14004 },
14005
14006 ${method_name('f', 'fix')}() {
14007 ${this.builders.fix}
14008 },
14009
14010 ${method_name('a', 'animate')}() {
14011 ${this.builders.animate}
14012 },
14013 `);
14014 }
14015 if (this.has_intro_method || this.has_outro_method) {
14016 if (this.builders.intro.is_empty()) {
14017 properties.add_line(`i: @noop,`);
14018 }
14019 else {
14020 properties.add_block(deindent `
14021 ${method_name('i', 'intro')}(#local) {
14022 ${this.has_outros && `if (#current) return;`}
14023 ${this.builders.intro}
14024 },
14025 `);
14026 }
14027 if (this.builders.outro.is_empty()) {
14028 properties.add_line(`o: @noop,`);
14029 }
14030 else {
14031 properties.add_block(deindent `
14032 ${method_name('o', 'outro')}(#local) {
14033 ${this.builders.outro}
14034 },
14035 `);
14036 }
14037 }
14038 if (this.builders.destroy.is_empty()) {
14039 properties.add_line(`d: @noop`);
14040 }
14041 else {
14042 properties.add_block(deindent `
14043 ${method_name('d', 'destroy')}(detaching) {
14044 ${this.builders.destroy}
14045 }
14046 `);
14047 }
14048 /* eslint-disable @typescript-eslint/indent,indent */
14049 return deindent `
14050 ${this.variables.size > 0 &&
14051 `var ${Array.from(this.variables.keys())
14052 .map(key => {
14053 const init = this.variables.get(key);
14054 return init !== undefined ? `${key} = ${init}` : key;
14055 })
14056 .join(', ')};`}
14057
14058 ${!this.builders.init.is_empty() && this.builders.init}
14059
14060 return {
14061 ${properties}
14062 };
14063 `.replace(/(#+)(\w*)/g, (_match, sigil, name) => {
14064 return sigil === '#' ? this.alias(name) : sigil.slice(1) + name;
14065 });
14066 /* eslint-enable @typescript-eslint/indent,indent */
14067 }
14068 render_listeners(chunk = '') {
14069 if (this.event_listeners.length > 0) {
14070 this.add_variable(`#dispose${chunk}`);
14071 if (this.event_listeners.length === 1) {
14072 this.builders.hydrate.add_line(`#dispose${chunk} = ${this.event_listeners[0]};`);
14073 this.builders.destroy.add_line(`#dispose${chunk}();`);
14074 }
14075 else {
14076 this.builders.hydrate.add_block(deindent `
14077 #dispose${chunk} = [
14078 ${this.event_listeners.join(',\n')}
14079 ];
14080 `);
14081 this.builders.destroy.add_line(`@run_all(#dispose${chunk});`);
14082 }
14083 }
14084 }
14085 toString() {
14086 const local_key = this.key && this.get_unique_name('key');
14087 return deindent `
14088 ${this.comment && `// ${escape(this.comment, { only_escape_at_symbol: true })}`}
14089 function ${this.name}(${this.key ? `${local_key}, ` : ''}ctx) {
14090 ${this.get_contents(local_key)}
14091 }
14092 `;
14093 }
14094 }
14095
14096 class Wrapper {
14097 constructor(renderer, block, parent, node) {
14098 this.node = node;
14099 // make these non-enumerable so that they can be logged sensibly
14100 // (TODO in dev only?)
14101 Object.defineProperties(this, {
14102 renderer: {
14103 value: renderer
14104 },
14105 parent: {
14106 value: parent
14107 }
14108 });
14109 this.can_use_innerhtml = !renderer.options.hydratable;
14110 block.wrappers.push(this);
14111 }
14112 cannot_use_innerhtml() {
14113 this.can_use_innerhtml = false;
14114 if (this.parent)
14115 this.parent.cannot_use_innerhtml();
14116 }
14117 get_or_create_anchor(block, parent_node, parent_nodes) {
14118 // TODO use this in EachBlock and IfBlock — tricky because
14119 // children need to be created first
14120 const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node();
14121 const anchor = needs_anchor
14122 ? block.get_unique_name(`${this.var}_anchor`)
14123 : (this.next && this.next.var) || 'null';
14124 if (needs_anchor) {
14125 block.add_element(anchor, `@empty()`, parent_nodes && `@empty()`, parent_node);
14126 }
14127 return anchor;
14128 }
14129 get_update_mount_node(anchor) {
14130 return (this.parent && this.parent.is_dom_node())
14131 ? this.parent.var
14132 : `${anchor}.parentNode`;
14133 }
14134 is_dom_node() {
14135 return (this.node.type === 'Element' ||
14136 this.node.type === 'Text' ||
14137 this.node.type === 'MustacheTag');
14138 }
14139 render(_block, _parent_node, _parent_nodes) {
14140 throw Error('Wrapper class is not renderable');
14141 }
14142 }
14143
14144 function create_debugging_comment(node, component) {
14145 const { locate, source } = component;
14146 let c = node.start;
14147 if (node.type === 'ElseBlock') {
14148 while (source[c - 1] !== '{')
14149 c -= 1;
14150 while (source[c - 1] === '{')
14151 c -= 1;
14152 }
14153 let d;
14154 if (node.type === 'InlineComponent' || node.type === 'Element') {
14155 d = node.children.length ? node.children[0].start : node.start;
14156 while (source[d - 1] !== '>')
14157 d -= 1;
14158 }
14159 else {
14160 // @ts-ignore
14161 d = node.expression ? node.expression.node.end : c;
14162 while (source[d] !== '}')
14163 d += 1;
14164 while (source[d] === '}')
14165 d += 1;
14166 }
14167 const start = locate(c);
14168 const loc = `(${start.line + 1}:${start.column})`;
14169 return `${loc} ${source.slice(c, d)}`.replace(/\s/g, ' ');
14170 }
14171
14172 class AwaitBlockBranch extends Wrapper {
14173 constructor(status, renderer, block, parent, node, strip_whitespace, next_sibling) {
14174 super(renderer, block, parent, node);
14175 this.var = null;
14176 this.block = block.child({
14177 comment: create_debugging_comment(node, this.renderer.component),
14178 name: this.renderer.component.get_unique_name(`create_${status}_block`)
14179 });
14180 this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, strip_whitespace, next_sibling);
14181 this.is_dynamic = this.block.dependencies.size > 0;
14182 }
14183 }
14184 class AwaitBlockWrapper extends Wrapper {
14185 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
14186 super(renderer, block, parent, node);
14187 this.var = 'await_block';
14188 this.cannot_use_innerhtml();
14189 block.add_dependencies(this.node.expression.dependencies);
14190 let is_dynamic = false;
14191 let has_intros = false;
14192 let has_outros = false;
14193 ['pending', 'then', 'catch'].forEach(status => {
14194 const child = this.node[status];
14195 const branch = new AwaitBlockBranch(status, renderer, block, this, child, strip_whitespace, next_sibling);
14196 renderer.blocks.push(branch.block);
14197 if (branch.is_dynamic) {
14198 is_dynamic = true;
14199 // TODO should blocks update their own parents?
14200 block.add_dependencies(branch.block.dependencies);
14201 }
14202 if (branch.block.has_intros)
14203 has_intros = true;
14204 if (branch.block.has_outros)
14205 has_outros = true;
14206 this[status] = branch;
14207 });
14208 this.pending.block.has_update_method = is_dynamic;
14209 this.then.block.has_update_method = is_dynamic;
14210 this.catch.block.has_update_method = is_dynamic;
14211 this.pending.block.has_intro_method = has_intros;
14212 this.then.block.has_intro_method = has_intros;
14213 this.catch.block.has_intro_method = has_intros;
14214 this.pending.block.has_outro_method = has_outros;
14215 this.then.block.has_outro_method = has_outros;
14216 this.catch.block.has_outro_method = has_outros;
14217 if (has_outros) {
14218 block.add_outro();
14219 }
14220 }
14221 render(block, parent_node, parent_nodes) {
14222 const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes);
14223 const update_mount_node = this.get_update_mount_node(anchor);
14224 const snippet = this.node.expression.render(block);
14225 const info = block.get_unique_name(`info`);
14226 const promise = block.get_unique_name(`promise`);
14227 block.add_variable(promise);
14228 block.maintain_context = true;
14229 const info_props = [
14230 'ctx',
14231 'current: null',
14232 'token: null',
14233 this.pending.block.name && `pending: ${this.pending.block.name}`,
14234 this.then.block.name && `then: ${this.then.block.name}`,
14235 this.catch.block.name && `catch: ${this.catch.block.name}`,
14236 this.then.block.name && `value: '${this.node.value}'`,
14237 this.catch.block.name && `error: '${this.node.error}'`,
14238 this.pending.block.has_outro_method && `blocks: [,,,]`
14239 ].filter(Boolean);
14240 block.builders.init.add_block(deindent `
14241 let ${info} = {
14242 ${info_props.join(',\n')}
14243 };
14244 `);
14245 block.builders.init.add_block(deindent `
14246 @handle_promise(${promise} = ${snippet}, ${info});
14247 `);
14248 block.builders.create.add_block(deindent `
14249 ${info}.block.c();
14250 `);
14251 if (parent_nodes && this.renderer.options.hydratable) {
14252 block.builders.claim.add_block(deindent `
14253 ${info}.block.l(${parent_nodes});
14254 `);
14255 }
14256 const initial_mount_node = parent_node || '#target';
14257 const anchor_node = parent_node ? 'null' : 'anchor';
14258 const has_transitions = this.pending.block.has_intro_method || this.pending.block.has_outro_method;
14259 block.builders.mount.add_block(deindent `
14260 ${info}.block.m(${initial_mount_node}, ${info}.anchor = ${anchor_node});
14261 ${info}.mount = () => ${update_mount_node};
14262 ${info}.anchor = ${anchor};
14263 `);
14264 if (has_transitions) {
14265 block.builders.intro.add_line(`@transition_in(${info}.block);`);
14266 }
14267 const conditions = [];
14268 const dependencies = this.node.expression.dynamic_dependencies();
14269 if (dependencies.length > 0) {
14270 conditions.push(`(${dependencies.map(dep => `'${dep}' in changed`).join(' || ')})`);
14271 }
14272 conditions.push(`${promise} !== (${promise} = ${snippet})`, `@handle_promise(${promise}, ${info})`);
14273 block.builders.update.add_line(`${info}.ctx = ctx;`);
14274 if (this.pending.block.has_update_method) {
14275 block.builders.update.add_block(deindent `
14276 if (${conditions.join(' && ')}) {
14277 // nothing
14278 } else {
14279 ${info}.block.p(changed, @assign(@assign({}, ctx), ${info}.resolved));
14280 }
14281 `);
14282 }
14283 else {
14284 block.builders.update.add_block(deindent `
14285 ${conditions.join(' && ')}
14286 `);
14287 }
14288 if (this.pending.block.has_outro_method) {
14289 block.builders.outro.add_block(deindent `
14290 for (let #i = 0; #i < 3; #i += 1) {
14291 const block = ${info}.blocks[#i];
14292 @transition_out(block);
14293 }
14294 `);
14295 }
14296 block.builders.destroy.add_block(deindent `
14297 ${info}.block.d(${parent_node ? '' : 'detaching'});
14298 ${info}.token = null;
14299 ${info} = null;
14300 `);
14301 [this.pending, this.then, this.catch].forEach(branch => {
14302 branch.fragment.render(branch.block, null, 'nodes');
14303 });
14304 }
14305 }
14306
14307 class BodyWrapper extends Wrapper {
14308 render(block, _parent_node, _parent_nodes) {
14309 this.node.handlers.forEach(handler => {
14310 const snippet = handler.render(block);
14311 block.builders.init.add_block(deindent `
14312 @_document.body.addEventListener("${handler.name}", ${snippet});
14313 `);
14314 block.builders.destroy.add_block(deindent `
14315 @_document.body.removeEventListener("${handler.name}", ${snippet});
14316 `);
14317 });
14318 }
14319 }
14320
14321 function add_to_set(a, b) {
14322 // @ts-ignore
14323 b.forEach(item => {
14324 a.add(item);
14325 });
14326 }
14327
14328 class DebugTagWrapper extends Wrapper {
14329 constructor(renderer, block, parent, node, _strip_whitespace, _next_sibling) {
14330 super(renderer, block, parent, node);
14331 }
14332 render(block, _parent_node, _parent_nodes) {
14333 const { renderer } = this;
14334 const { component } = renderer;
14335 if (!renderer.options.dev)
14336 return;
14337 const { code, var_lookup } = component;
14338 if (this.node.expressions.length === 0) {
14339 // Debug all
14340 code.overwrite(this.node.start + 1, this.node.start + 7, 'debugger', {
14341 storeName: true
14342 });
14343 const statement = `[✂${this.node.start + 1}-${this.node.start + 7}✂];`;
14344 block.builders.create.add_line(statement);
14345 block.builders.update.add_line(statement);
14346 }
14347 else {
14348 const { code } = component;
14349 code.overwrite(this.node.start + 1, this.node.start + 7, 'log', {
14350 storeName: true
14351 });
14352 const log = `[✂${this.node.start + 1}-${this.node.start + 7}✂]`;
14353 const dependencies = new Set();
14354 this.node.expressions.forEach(expression => {
14355 add_to_set(dependencies, expression.dependencies);
14356 });
14357 const condition = Array.from(dependencies).map(d => `changed.${d}`).join(' || ');
14358 const ctx_identifiers = this.node.expressions
14359 .filter(e => {
14360 const looked_up_var = var_lookup.get(e.node.name);
14361 return !(looked_up_var && looked_up_var.hoistable);
14362 })
14363 .map(e => e.node.name)
14364 .join(', ');
14365 const logged_identifiers = this.node.expressions.map(e => e.node.name).join(', ');
14366 block.builders.update.add_block(deindent `
14367 if (${condition}) {
14368 const { ${ctx_identifiers} } = ctx;
14369 @_console.${log}({ ${logged_identifiers} });
14370 debugger;
14371 }
14372 `);
14373 block.builders.create.add_block(deindent `
14374 {
14375 const { ${ctx_identifiers} } = ctx;
14376 @_console.${log}({ ${logged_identifiers} });
14377 debugger;
14378 }
14379 `);
14380 }
14381 }
14382 }
14383
14384 function new_tail() {
14385 return '%%tail_head%%';
14386 }
14387 function attach_head(head, tail) {
14388 return tail.replace('%%tail_head%%', head);
14389 }
14390
14391 class ElseBlockWrapper extends Wrapper {
14392 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
14393 super(renderer, block, parent, node);
14394 this.var = null;
14395 this.block = block.child({
14396 comment: create_debugging_comment(node, this.renderer.component),
14397 name: this.renderer.component.get_unique_name(`create_else_block`)
14398 });
14399 this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, strip_whitespace, next_sibling);
14400 this.is_dynamic = this.block.dependencies.size > 0;
14401 }
14402 }
14403 class EachBlockWrapper extends Wrapper {
14404 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
14405 super(renderer, block, parent, node);
14406 this.var = 'each';
14407 this.cannot_use_innerhtml();
14408 const { dependencies } = node.expression;
14409 block.add_dependencies(dependencies);
14410 this.block = block.child({
14411 comment: create_debugging_comment(this.node, this.renderer.component),
14412 name: renderer.component.get_unique_name('create_each_block'),
14413 // @ts-ignore todo: probably error
14414 key: node.key,
14415 bindings: new Map(block.bindings)
14416 });
14417 // TODO this seems messy
14418 this.block.has_animation = this.node.has_animation;
14419 this.index_name = this.node.index || renderer.component.get_unique_name(`${this.node.context}_index`);
14420 const fixed_length = node.expression.node.type === 'ArrayExpression' &&
14421 node.expression.node.elements.every(element => element.type !== 'SpreadElement')
14422 ? node.expression.node.elements.length
14423 : null;
14424 // hack the sourcemap, so that if data is missing the bug
14425 // is easy to find
14426 let c = this.node.start + 2;
14427 while (renderer.component.source[c] !== 'e')
14428 c += 1;
14429 renderer.component.code.overwrite(c, c + 4, 'length');
14430 const each_block_value = renderer.component.get_unique_name(`${this.var}_value`);
14431 const iterations = block.get_unique_name(`${this.var}_blocks`);
14432 this.vars = {
14433 create_each_block: this.block.name,
14434 each_block_value,
14435 get_each_context: renderer.component.get_unique_name(`get_${this.var}_context`),
14436 iterations,
14437 length: `[✂${c}-${c + 4}✂]`,
14438 // optimisation for array literal
14439 fixed_length,
14440 data_length: fixed_length === null ? `${each_block_value}.[✂${c}-${c + 4}✂]` : fixed_length,
14441 view_length: fixed_length === null ? `${iterations}.[✂${c}-${c + 4}✂]` : fixed_length
14442 };
14443 node.contexts.forEach(prop => {
14444 this.block.bindings.set(prop.key.name, {
14445 object: this.vars.each_block_value,
14446 property: this.index_name,
14447 snippet: attach_head(`${this.vars.each_block_value}[${this.index_name}]`, prop.tail)
14448 });
14449 });
14450 if (this.node.index) {
14451 this.block.get_unique_name(this.node.index); // this prevents name collisions (#1254)
14452 }
14453 renderer.blocks.push(this.block);
14454 this.fragment = new FragmentWrapper(renderer, this.block, node.children, this, strip_whitespace, next_sibling);
14455 if (this.node.else) {
14456 this.else = new ElseBlockWrapper(renderer, block, this, this.node.else, strip_whitespace, next_sibling);
14457 renderer.blocks.push(this.else.block);
14458 if (this.else.is_dynamic) {
14459 this.block.add_dependencies(this.else.block.dependencies);
14460 }
14461 }
14462 block.add_dependencies(this.block.dependencies);
14463 if (this.block.has_outros || (this.else && this.else.block.has_outros)) {
14464 block.add_outro();
14465 }
14466 }
14467 render(block, parent_node, parent_nodes) {
14468 if (this.fragment.nodes.length === 0)
14469 return;
14470 const { renderer } = this;
14471 const { component } = renderer;
14472 const needs_anchor = this.next
14473 ? !this.next.is_dom_node() :
14474 !parent_node || !this.parent.is_dom_node();
14475 this.context_props = this.node.contexts.map(prop => `child_ctx.${prop.key.name} = ${attach_head('list[i]', prop.tail)};`);
14476 if (this.node.has_binding)
14477 this.context_props.push(`child_ctx.${this.vars.each_block_value} = list;`);
14478 if (this.node.has_binding || this.node.index)
14479 this.context_props.push(`child_ctx.${this.index_name} = i;`);
14480 const snippet = this.node.expression.render(block);
14481 block.builders.init.add_line(`var ${this.vars.each_block_value} = ${snippet};`);
14482 renderer.blocks.push(deindent `
14483 function ${this.vars.get_each_context}(ctx, list, i) {
14484 const child_ctx = @_Object.create(ctx);
14485 ${this.context_props}
14486 return child_ctx;
14487 }
14488 `);
14489 const initial_anchor_node = parent_node ? 'null' : 'anchor';
14490 const initial_mount_node = parent_node || '#target';
14491 const update_anchor_node = needs_anchor
14492 ? block.get_unique_name(`${this.var}_anchor`)
14493 : (this.next && this.next.var) || 'null';
14494 const update_mount_node = this.get_update_mount_node(update_anchor_node);
14495 const args = {
14496 block,
14497 parent_node,
14498 parent_nodes,
14499 snippet,
14500 initial_anchor_node,
14501 initial_mount_node,
14502 update_anchor_node,
14503 update_mount_node
14504 };
14505 if (this.node.key) {
14506 this.render_keyed(args);
14507 }
14508 else {
14509 this.render_unkeyed(args);
14510 }
14511 if (this.block.has_intro_method || this.block.has_outro_method) {
14512 block.builders.intro.add_block(deindent `
14513 for (var #i = 0; #i < ${this.vars.data_length}; #i += 1) @transition_in(${this.vars.iterations}[#i]);
14514 `);
14515 }
14516 if (needs_anchor) {
14517 block.add_element(update_anchor_node, `@empty()`, parent_nodes && `@empty()`, parent_node);
14518 }
14519 if (this.else) {
14520 const each_block_else = component.get_unique_name(`${this.var}_else`);
14521 block.builders.init.add_line(`var ${each_block_else} = null;`);
14522 // TODO neaten this up... will end up with an empty line in the block
14523 block.builders.init.add_block(deindent `
14524 if (!${this.vars.data_length}) {
14525 ${each_block_else} = ${this.else.block.name}(ctx);
14526 ${each_block_else}.c();
14527 }
14528 `);
14529 block.builders.mount.add_block(deindent `
14530 if (${each_block_else}) {
14531 ${each_block_else}.m(${initial_mount_node}, ${initial_anchor_node});
14532 }
14533 `);
14534 if (this.else.block.has_update_method) {
14535 block.builders.update.add_block(deindent `
14536 if (!${this.vars.data_length} && ${each_block_else}) {
14537 ${each_block_else}.p(changed, ctx);
14538 } else if (!${this.vars.data_length}) {
14539 ${each_block_else} = ${this.else.block.name}(ctx);
14540 ${each_block_else}.c();
14541 ${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
14542 } else if (${each_block_else}) {
14543 ${each_block_else}.d(1);
14544 ${each_block_else} = null;
14545 }
14546 `);
14547 }
14548 else {
14549 block.builders.update.add_block(deindent `
14550 if (${this.vars.data_length}) {
14551 if (${each_block_else}) {
14552 ${each_block_else}.d(1);
14553 ${each_block_else} = null;
14554 }
14555 } else if (!${each_block_else}) {
14556 ${each_block_else} = ${this.else.block.name}(ctx);
14557 ${each_block_else}.c();
14558 ${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
14559 }
14560 `);
14561 }
14562 block.builders.destroy.add_block(deindent `
14563 if (${each_block_else}) ${each_block_else}.d(${parent_node ? '' : 'detaching'});
14564 `);
14565 }
14566 this.fragment.render(this.block, null, 'nodes');
14567 if (this.else) {
14568 this.else.fragment.render(this.else.block, null, 'nodes');
14569 }
14570 }
14571 render_keyed({ block, parent_node, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }) {
14572 const { create_each_block, length, iterations, view_length } = this.vars;
14573 const get_key = block.get_unique_name('get_key');
14574 const lookup = block.get_unique_name(`${this.var}_lookup`);
14575 block.add_variable(iterations, '[]');
14576 block.add_variable(lookup, `new @_Map()`);
14577 if (this.fragment.nodes[0].is_dom_node()) {
14578 this.block.first = this.fragment.nodes[0].var;
14579 }
14580 else {
14581 this.block.first = this.block.get_unique_name('first');
14582 this.block.add_element(this.block.first, `@empty()`, parent_nodes && `@empty()`, null);
14583 }
14584 block.builders.init.add_block(deindent `
14585 const ${get_key} = ctx => ${
14586 // @ts-ignore todo: probably error
14587 this.node.key.render()};
14588
14589 for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
14590 let child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i);
14591 let key = ${get_key}(child_ctx);
14592 ${lookup}.set(key, ${iterations}[#i] = ${create_each_block}(key, child_ctx));
14593 }
14594 `);
14595 block.builders.create.add_block(deindent `
14596 for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].c();
14597 `);
14598 if (parent_nodes && this.renderer.options.hydratable) {
14599 block.builders.claim.add_block(deindent `
14600 for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].l(${parent_nodes});
14601 `);
14602 }
14603 block.builders.mount.add_block(deindent `
14604 for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node});
14605 `);
14606 const dynamic = this.block.has_update_method;
14607 const destroy = this.node.has_animation
14608 ? (this.block.has_outros
14609 ? `@fix_and_outro_and_destroy_block`
14610 : `@fix_and_destroy_block`)
14611 : this.block.has_outros
14612 ? `@outro_and_destroy_block`
14613 : `@destroy_block`;
14614 block.builders.update.add_block(deindent `
14615 const ${this.vars.each_block_value} = ${snippet};
14616
14617 ${this.block.has_outros && `@group_outros();`}
14618 ${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`}
14619 ${iterations} = @update_keyed_each(${iterations}, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context});
14620 ${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`}
14621 ${this.block.has_outros && `@check_outros();`}
14622 `);
14623 if (this.block.has_outros) {
14624 block.builders.outro.add_block(deindent `
14625 for (#i = 0; #i < ${view_length}; #i += 1) @transition_out(${iterations}[#i]);
14626 `);
14627 }
14628 block.builders.destroy.add_block(deindent `
14629 for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].d(${parent_node ? '' : 'detaching'});
14630 `);
14631 }
14632 render_unkeyed({ block, parent_nodes, snippet, initial_anchor_node, initial_mount_node, update_anchor_node, update_mount_node }) {
14633 const { create_each_block, length, iterations, fixed_length, data_length, view_length } = this.vars;
14634 block.builders.init.add_block(deindent `
14635 var ${iterations} = [];
14636
14637 for (var #i = 0; #i < ${data_length}; #i += 1) {
14638 ${iterations}[#i] = ${create_each_block}(${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i));
14639 }
14640 `);
14641 block.builders.create.add_block(deindent `
14642 for (var #i = 0; #i < ${view_length}; #i += 1) {
14643 ${iterations}[#i].c();
14644 }
14645 `);
14646 if (parent_nodes && this.renderer.options.hydratable) {
14647 block.builders.claim.add_block(deindent `
14648 for (var #i = 0; #i < ${view_length}; #i += 1) {
14649 ${iterations}[#i].l(${parent_nodes});
14650 }
14651 `);
14652 }
14653 block.builders.mount.add_block(deindent `
14654 for (var #i = 0; #i < ${view_length}; #i += 1) {
14655 ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node});
14656 }
14657 `);
14658 const all_dependencies = new Set(this.block.dependencies);
14659 const { dependencies } = this.node.expression;
14660 dependencies.forEach((dependency) => {
14661 all_dependencies.add(dependency);
14662 });
14663 const condition = Array.from(all_dependencies)
14664 .map(dependency => `changed.${dependency}`)
14665 .join(' || ');
14666 const has_transitions = !!(this.block.has_intro_method || this.block.has_outro_method);
14667 if (condition !== '') {
14668 const for_loop_body = this.block.has_update_method
14669 ? deindent `
14670 if (${iterations}[#i]) {
14671 ${iterations}[#i].p(changed, child_ctx);
14672 ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
14673 } else {
14674 ${iterations}[#i] = ${create_each_block}(child_ctx);
14675 ${iterations}[#i].c();
14676 ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
14677 ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node});
14678 }
14679 `
14680 : has_transitions
14681 ? deindent `
14682 if (${iterations}[#i]) {
14683 @transition_in(${this.vars.iterations}[#i], 1);
14684 } else {
14685 ${iterations}[#i] = ${create_each_block}(child_ctx);
14686 ${iterations}[#i].c();
14687 @transition_in(${this.vars.iterations}[#i], 1);
14688 ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node});
14689 }
14690 `
14691 : deindent `
14692 if (!${iterations}[#i]) {
14693 ${iterations}[#i] = ${create_each_block}(child_ctx);
14694 ${iterations}[#i].c();
14695 ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node});
14696 }
14697 `;
14698 const start = this.block.has_update_method ? '0' : `#old_length`;
14699 let remove_old_blocks;
14700 if (this.block.has_outros) {
14701 const out = block.get_unique_name('out');
14702 block.builders.init.add_block(deindent `
14703 const ${out} = i => @transition_out(${iterations}[i], 1, 1, () => {
14704 ${iterations}[i] = null;
14705 });
14706 `);
14707 remove_old_blocks = deindent `
14708 @group_outros();
14709 for (#i = ${this.vars.each_block_value}.${length}; #i < ${view_length}; #i += 1) ${out}(#i);
14710 @check_outros();
14711 `;
14712 }
14713 else {
14714 remove_old_blocks = deindent `
14715 for (${this.block.has_update_method ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) {
14716 ${iterations}[#i].d(1);
14717 }
14718 ${!fixed_length && `${view_length} = ${this.vars.each_block_value}.${length};`}
14719 `;
14720 }
14721 const update = deindent `
14722 ${!this.block.has_update_method && `const #old_length = ${this.vars.each_block_value}.length;`}
14723 ${this.vars.each_block_value} = ${snippet};
14724
14725 for (var #i = ${start}; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
14726 const child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i);
14727
14728 ${for_loop_body}
14729 }
14730
14731 ${remove_old_blocks}
14732 `;
14733 block.builders.update.add_block(deindent `
14734 if (${condition}) {
14735 ${update}
14736 }
14737 `);
14738 }
14739 if (this.block.has_outros) {
14740 block.builders.outro.add_block(deindent `
14741 ${iterations} = ${iterations}.filter(@_Boolean);
14742 for (let #i = 0; #i < ${view_length}; #i += 1) @transition_out(${iterations}[#i]);`);
14743 }
14744 block.builders.destroy.add_block(`@destroy_each(${iterations}, detaching);`);
14745 }
14746 }
14747
14748 const svg_attributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' ');
14749 const svg_attribute_lookup = new Map();
14750 svg_attributes.forEach(name => {
14751 svg_attribute_lookup.set(name.toLowerCase(), name);
14752 });
14753 function fix_attribute_casing(name) {
14754 name = name.toLowerCase();
14755 return svg_attribute_lookup.get(name) || name;
14756 }
14757
14758 const html = 'http://www.w3.org/1999/xhtml';
14759 const mathml = 'http://www.w3.org/1998/Math/MathML';
14760 const svg = 'http://www.w3.org/2000/svg';
14761 const xlink = 'http://www.w3.org/1999/xlink';
14762 const xml = 'http://www.w3.org/XML/1998/namespace';
14763 const xmlns = 'http://www.w3.org/2000/xmlns';
14764 const valid_namespaces = [
14765 'html',
14766 'mathml',
14767 'svg',
14768 'xlink',
14769 'xml',
14770 'xmlns',
14771 html,
14772 mathml,
14773 svg,
14774 xlink,
14775 xml,
14776 xmlns,
14777 ];
14778 const namespaces = { html, mathml, svg, xlink, xml, xmlns };
14779
14780 class AttributeWrapper {
14781 constructor(parent, block, node) {
14782 this.node = node;
14783 this.parent = parent;
14784 if (node.dependencies.size > 0) {
14785 parent.cannot_use_innerhtml();
14786 block.add_dependencies(node.dependencies);
14787 // special case — <option value={foo}> — see below
14788 if (this.parent.node.name === 'option' && node.name === 'value') {
14789 let select = this.parent;
14790 while (select && (select.node.type !== 'Element' || select.node.name !== 'select'))
14791 // @ts-ignore todo: doublecheck this, but looks to be correct
14792 select = select.parent;
14793 if (select && select.select_binding_dependencies) {
14794 select.select_binding_dependencies.forEach(prop => {
14795 this.node.dependencies.forEach((dependency) => {
14796 this.parent.renderer.component.indirect_dependencies.get(prop).add(dependency);
14797 });
14798 });
14799 }
14800 }
14801 }
14802 }
14803 render(block) {
14804 const element = this.parent;
14805 const name = fix_attribute_casing(this.node.name);
14806 let metadata = element.node.namespace ? null : attribute_lookup[name];
14807 if (metadata && metadata.applies_to && !~metadata.applies_to.indexOf(element.node.name))
14808 metadata = null;
14809 const is_indirectly_bound_value = name === 'value' &&
14810 (element.node.name === 'option' || // TODO check it's actually bound
14811 (element.node.name === 'input' &&
14812 element.node.bindings.find((binding) => /checked|group/.test(binding.name))));
14813 const property_name = is_indirectly_bound_value
14814 ? '__value'
14815 : metadata && metadata.property_name;
14816 // xlink is a special case... we could maybe extend this to generic
14817 // namespaced attributes but I'm not sure that's applicable in
14818 // HTML5?
14819 const method = /-/.test(element.node.name)
14820 ? '@set_custom_element_data'
14821 : name.slice(0, 6) === 'xlink:'
14822 ? '@xlink_attr'
14823 : '@attr';
14824 const is_legacy_input_type = element.renderer.component.compile_options.legacy && name === 'type' && this.parent.node.name === 'input';
14825 const is_dataset = /^data-/.test(name) && !element.renderer.component.compile_options.legacy && !element.node.namespace;
14826 const camel_case_name = is_dataset ? name.replace('data-', '').replace(/(-\w)/g, (m) => {
14827 return m[1].toUpperCase();
14828 }) : name;
14829 if (this.node.is_dynamic) {
14830 let value;
14831 // TODO some of this code is repeated in Tag.ts — would be good to
14832 // DRY it out if that's possible without introducing crazy indirection
14833 if (this.node.chunks.length === 1) {
14834 // single {tag} — may be a non-string
14835 value = this.node.chunks[0].render(block);
14836 }
14837 else {
14838 // '{foo} {bar}' — treat as string concatenation
14839 value =
14840 (this.node.chunks[0].type === 'Text' ? '' : `"" + `) +
14841 this.node.chunks
14842 .map((chunk) => {
14843 if (chunk.type === 'Text') {
14844 return stringify(chunk.data);
14845 }
14846 else {
14847 return chunk.get_precedence() <= 13
14848 ? `(${chunk.render()})`
14849 : chunk.render();
14850 }
14851 })
14852 .join(' + ');
14853 }
14854 const is_select_value_attribute = name === 'value' && element.node.name === 'select';
14855 const should_cache = (this.node.should_cache || is_select_value_attribute);
14856 const last = should_cache && block.get_unique_name(`${element.var}_${name.replace(/[^a-zA-Z_$]/g, '_')}_value`);
14857 if (should_cache)
14858 block.add_variable(last);
14859 let updater;
14860 const init = should_cache ? `${last} = ${value}` : value;
14861 if (is_legacy_input_type) {
14862 block.builders.hydrate.add_line(`@set_input_type(${element.var}, ${init});`);
14863 updater = `@set_input_type(${element.var}, ${should_cache ? last : value});`;
14864 }
14865 else if (is_select_value_attribute) {
14866 // annoying special case
14867 const is_multiple_select = element.node.get_static_attribute_value('multiple');
14868 const i = block.get_unique_name('i');
14869 const option = block.get_unique_name('option');
14870 const if_statement = is_multiple_select
14871 ? deindent `
14872 ${option}.selected = ~${last}.indexOf(${option}.__value);`
14873 : deindent `
14874 if (${option}.__value === ${last}) {
14875 ${option}.selected = true;
14876 break;
14877 }`;
14878 updater = deindent `
14879 for (var ${i} = 0; ${i} < ${element.var}.options.length; ${i} += 1) {
14880 var ${option} = ${element.var}.options[${i}];
14881
14882 ${if_statement}
14883 }
14884 `;
14885 block.builders.mount.add_block(deindent `
14886 ${last} = ${value};
14887 ${updater}
14888 `);
14889 }
14890 else if (property_name) {
14891 block.builders.hydrate.add_line(`${element.var}.${property_name} = ${init};`);
14892 updater = `${element.var}.${property_name} = ${should_cache ? last : value};`;
14893 }
14894 else if (is_dataset) {
14895 block.builders.hydrate.add_line(`${element.var}.dataset.${camel_case_name} = ${init};`);
14896 updater = `${element.var}.dataset.${camel_case_name} = ${should_cache ? last : value};`;
14897 }
14898 else {
14899 block.builders.hydrate.add_line(`${method}(${element.var}, "${name}", ${init});`);
14900 updater = `${method}(${element.var}, "${name}", ${should_cache ? last : value});`;
14901 }
14902 // only add an update if mutations are involved (or it's a select?)
14903 const dependencies = this.node.get_dependencies();
14904 if (dependencies.length > 0 || is_select_value_attribute) {
14905 const changed_check = ((block.has_outros ? `!#current || ` : '') +
14906 dependencies.map(dependency => `changed.${dependency}`).join(' || '));
14907 const update_cached_value = `${last} !== (${last} = ${value})`;
14908 const condition = should_cache
14909 ? (dependencies.length ? `(${changed_check}) && ${update_cached_value}` : update_cached_value)
14910 : changed_check;
14911 block.builders.update.add_conditional(condition, updater);
14912 }
14913 }
14914 else {
14915 const value = this.node.get_value(block);
14916 const statement = (is_legacy_input_type
14917 ? `@set_input_type(${element.var}, ${value});`
14918 : property_name
14919 ? `${element.var}.${property_name} = ${value};`
14920 : is_dataset
14921 ? `${element.var}.dataset.${camel_case_name} = ${value === true ? '""' : value};`
14922 : `${method}(${element.var}, "${name}", ${value === true ? '""' : value});`);
14923 block.builders.hydrate.add_line(statement);
14924 // special case – autofocus. has to be handled in a bit of a weird way
14925 if (this.node.is_true && name === 'autofocus') {
14926 block.autofocus = element.var;
14927 }
14928 }
14929 if (is_indirectly_bound_value) {
14930 const update_value = `${element.var}.value = ${element.var}.__value;`;
14931 block.builders.hydrate.add_line(update_value);
14932 if (this.node.is_dynamic)
14933 block.builders.update.add_line(update_value);
14934 }
14935 }
14936 stringify() {
14937 if (this.node.is_true)
14938 return '';
14939 const value = this.node.chunks;
14940 if (value.length === 0)
14941 return `=""`;
14942 return `="${value.map(chunk => {
14943 return chunk.type === 'Text'
14944 ? chunk.data.replace(/"/g, '\\"')
14945 : `\${${chunk.render()}}`;
14946 })}"`;
14947 }
14948 }
14949 // source: https://html.spec.whatwg.org/multipage/indices.html
14950 const attribute_lookup = {
14951 allowfullscreen: { property_name: 'allowFullscreen', applies_to: ['iframe'] },
14952 allowpaymentrequest: { property_name: 'allowPaymentRequest', applies_to: ['iframe'] },
14953 async: { applies_to: ['script'] },
14954 autofocus: { applies_to: ['button', 'input', 'keygen', 'select', 'textarea'] },
14955 autoplay: { applies_to: ['audio', 'video'] },
14956 checked: { applies_to: ['input'] },
14957 controls: { applies_to: ['audio', 'video'] },
14958 default: { applies_to: ['track'] },
14959 defer: { applies_to: ['script'] },
14960 disabled: {
14961 applies_to: [
14962 'button',
14963 'fieldset',
14964 'input',
14965 'keygen',
14966 'optgroup',
14967 'option',
14968 'select',
14969 'textarea',
14970 ],
14971 },
14972 formnovalidate: { property_name: 'formNoValidate', applies_to: ['button', 'input'] },
14973 hidden: {},
14974 indeterminate: { applies_to: ['input'] },
14975 ismap: { property_name: 'isMap', applies_to: ['img'] },
14976 loop: { applies_to: ['audio', 'bgsound', 'video'] },
14977 multiple: { applies_to: ['input', 'select'] },
14978 muted: { applies_to: ['audio', 'video'] },
14979 nomodule: { property_name: 'noModule', applies_to: ['script'] },
14980 novalidate: { property_name: 'noValidate', applies_to: ['form'] },
14981 open: { applies_to: ['details', 'dialog'] },
14982 playsinline: { property_name: 'playsInline', applies_to: ['video'] },
14983 readonly: { property_name: 'readOnly', applies_to: ['input', 'textarea'] },
14984 required: { applies_to: ['input', 'select', 'textarea'] },
14985 reversed: { applies_to: ['ol'] },
14986 selected: { applies_to: ['option'] },
14987 value: {
14988 applies_to: [
14989 'button',
14990 'option',
14991 'input',
14992 'li',
14993 'meter',
14994 'progress',
14995 'param',
14996 'select',
14997 'textarea',
14998 ],
14999 },
15000 };
15001 Object.keys(attribute_lookup).forEach(name => {
15002 const metadata = attribute_lookup[name];
15003 if (!metadata.property_name)
15004 metadata.property_name = name;
15005 });
15006
15007 class StyleAttributeWrapper extends AttributeWrapper {
15008 render(block) {
15009 const style_props = optimize_style(this.node.chunks);
15010 if (!style_props)
15011 return super.render(block);
15012 style_props.forEach((prop) => {
15013 let value;
15014 if (is_dynamic(prop.value)) {
15015 const prop_dependencies = new Set();
15016 value =
15017 ((prop.value.length === 1 || prop.value[0].type === 'Text') ? '' : `"" + `) +
15018 prop.value
15019 .map((chunk) => {
15020 if (chunk.type === 'Text') {
15021 return stringify(chunk.data);
15022 }
15023 else {
15024 const snippet = chunk.render();
15025 add_to_set(prop_dependencies, chunk.dependencies);
15026 return chunk.get_precedence() <= 13 ? `(${snippet})` : snippet;
15027 }
15028 })
15029 .join(' + ');
15030 if (prop_dependencies.size) {
15031 const dependencies = Array.from(prop_dependencies);
15032 const condition = ((block.has_outros ? `!#current || ` : '') +
15033 dependencies.map(dependency => `changed.${dependency}`).join(' || '));
15034 block.builders.update.add_conditional(condition, `@set_style(${this.parent.var}, "${prop.key}", ${value});`);
15035 }
15036 }
15037 else {
15038 value = stringify(prop.value[0].data);
15039 }
15040 block.builders.hydrate.add_line(`@set_style(${this.parent.var}, "${prop.key}", ${value});`);
15041 });
15042 }
15043 }
15044 function optimize_style(value) {
15045 const props = [];
15046 let chunks = value.slice();
15047 while (chunks.length) {
15048 const chunk = chunks[0];
15049 if (chunk.type !== 'Text')
15050 return null;
15051 const key_match = /^\s*([\w-]+):\s*/.exec(chunk.data);
15052 if (!key_match)
15053 return null;
15054 const key = key_match[1];
15055 const offset = key_match.index + key_match[0].length;
15056 const remaining_data = chunk.data.slice(offset);
15057 if (remaining_data) {
15058 /* eslint-disable @typescript-eslint/no-object-literal-type-assertion */
15059 chunks[0] = {
15060 start: chunk.start + offset,
15061 end: chunk.end,
15062 type: 'Text',
15063 data: remaining_data
15064 };
15065 /* eslint-enable @typescript-eslint/no-object-literal-type-assertion */
15066 }
15067 else {
15068 chunks.shift();
15069 }
15070 const result = get_style_value(chunks);
15071 props.push({ key, value: result.value });
15072 chunks = result.chunks;
15073 }
15074 return props;
15075 }
15076 function get_style_value(chunks) {
15077 const value = [];
15078 let in_url = false;
15079 let quote_mark = null;
15080 let escaped = false;
15081 while (chunks.length) {
15082 const chunk = chunks.shift();
15083 if (chunk.type === 'Text') {
15084 let c = 0;
15085 while (c < chunk.data.length) {
15086 const char = chunk.data[c];
15087 if (escaped) {
15088 escaped = false;
15089 }
15090 else if (char === '\\') {
15091 escaped = true;
15092 }
15093 else if (char === quote_mark) {
15094 quote_mark = null;
15095 }
15096 else if (char === '"' || char === "'") {
15097 quote_mark = char;
15098 }
15099 else if (char === ')' && in_url) {
15100 in_url = false;
15101 }
15102 else if (char === 'u' && chunk.data.slice(c, c + 4) === 'url(') {
15103 in_url = true;
15104 }
15105 else if (char === ';' && !in_url && !quote_mark) {
15106 break;
15107 }
15108 c += 1;
15109 }
15110 if (c > 0) {
15111 value.push({
15112 type: 'Text',
15113 start: chunk.start,
15114 end: chunk.start + c,
15115 data: chunk.data.slice(0, c)
15116 });
15117 }
15118 while (/[;\s]/.test(chunk.data[c]))
15119 c += 1;
15120 const remaining_data = chunk.data.slice(c);
15121 if (remaining_data) {
15122 chunks.unshift({
15123 start: chunk.start + c,
15124 end: chunk.end,
15125 type: 'Text',
15126 data: remaining_data
15127 });
15128 break;
15129 }
15130 }
15131 else {
15132 value.push(chunk);
15133 }
15134 }
15135 return {
15136 chunks,
15137 value
15138 };
15139 }
15140 function is_dynamic(value) {
15141 return value.length > 1 || value[0].type !== 'Text';
15142 }
15143
15144 function unwrap_parens(node) {
15145 while (node.type === 'ParenthesizedExpression')
15146 node = node.expression;
15147 return node;
15148 }
15149
15150 function get_object(node) {
15151 node = unwrap_parens(node);
15152 while (node.type === 'MemberExpression')
15153 node = node.object;
15154 return node;
15155 }
15156
15157 function flatten_reference(node) {
15158 if (node.type === 'Expression')
15159 throw new Error('bad');
15160 const nodes = [];
15161 const parts = [];
15162 const prop_end = node.end;
15163 while (node.type === 'MemberExpression') {
15164 nodes.unshift(node.property);
15165 if (!node.computed) {
15166 parts.unshift(node.property.name);
15167 }
15168 node = node.object;
15169 }
15170 const prop_start = node.end;
15171 const name = node.type === 'Identifier'
15172 ? node.name
15173 : node.type === 'ThisExpression' ? 'this' : null;
15174 nodes.unshift(node);
15175 if (!node.computed) {
15176 parts.unshift(name);
15177 }
15178 return { name, nodes, parts, keypath: `${name}[✂${prop_start}-${prop_end}✂]` };
15179 }
15180
15181 function get_tail(node) {
15182 const end = node.end;
15183 while (node.type === 'MemberExpression')
15184 node = node.object;
15185 return { start: node.end, end };
15186 }
15187 class BindingWrapper {
15188 constructor(block, node, parent) {
15189 this.node = node;
15190 this.parent = parent;
15191 const { dependencies } = this.node.expression;
15192 block.add_dependencies(dependencies);
15193 // TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`?
15194 if (parent.node.name === 'select') {
15195 parent.select_binding_dependencies = dependencies;
15196 dependencies.forEach((prop) => {
15197 parent.renderer.component.indirect_dependencies.set(prop, new Set());
15198 });
15199 }
15200 if (node.is_contextual) {
15201 // we need to ensure that the each block creates a context including
15202 // the list and the index, if they're not otherwise referenced
15203 const { name } = get_object(this.node.expression.node);
15204 const each_block = this.parent.node.scope.get_owner(name);
15205 each_block.has_binding = true;
15206 }
15207 this.object = get_object(this.node.expression.node).name;
15208 // TODO unfortunate code is necessary because we need to use `ctx`
15209 // inside the fragment, but not inside the <script>
15210 const contextless_snippet = this.parent.renderer.component.source.slice(this.node.expression.node.start, this.node.expression.node.end);
15211 // view to model
15212 this.handler = get_event_handler(this, parent.renderer, block, this.object, contextless_snippet);
15213 this.snippet = this.node.expression.render(block);
15214 this.is_readonly = this.node.is_readonly;
15215 this.needs_lock = this.node.name === 'currentTime'; // TODO others?
15216 }
15217 get_dependencies() {
15218 const dependencies = new Set(this.node.expression.dependencies);
15219 this.node.expression.dependencies.forEach((prop) => {
15220 const indirect_dependencies = this.parent.renderer.component.indirect_dependencies.get(prop);
15221 if (indirect_dependencies) {
15222 indirect_dependencies.forEach(indirect_dependency => {
15223 dependencies.add(indirect_dependency);
15224 });
15225 }
15226 });
15227 return dependencies;
15228 }
15229 is_readonly_media_attribute() {
15230 return this.node.is_readonly_media_attribute();
15231 }
15232 render(block, lock) {
15233 if (this.is_readonly)
15234 return;
15235 const { parent } = this;
15236 const update_conditions = this.needs_lock ? [`!${lock}`] : [];
15237 const dependency_array = [...this.node.expression.dependencies];
15238 if (dependency_array.length === 1) {
15239 update_conditions.push(`changed.${dependency_array[0]}`);
15240 }
15241 else if (dependency_array.length > 1) {
15242 update_conditions.push(`(${dependency_array.map(prop => `changed.${prop}`).join(' || ')})`);
15243 }
15244 if (parent.node.name === 'input') {
15245 const type = parent.node.get_static_attribute_value('type');
15246 if (type === null || type === "" || type === "text") {
15247 update_conditions.push(`(${parent.var}.${this.node.name} !== ${this.snippet})`);
15248 }
15249 }
15250 // model to view
15251 let update_dom = get_dom_updater(parent, this);
15252 // special cases
15253 switch (this.node.name) {
15254 case 'group':
15255 {
15256 const binding_group = get_binding_group(parent.renderer, this.node.expression.node);
15257 block.builders.hydrate.add_line(`ctx.$$binding_groups[${binding_group}].push(${parent.var});`);
15258 block.builders.destroy.add_line(`ctx.$$binding_groups[${binding_group}].splice(ctx.$$binding_groups[${binding_group}].indexOf(${parent.var}), 1);`);
15259 break;
15260 }
15261 case 'textContent':
15262 update_conditions.push(`${this.snippet} !== ${parent.var}.textContent`);
15263 break;
15264 case 'innerHTML':
15265 update_conditions.push(`${this.snippet} !== ${parent.var}.innerHTML`);
15266 break;
15267 case 'currentTime':
15268 case 'playbackRate':
15269 case 'volume':
15270 update_conditions.push(`!@_isNaN(${this.snippet})`);
15271 break;
15272 case 'paused':
15273 {
15274 // this is necessary to prevent audio restarting by itself
15275 const last = block.get_unique_name(`${parent.var}_is_paused`);
15276 block.add_variable(last, 'true');
15277 update_conditions.push(`${last} !== (${last} = ${this.snippet})`);
15278 update_dom = `${parent.var}[${last} ? "pause" : "play"]();`;
15279 break;
15280 }
15281 case 'value':
15282 if (parent.node.get_static_attribute_value('type') === 'file') {
15283 update_dom = null;
15284 }
15285 }
15286 if (update_dom) {
15287 block.builders.update.add_line(update_conditions.length ? `if (${update_conditions.join(' && ')}) ${update_dom}` : update_dom);
15288 }
15289 if (this.node.name === 'innerHTML' || this.node.name === 'textContent') {
15290 block.builders.mount.add_block(`if (${this.snippet} !== void 0) ${update_dom}`);
15291 }
15292 else if (!/(currentTime|paused)/.test(this.node.name)) {
15293 block.builders.mount.add_block(update_dom);
15294 }
15295 }
15296 }
15297 function get_dom_updater(element, binding) {
15298 const { node } = element;
15299 if (binding.is_readonly_media_attribute()) {
15300 return null;
15301 }
15302 if (binding.node.name === 'this') {
15303 return null;
15304 }
15305 if (node.name === 'select') {
15306 return node.get_static_attribute_value('multiple') === true ?
15307 `@select_options(${element.var}, ${binding.snippet})` :
15308 `@select_option(${element.var}, ${binding.snippet})`;
15309 }
15310 if (binding.node.name === 'group') {
15311 const type = node.get_static_attribute_value('type');
15312 const condition = type === 'checkbox'
15313 ? `~${binding.snippet}.indexOf(${element.var}.__value)`
15314 : `${element.var}.__value === ${binding.snippet}`;
15315 return `${element.var}.checked = ${condition};`;
15316 }
15317 return `${element.var}.${binding.node.name} = ${binding.snippet};`;
15318 }
15319 function get_binding_group(renderer, value) {
15320 const { parts } = flatten_reference(value); // TODO handle cases involving computed member expressions
15321 const keypath = parts.join('.');
15322 // TODO handle contextual bindings — `keypath` should include unique ID of
15323 // each block that provides context
15324 let index = renderer.binding_groups.indexOf(keypath);
15325 if (index === -1) {
15326 index = renderer.binding_groups.length;
15327 renderer.binding_groups.push(keypath);
15328 }
15329 return index;
15330 }
15331 function mutate_store(store, value, tail) {
15332 return tail
15333 ? `${store}.update($$value => ($$value${tail} = ${value}, $$value));`
15334 : `${store}.set(${value});`;
15335 }
15336 function get_event_handler(binding, renderer, block, name, snippet) {
15337 const value = get_value_from_dom(renderer, binding.parent, binding);
15338 const store = binding.object[0] === '$' ? binding.object.slice(1) : null;
15339 let tail = '';
15340 if (binding.node.expression.node.type === 'MemberExpression') {
15341 const { start, end } = get_tail(binding.node.expression.node);
15342 tail = renderer.component.source.slice(start, end);
15343 }
15344 if (binding.node.is_contextual) {
15345 const { object, property, snippet } = block.bindings.get(name);
15346 return {
15347 uses_context: true,
15348 mutation: store
15349 ? mutate_store(store, value, tail)
15350 : `${snippet}${tail} = ${value};`,
15351 contextual_dependencies: new Set([object, property])
15352 };
15353 }
15354 const mutation = store
15355 ? mutate_store(store, value, tail)
15356 : `${snippet} = ${value};`;
15357 if (binding.node.expression.node.type === 'MemberExpression') {
15358 return {
15359 uses_context: binding.node.expression.uses_context,
15360 mutation,
15361 contextual_dependencies: binding.node.expression.contextual_dependencies,
15362 snippet
15363 };
15364 }
15365 return {
15366 uses_context: false,
15367 mutation,
15368 contextual_dependencies: new Set()
15369 };
15370 }
15371 function get_value_from_dom(renderer, element, binding) {
15372 const { node } = element;
15373 const { name } = binding.node;
15374 if (name === 'this') {
15375 return `$$node`;
15376 }
15377 // <select bind:value='selected>
15378 if (node.name === 'select') {
15379 return node.get_static_attribute_value('multiple') === true ?
15380 `@select_multiple_value(this)` :
15381 `@select_value(this)`;
15382 }
15383 const type = node.get_static_attribute_value('type');
15384 // <input type='checkbox' bind:group='foo'>
15385 if (name === 'group') {
15386 const binding_group = get_binding_group(renderer, binding.node.expression.node);
15387 if (type === 'checkbox') {
15388 return `@get_binding_group_value($$binding_groups[${binding_group}])`;
15389 }
15390 return `this.__value`;
15391 }
15392 // <input type='range|number' bind:value>
15393 if (type === 'range' || type === 'number') {
15394 return `@to_number(this.${name})`;
15395 }
15396 if ((name === 'buffered' || name === 'seekable' || name === 'played')) {
15397 return `@time_ranges_to_array(this.${name})`;
15398 }
15399 // everything else
15400 return `this.${name}`;
15401 }
15402
15403 function add_event_handlers(block, target, handlers) {
15404 handlers.forEach(handler => {
15405 let snippet = handler.render(block);
15406 if (handler.modifiers.has('preventDefault'))
15407 snippet = `@prevent_default(${snippet})`;
15408 if (handler.modifiers.has('stopPropagation'))
15409 snippet = `@stop_propagation(${snippet})`;
15410 const opts = ['passive', 'once', 'capture'].filter(mod => handler.modifiers.has(mod));
15411 if (opts.length) {
15412 const opts_string = (opts.length === 1 && opts[0] === 'capture')
15413 ? 'true'
15414 : `{ ${opts.map(opt => `${opt}: true`).join(', ')} }`;
15415 block.event_listeners.push(`@listen(${target}, "${handler.name}", ${snippet}, ${opts_string})`);
15416 }
15417 else {
15418 block.event_listeners.push(`@listen(${target}, "${handler.name}", ${snippet})`);
15419 }
15420 });
15421 }
15422
15423 function add_actions(component, block, target, actions) {
15424 actions.forEach(action => {
15425 const { expression } = action;
15426 let snippet;
15427 let dependencies;
15428 if (expression) {
15429 snippet = expression.render(block);
15430 dependencies = expression.dynamic_dependencies();
15431 }
15432 const name = block.get_unique_name(`${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action`);
15433 block.add_variable(name);
15434 const fn = component.qualify(action.name);
15435 block.builders.mount.add_line(`${name} = ${fn}.call(null, ${target}${snippet ? `, ${snippet}` : ''}) || {};`);
15436 if (dependencies && dependencies.length > 0) {
15437 let conditional = `typeof ${name}.update === 'function' && `;
15438 const deps = dependencies.map(dependency => `changed.${dependency}`).join(' || ');
15439 conditional += dependencies.length > 1 ? `(${deps})` : deps;
15440 block.builders.update.add_conditional(conditional, `${name}.update.call(null, ${snippet});`);
15441 }
15442 block.builders.destroy.add_line(`if (${name} && typeof ${name}.destroy === 'function') ${name}.destroy();`);
15443 });
15444 }
15445
15446 function get_context_merger(lets) {
15447 if (lets.length === 0)
15448 return null;
15449 const input = lets.map(l => l.value ? `${l.name}: ${l.value}` : l.name).join(', ');
15450 const names = new Set();
15451 lets.forEach(l => {
15452 l.names.forEach(name => {
15453 names.add(name);
15454 });
15455 });
15456 const output = Array.from(names).join(', ');
15457 return `({ ${input} }) => ({ ${output} })`;
15458 }
15459
15460 function bind_this(component, block, binding, variable) {
15461 const fn = component.get_unique_name(`${variable}_binding`);
15462 component.add_var({
15463 name: fn,
15464 internal: true,
15465 referenced: true
15466 });
15467 let lhs;
15468 let object;
15469 let body;
15470 if (binding.is_contextual && binding.expression.node.type === 'Identifier') {
15471 // bind:x={y} — we can't just do `y = x`, we need to
15472 // to `array[index] = x;
15473 const { name } = binding.expression.node;
15474 const { snippet } = block.bindings.get(name);
15475 lhs = snippet;
15476 body = `${lhs} = $$value`; // TODO we need to invalidate... something
15477 }
15478 else {
15479 object = flatten_reference(binding.expression.node).name;
15480 lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim();
15481 body = binding.expression.node.type === 'Identifier'
15482 ? deindent `
15483 ${component.invalidate(object, `${lhs} = $$value`)};
15484 `
15485 : deindent `
15486 ${lhs} = $$value;
15487 ${component.invalidate(object)};
15488 `;
15489 }
15490 const contextual_dependencies = Array.from(binding.expression.contextual_dependencies);
15491 if (contextual_dependencies.length) {
15492 component.partly_hoisted.push(deindent `
15493 function ${fn}(${['$$value', ...contextual_dependencies].join(', ')}) {
15494 if (${lhs} === $$value) return;
15495 @binding_callbacks[$$value ? 'unshift' : 'push'](() => {
15496 ${body}
15497 });
15498 }
15499 `);
15500 const args = [];
15501 for (const arg of contextual_dependencies) {
15502 args.push(arg);
15503 block.add_variable(arg, `ctx.${arg}`);
15504 }
15505 const assign = block.get_unique_name(`assign_${variable}`);
15506 const unassign = block.get_unique_name(`unassign_${variable}`);
15507 block.builders.init.add_block(deindent `
15508 const ${assign} = () => ctx.${fn}(${[variable].concat(args).join(', ')});
15509 const ${unassign} = () => ctx.${fn}(${['null'].concat(args).join(', ')});
15510 `);
15511 const condition = Array.from(contextual_dependencies).map(name => `${name} !== ctx.${name}`).join(' || ');
15512 // we push unassign and unshift assign so that references are
15513 // nulled out before they're created, to avoid glitches
15514 // with shifting indices
15515 block.builders.update.add_line(deindent `
15516 if (${condition}) {
15517 ${unassign}();
15518 ${args.map(a => `${a} = ctx.${a}`).join(', ')};
15519 ${assign}();
15520 }`);
15521 block.builders.destroy.add_line(`${unassign}();`);
15522 return `${assign}();`;
15523 }
15524 component.partly_hoisted.push(deindent `
15525 function ${fn}($$value) {
15526 @binding_callbacks[$$value ? 'unshift' : 'push'](() => {
15527 ${body}
15528 });
15529 }
15530 `);
15531 block.builders.destroy.add_line(`ctx.${fn}(null);`);
15532 return `ctx.${fn}(${variable});`;
15533 }
15534
15535 const events = [
15536 {
15537 event_names: ['input'],
15538 filter: (node, _name) => node.name === 'textarea' ||
15539 node.name === 'input' && !/radio|checkbox|range/.test(node.get_static_attribute_value('type'))
15540 },
15541 {
15542 event_names: ['input'],
15543 filter: (node, name) => (name === 'textContent' || name === 'innerHTML') &&
15544 node.attributes.some(attribute => attribute.name === 'contenteditable')
15545 },
15546 {
15547 event_names: ['change'],
15548 filter: (node, _name) => node.name === 'select' ||
15549 node.name === 'input' && /radio|checkbox/.test(node.get_static_attribute_value('type'))
15550 },
15551 {
15552 event_names: ['change', 'input'],
15553 filter: (node, _name) => node.name === 'input' && node.get_static_attribute_value('type') === 'range'
15554 },
15555 {
15556 event_names: ['resize'],
15557 filter: (_node, name) => dimensions.test(name)
15558 },
15559 // media events
15560 {
15561 event_names: ['timeupdate'],
15562 filter: (node, name) => node.is_media_node() &&
15563 (name === 'currentTime' || name === 'played')
15564 },
15565 {
15566 event_names: ['durationchange'],
15567 filter: (node, name) => node.is_media_node() &&
15568 name === 'duration'
15569 },
15570 {
15571 event_names: ['play', 'pause'],
15572 filter: (node, name) => node.is_media_node() &&
15573 name === 'paused'
15574 },
15575 {
15576 event_names: ['progress'],
15577 filter: (node, name) => node.is_media_node() &&
15578 name === 'buffered'
15579 },
15580 {
15581 event_names: ['loadedmetadata'],
15582 filter: (node, name) => node.is_media_node() &&
15583 (name === 'buffered' || name === 'seekable')
15584 },
15585 {
15586 event_names: ['volumechange'],
15587 filter: (node, name) => node.is_media_node() &&
15588 name === 'volume'
15589 },
15590 {
15591 event_names: ['ratechange'],
15592 filter: (node, name) => node.is_media_node() &&
15593 name === 'playbackRate'
15594 },
15595 // details event
15596 {
15597 event_names: ['toggle'],
15598 filter: (node, _name) => node.name === 'details'
15599 },
15600 ];
15601 class ElementWrapper extends Wrapper {
15602 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
15603 super(renderer, block, parent, node);
15604 this.var = node.name.replace(/[^a-zA-Z0-9_$]/g, '_');
15605 this.class_dependencies = [];
15606 this.attributes = this.node.attributes.map(attribute => {
15607 if (attribute.name === 'slot') {
15608 // TODO make separate subclass for this?
15609 let owner = this.parent;
15610 while (owner) {
15611 if (owner.node.type === 'InlineComponent') {
15612 break;
15613 }
15614 if (owner.node.type === 'Element' && /-/.test(owner.node.name)) {
15615 break;
15616 }
15617 owner = owner.parent;
15618 }
15619 if (owner && owner.node.type === 'InlineComponent') {
15620 const name = attribute.get_static_value();
15621 if (!owner.slots.has(name)) {
15622 const child_block = block.child({
15623 comment: create_debugging_comment(node, this.renderer.component),
15624 name: this.renderer.component.get_unique_name(`create_${sanitize(name)}_slot`)
15625 });
15626 const lets = this.node.lets;
15627 const seen = new Set(lets.map(l => l.name));
15628 owner.node.lets.forEach(l => {
15629 if (!seen.has(l.name))
15630 lets.push(l);
15631 });
15632 const fn = get_context_merger(lets);
15633 owner.slots.set(name, {
15634 block: child_block,
15635 scope: this.node.scope,
15636 fn
15637 });
15638 this.renderer.blocks.push(child_block);
15639 }
15640 this.slot_block = owner.slots.get(name).block;
15641 block = this.slot_block;
15642 }
15643 }
15644 if (attribute.name === 'style') {
15645 return new StyleAttributeWrapper(this, block, attribute);
15646 }
15647 return new AttributeWrapper(this, block, attribute);
15648 });
15649 // ordinarily, there'll only be one... but we need to handle
15650 // the rare case where an element can have multiple bindings,
15651 // e.g. <audio bind:paused bind:currentTime>
15652 this.bindings = this.node.bindings.map(binding => new BindingWrapper(block, binding, this));
15653 if (node.intro || node.outro) {
15654 if (node.intro)
15655 block.add_intro(node.intro.is_local);
15656 if (node.outro)
15657 block.add_outro(node.outro.is_local);
15658 }
15659 if (node.animation) {
15660 block.add_animation();
15661 }
15662 // add directive and handler dependencies
15663 [node.animation, node.outro, ...node.actions, ...node.classes].forEach(directive => {
15664 if (directive && directive.expression) {
15665 block.add_dependencies(directive.expression.dependencies);
15666 }
15667 });
15668 node.handlers.forEach(handler => {
15669 if (handler.expression) {
15670 block.add_dependencies(handler.expression.dependencies);
15671 }
15672 });
15673 if (this.parent) {
15674 if (node.actions.length > 0)
15675 this.parent.cannot_use_innerhtml();
15676 if (node.animation)
15677 this.parent.cannot_use_innerhtml();
15678 if (node.bindings.length > 0)
15679 this.parent.cannot_use_innerhtml();
15680 if (node.classes.length > 0)
15681 this.parent.cannot_use_innerhtml();
15682 if (node.intro || node.outro)
15683 this.parent.cannot_use_innerhtml();
15684 if (node.handlers.length > 0)
15685 this.parent.cannot_use_innerhtml();
15686 if (this.node.name === 'option')
15687 this.parent.cannot_use_innerhtml();
15688 if (renderer.options.dev) {
15689 this.parent.cannot_use_innerhtml(); // need to use add_location
15690 }
15691 }
15692 this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling);
15693 if (this.slot_block) {
15694 block.parent.add_dependencies(block.dependencies);
15695 // appalling hack
15696 const index = block.parent.wrappers.indexOf(this);
15697 block.parent.wrappers.splice(index, 1);
15698 block.wrappers.push(this);
15699 }
15700 }
15701 render(block, parent_node, parent_nodes) {
15702 const { renderer } = this;
15703 if (this.node.name === 'noscript')
15704 return;
15705 if (this.slot_block) {
15706 block = this.slot_block;
15707 }
15708 const node = this.var;
15709 const nodes = parent_nodes && block.get_unique_name(`${this.var}_nodes`); // if we're in unclaimable territory, i.e. <head>, parent_nodes is null
15710 block.add_variable(node);
15711 const render_statement = this.get_render_statement();
15712 block.builders.create.add_line(`${node} = ${render_statement};`);
15713 if (renderer.options.hydratable) {
15714 if (parent_nodes) {
15715 block.builders.claim.add_block(deindent `
15716 ${node} = ${this.get_claim_statement(parent_nodes)};
15717 var ${nodes} = @children(${this.node.name === 'template' ? `${node}.content` : node});
15718 `);
15719 }
15720 else {
15721 block.builders.claim.add_line(`${node} = ${render_statement};`);
15722 }
15723 }
15724 if (parent_node) {
15725 block.builders.mount.add_line(`@append(${parent_node}, ${node});`);
15726 if (parent_node === '@_document.head') {
15727 block.builders.destroy.add_line(`@detach(${node});`);
15728 }
15729 }
15730 else {
15731 block.builders.mount.add_line(`@insert(#target, ${node}, anchor);`);
15732 // TODO we eventually need to consider what happens to elements
15733 // that belong to the same outgroup as an outroing element...
15734 block.builders.destroy.add_conditional('detaching', `@detach(${node});`);
15735 }
15736 // insert static children with textContent or innerHTML
15737 if (!this.node.namespace && this.can_use_innerhtml && this.fragment.nodes.length > 0) {
15738 if (this.fragment.nodes.length === 1 && this.fragment.nodes[0].node.type === 'Text') {
15739 block.builders.create.add_line(
15740 // @ts-ignore todo: should it be this.fragment.nodes[0].node.data instead?
15741 `${node}.textContent = ${stringify(this.fragment.nodes[0].data)};`);
15742 }
15743 else {
15744 const inner_html = escape(this.fragment.nodes
15745 .map(to_html)
15746 .join(''));
15747 block.builders.create.add_line(`${node}.innerHTML = \`${inner_html}\`;`);
15748 }
15749 }
15750 else {
15751 this.fragment.nodes.forEach((child) => {
15752 child.render(block, this.node.name === 'template' ? `${node}.content` : node, nodes);
15753 });
15754 }
15755 const event_handler_or_binding_uses_context = (this.bindings.some(binding => binding.handler.uses_context) ||
15756 this.node.handlers.some(handler => handler.uses_context) ||
15757 this.node.actions.some(action => action.uses_context));
15758 if (event_handler_or_binding_uses_context) {
15759 block.maintain_context = true;
15760 }
15761 this.add_bindings(block);
15762 this.add_event_handlers(block);
15763 this.add_attributes(block);
15764 this.add_transitions(block);
15765 this.add_animation(block);
15766 this.add_actions(block);
15767 this.add_classes(block);
15768 if (nodes && this.renderer.options.hydratable) {
15769 block.builders.claim.add_line(`${nodes}.forEach(@detach);`);
15770 }
15771 function to_html(wrapper) {
15772 if (wrapper.node.type === 'Text') {
15773 if (wrapper.use_space())
15774 return ' ';
15775 const parent = wrapper.node.parent;
15776 const raw = parent && (parent.name === 'script' ||
15777 parent.name === 'style');
15778 return (raw ? wrapper.node.data : escape_html(wrapper.node.data))
15779 .replace(/\\/g, '\\\\')
15780 .replace(/`/g, '\\`')
15781 .replace(/\$/g, '\\$');
15782 }
15783 if (wrapper.node.name === 'noscript')
15784 return '';
15785 let open = `<${wrapper.node.name}`;
15786 wrapper.attributes.forEach((attr) => {
15787 open += ` ${fix_attribute_casing(attr.node.name)}${attr.stringify()}`;
15788 });
15789 if (is_void(wrapper.node.name))
15790 return open + '>';
15791 return `${open}>${wrapper.fragment.nodes.map(to_html).join('')}</${wrapper.node.name}>`;
15792 }
15793 if (renderer.options.dev) {
15794 const loc = renderer.locate(this.node.start);
15795 block.builders.hydrate.add_line(`@add_location(${this.var}, ${renderer.file_var}, ${loc.line}, ${loc.column}, ${this.node.start});`);
15796 }
15797 }
15798 get_render_statement() {
15799 const { name, namespace } = this.node;
15800 if (namespace === 'http://www.w3.org/2000/svg') {
15801 return `@svg_element("${name}")`;
15802 }
15803 if (namespace) {
15804 return `@_document.createElementNS("${namespace}", "${name}")`;
15805 }
15806 return `@element("${name}")`;
15807 }
15808 get_claim_statement(nodes) {
15809 const attributes = this.node.attributes
15810 .filter((attr) => attr.type === 'Attribute')
15811 .map((attr) => `${quote_name_if_necessary(attr.name)}: true`)
15812 .join(', ');
15813 const name = this.node.namespace
15814 ? this.node.name
15815 : this.node.name.toUpperCase();
15816 return `@claim_element(${nodes}, "${name}", ${attributes
15817 ? `{ ${attributes} }`
15818 : `{}`}, ${this.node.namespace === namespaces.svg ? true : false})`;
15819 }
15820 add_bindings(block) {
15821 const { renderer } = this;
15822 if (this.bindings.length === 0)
15823 return;
15824 renderer.component.has_reactive_assignments = true;
15825 const lock = this.bindings.some(binding => binding.needs_lock) ?
15826 block.get_unique_name(`${this.var}_updating`) :
15827 null;
15828 if (lock)
15829 block.add_variable(lock, 'false');
15830 const groups = events
15831 .map(event => ({
15832 events: event.event_names,
15833 bindings: this.bindings
15834 .filter(binding => binding.node.name !== 'this')
15835 .filter(binding => event.filter(this.node, binding.node.name))
15836 }))
15837 .filter(group => group.bindings.length);
15838 groups.forEach(group => {
15839 const handler = renderer.component.get_unique_name(`${this.var}_${group.events.join('_')}_handler`);
15840 renderer.component.add_var({
15841 name: handler,
15842 internal: true,
15843 referenced: true
15844 });
15845 // TODO figure out how to handle locks
15846 const needs_lock = group.bindings.some(binding => binding.needs_lock);
15847 const dependencies = new Set();
15848 const contextual_dependencies = new Set();
15849 group.bindings.forEach(binding => {
15850 // TODO this is a mess
15851 add_to_set(dependencies, binding.get_dependencies());
15852 add_to_set(contextual_dependencies, binding.node.expression.contextual_dependencies);
15853 add_to_set(contextual_dependencies, binding.handler.contextual_dependencies);
15854 binding.render(block, lock);
15855 });
15856 // media bindings — awkward special case. The native timeupdate events
15857 // fire too infrequently, so we need to take matters into our
15858 // own hands
15859 let animation_frame;
15860 if (group.events[0] === 'timeupdate') {
15861 animation_frame = block.get_unique_name(`${this.var}_animationframe`);
15862 block.add_variable(animation_frame);
15863 }
15864 const has_local_function = contextual_dependencies.size > 0 || needs_lock || animation_frame;
15865 let callee;
15866 // TODO dry this out — similar code for event handlers and component bindings
15867 if (has_local_function) {
15868 // need to create a block-local function that calls an instance-level function
15869 block.builders.init.add_block(deindent `
15870 function ${handler}() {
15871 ${animation_frame && deindent `
15872 @_cancelAnimationFrame(${animation_frame});
15873 if (!${this.var}.paused) ${animation_frame} = @raf(${handler});`}
15874 ${needs_lock && `${lock} = true;`}
15875 ctx.${handler}.call(${this.var}${contextual_dependencies.size > 0 ? ', ctx' : ''});
15876 }
15877 `);
15878 callee = handler;
15879 }
15880 else {
15881 callee = `ctx.${handler}`;
15882 }
15883 this.renderer.component.partly_hoisted.push(deindent `
15884 function ${handler}(${contextual_dependencies.size > 0 ? `{ ${Array.from(contextual_dependencies).join(', ')} }` : ``}) {
15885 ${group.bindings.map(b => b.handler.mutation)}
15886 ${Array.from(dependencies).filter(dep => dep[0] !== '$').map(dep => `${this.renderer.component.invalidate(dep)};`)}
15887 }
15888 `);
15889 group.events.forEach(name => {
15890 if (name === 'resize') {
15891 // special case
15892 const resize_listener = block.get_unique_name(`${this.var}_resize_listener`);
15893 block.add_variable(resize_listener);
15894 block.builders.mount.add_line(`${resize_listener} = @add_resize_listener(${this.var}, ${callee}.bind(${this.var}));`);
15895 block.builders.destroy.add_line(`${resize_listener}.cancel();`);
15896 }
15897 else {
15898 block.event_listeners.push(`@listen(${this.var}, "${name}", ${callee})`);
15899 }
15900 });
15901 const some_initial_state_is_undefined = group.bindings
15902 .map(binding => `${binding.snippet} === void 0`)
15903 .join(' || ');
15904 const should_initialise = (this.node.name === 'select' ||
15905 group.bindings.find(binding => {
15906 return (binding.node.name === 'indeterminate' ||
15907 binding.node.name === 'textContent' ||
15908 binding.node.name === 'innerHTML' ||
15909 binding.is_readonly_media_attribute());
15910 }));
15911 if (should_initialise) {
15912 const callback = has_local_function ? handler : `() => ${callee}.call(${this.var})`;
15913 block.builders.hydrate.add_line(`if (${some_initial_state_is_undefined}) @add_render_callback(${callback});`);
15914 }
15915 if (group.events[0] === 'resize') {
15916 block.builders.hydrate.add_line(`@add_render_callback(() => ${callee}.call(${this.var}));`);
15917 }
15918 });
15919 if (lock) {
15920 block.builders.update.add_line(`${lock} = false;`);
15921 }
15922 const this_binding = this.bindings.find(b => b.node.name === 'this');
15923 if (this_binding) {
15924 const binding_callback = bind_this(renderer.component, block, this_binding.node, this.var);
15925 block.builders.mount.add_line(binding_callback);
15926 }
15927 }
15928 add_attributes(block) {
15929 // @ts-ignore todo:
15930 if (this.node.attributes.find(attr => attr.type === 'Spread')) {
15931 this.add_spread_attributes(block);
15932 return;
15933 }
15934 this.attributes.forEach((attribute) => {
15935 if (attribute.node.name === 'class' && attribute.node.is_dynamic) {
15936 this.class_dependencies.push(...attribute.node.dependencies);
15937 }
15938 attribute.render(block);
15939 });
15940 }
15941 add_spread_attributes(block) {
15942 const levels = block.get_unique_name(`${this.var}_levels`);
15943 const data = block.get_unique_name(`${this.var}_data`);
15944 const initial_props = [];
15945 const updates = [];
15946 this.node.attributes
15947 .filter(attr => attr.type === 'Attribute' || attr.type === 'Spread')
15948 .forEach(attr => {
15949 const condition = attr.dependencies.size > 0
15950 ? `(${[...attr.dependencies].map(d => `changed.${d}`).join(' || ')})`
15951 : null;
15952 if (attr.is_spread) {
15953 const snippet = attr.expression.render(block);
15954 initial_props.push(snippet);
15955 updates.push(condition ? `${condition} && ${snippet}` : snippet);
15956 }
15957 else {
15958 const snippet = `{ ${quote_name_if_necessary(attr.name)}: ${attr.get_value(block)} }`;
15959 initial_props.push(snippet);
15960 updates.push(condition ? `${condition} && ${snippet}` : snippet);
15961 }
15962 });
15963 block.builders.init.add_block(deindent `
15964 var ${levels} = [
15965 ${initial_props.join(',\n')}
15966 ];
15967
15968 var ${data} = {};
15969 for (var #i = 0; #i < ${levels}.length; #i += 1) {
15970 ${data} = @assign(${data}, ${levels}[#i]);
15971 }
15972 `);
15973 block.builders.hydrate.add_line(`@set_attributes(${this.var}, ${data});`);
15974 block.builders.update.add_block(deindent `
15975 @set_attributes(${this.var}, @get_spread_update(${levels}, [
15976 ${updates.join(',\n')}
15977 ]));
15978 `);
15979 }
15980 add_event_handlers(block) {
15981 add_event_handlers(block, this.var, this.node.handlers);
15982 }
15983 add_transitions(block) {
15984 const { intro, outro } = this.node;
15985 if (!intro && !outro)
15986 return;
15987 const { component } = this.renderer;
15988 if (intro === outro) {
15989 // bidirectional transition
15990 const name = block.get_unique_name(`${this.var}_transition`);
15991 const snippet = intro.expression
15992 ? intro.expression.render(block)
15993 : '{}';
15994 block.add_variable(name);
15995 const fn = component.qualify(intro.name);
15996 const intro_block = deindent `
15997 @add_render_callback(() => {
15998 if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, true);
15999 ${name}.run(1);
16000 });
16001 `;
16002 const outro_block = deindent `
16003 if (!${name}) ${name} = @create_bidirectional_transition(${this.var}, ${fn}, ${snippet}, false);
16004 ${name}.run(0);
16005 `;
16006 if (intro.is_local) {
16007 block.builders.intro.add_block(deindent `
16008 if (#local) {
16009 ${intro_block}
16010 }
16011 `);
16012 block.builders.outro.add_block(deindent `
16013 if (#local) {
16014 ${outro_block}
16015 }
16016 `);
16017 }
16018 else {
16019 block.builders.intro.add_block(intro_block);
16020 block.builders.outro.add_block(outro_block);
16021 }
16022 block.builders.destroy.add_conditional('detaching', `if (${name}) ${name}.end();`);
16023 }
16024 else {
16025 const intro_name = intro && block.get_unique_name(`${this.var}_intro`);
16026 const outro_name = outro && block.get_unique_name(`${this.var}_outro`);
16027 if (intro) {
16028 block.add_variable(intro_name);
16029 const snippet = intro.expression
16030 ? intro.expression.render(block)
16031 : '{}';
16032 const fn = component.qualify(intro.name);
16033 let intro_block;
16034 if (outro) {
16035 intro_block = deindent `
16036 @add_render_callback(() => {
16037 if (${outro_name}) ${outro_name}.end(1);
16038 if (!${intro_name}) ${intro_name} = @create_in_transition(${this.var}, ${fn}, ${snippet});
16039 ${intro_name}.start();
16040 });
16041 `;
16042 block.builders.outro.add_line(`if (${intro_name}) ${intro_name}.invalidate();`);
16043 }
16044 else {
16045 intro_block = deindent `
16046 if (!${intro_name}) {
16047 @add_render_callback(() => {
16048 ${intro_name} = @create_in_transition(${this.var}, ${fn}, ${snippet});
16049 ${intro_name}.start();
16050 });
16051 }
16052 `;
16053 }
16054 if (intro.is_local) {
16055 intro_block = deindent `
16056 if (#local) {
16057 ${intro_block}
16058 }
16059 `;
16060 }
16061 block.builders.intro.add_block(intro_block);
16062 }
16063 if (outro) {
16064 block.add_variable(outro_name);
16065 const snippet = outro.expression
16066 ? outro.expression.render(block)
16067 : '{}';
16068 const fn = component.qualify(outro.name);
16069 if (!intro) {
16070 block.builders.intro.add_block(deindent `
16071 if (${outro_name}) ${outro_name}.end(1);
16072 `);
16073 }
16074 // TODO hide elements that have outro'd (unless they belong to a still-outroing
16075 // group) prior to their removal from the DOM
16076 let outro_block = deindent `
16077 ${outro_name} = @create_out_transition(${this.var}, ${fn}, ${snippet});
16078 `;
16079 if (outro.is_local) {
16080 outro_block = deindent `
16081 if (#local) {
16082 ${outro_block}
16083 }
16084 `;
16085 }
16086 block.builders.outro.add_block(outro_block);
16087 block.builders.destroy.add_conditional('detaching', `if (${outro_name}) ${outro_name}.end();`);
16088 }
16089 }
16090 }
16091 add_animation(block) {
16092 if (!this.node.animation)
16093 return;
16094 const { component } = this.renderer;
16095 const { outro } = this.node;
16096 const rect = block.get_unique_name('rect');
16097 const stop_animation = block.get_unique_name('stop_animation');
16098 block.add_variable(rect);
16099 block.add_variable(stop_animation, '@noop');
16100 block.builders.measure.add_block(deindent `
16101 ${rect} = ${this.var}.getBoundingClientRect();
16102 `);
16103 block.builders.fix.add_block(deindent `
16104 @fix_position(${this.var});
16105 ${stop_animation}();
16106 ${outro && `@add_transform(${this.var}, ${rect});`}
16107 `);
16108 const params = this.node.animation.expression ? this.node.animation.expression.render(block) : '{}';
16109 const name = component.qualify(this.node.animation.name);
16110 block.builders.animate.add_block(deindent `
16111 ${stop_animation}();
16112 ${stop_animation} = @create_animation(${this.var}, ${rect}, ${name}, ${params});
16113 `);
16114 }
16115 add_actions(block) {
16116 add_actions(this.renderer.component, block, this.var, this.node.actions);
16117 }
16118 add_classes(block) {
16119 this.node.classes.forEach(class_directive => {
16120 const { expression, name } = class_directive;
16121 let snippet;
16122 let dependencies;
16123 if (expression) {
16124 snippet = expression.render(block);
16125 dependencies = expression.dependencies;
16126 }
16127 else {
16128 snippet = `${quote_prop_if_necessary(name)}`;
16129 dependencies = new Set([name]);
16130 }
16131 const updater = `@toggle_class(${this.var}, "${name}", ${snippet});`;
16132 block.builders.hydrate.add_line(updater);
16133 if ((dependencies && dependencies.size > 0) || this.class_dependencies.length) {
16134 const all_dependencies = this.class_dependencies.concat(...dependencies);
16135 const deps = all_dependencies.map(dependency => `changed${quote_prop_if_necessary(dependency)}`).join(' || ');
16136 const condition = all_dependencies.length > 1 ? `(${deps})` : deps;
16137 block.builders.update.add_conditional(condition, updater);
16138 }
16139 });
16140 }
16141 }
16142
16143 class HeadWrapper extends Wrapper {
16144 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
16145 super(renderer, block, parent, node);
16146 this.can_use_innerhtml = false;
16147 this.fragment = new FragmentWrapper(renderer, block, node.children, this, strip_whitespace, next_sibling);
16148 }
16149 render(block, _parent_node, _parent_nodes) {
16150 this.fragment.render(block, '@_document.head', 'nodes');
16151 }
16152 }
16153
16154 function is_else_if(node) {
16155 return (node && node.children.length === 1 && node.children[0].type === 'IfBlock');
16156 }
16157 class IfBlockBranch extends Wrapper {
16158 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
16159 super(renderer, block, parent, node);
16160 this.var = null;
16161 this.condition = node.expression && node.expression.render(block);
16162 this.block = block.child({
16163 comment: create_debugging_comment(node, parent.renderer.component),
16164 name: parent.renderer.component.get_unique_name(node.expression ? `create_if_block` : `create_else_block`)
16165 });
16166 this.fragment = new FragmentWrapper(renderer, this.block, node.children, parent, strip_whitespace, next_sibling);
16167 this.is_dynamic = this.block.dependencies.size > 0;
16168 }
16169 }
16170 class IfBlockWrapper extends Wrapper {
16171 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
16172 super(renderer, block, parent, node);
16173 this.var = 'if_block';
16174 this.cannot_use_innerhtml();
16175 this.branches = [];
16176 const blocks = [];
16177 let is_dynamic = false;
16178 let has_intros = false;
16179 let has_outros = false;
16180 const create_branches = (node) => {
16181 const branch = new IfBlockBranch(renderer, block, this, node, strip_whitespace, next_sibling);
16182 this.branches.push(branch);
16183 blocks.push(branch.block);
16184 block.add_dependencies(node.expression.dependencies);
16185 if (branch.block.dependencies.size > 0) {
16186 is_dynamic = true;
16187 block.add_dependencies(branch.block.dependencies);
16188 }
16189 if (branch.block.has_intros)
16190 has_intros = true;
16191 if (branch.block.has_outros)
16192 has_outros = true;
16193 if (is_else_if(node.else)) {
16194 create_branches(node.else.children[0]);
16195 }
16196 else if (node.else) {
16197 const branch = new IfBlockBranch(renderer, block, this, node.else, strip_whitespace, next_sibling);
16198 this.branches.push(branch);
16199 blocks.push(branch.block);
16200 if (branch.block.dependencies.size > 0) {
16201 is_dynamic = true;
16202 block.add_dependencies(branch.block.dependencies);
16203 }
16204 if (branch.block.has_intros)
16205 has_intros = true;
16206 if (branch.block.has_outros)
16207 has_outros = true;
16208 }
16209 };
16210 create_branches(this.node);
16211 blocks.forEach(block => {
16212 block.has_update_method = is_dynamic;
16213 block.has_intro_method = has_intros;
16214 block.has_outro_method = has_outros;
16215 });
16216 renderer.blocks.push(...blocks);
16217 }
16218 render(block, parent_node, parent_nodes) {
16219 const name = this.var;
16220 const needs_anchor = this.next ? !this.next.is_dom_node() : !parent_node || !this.parent.is_dom_node();
16221 const anchor = needs_anchor
16222 ? block.get_unique_name(`${name}_anchor`)
16223 : (this.next && this.next.var) || 'null';
16224 const has_else = !(this.branches[this.branches.length - 1].condition);
16225 const if_name = has_else ? '' : `if (${name}) `;
16226 const dynamic = this.branches[0].block.has_update_method; // can use [0] as proxy for all, since they necessarily have the same value
16227 const has_intros = this.branches[0].block.has_intro_method;
16228 const has_outros = this.branches[0].block.has_outro_method;
16229 const has_transitions = has_intros || has_outros;
16230 const vars = { name, anchor, if_name, has_else, has_transitions };
16231 const detaching = (parent_node && parent_node !== '@_document.head') ? '' : 'detaching';
16232 if (this.node.else) {
16233 if (has_outros) {
16234 this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching);
16235 block.builders.outro.add_line(`@transition_out(${name});`);
16236 }
16237 else {
16238 this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching);
16239 }
16240 }
16241 else {
16242 this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching);
16243 if (has_outros) {
16244 block.builders.outro.add_line(`@transition_out(${name});`);
16245 }
16246 }
16247 block.builders.create.add_line(`${if_name}${name}.c();`);
16248 if (parent_nodes && this.renderer.options.hydratable) {
16249 block.builders.claim.add_line(`${if_name}${name}.l(${parent_nodes});`);
16250 }
16251 if (has_intros || has_outros) {
16252 block.builders.intro.add_line(`@transition_in(${name});`);
16253 }
16254 if (needs_anchor) {
16255 block.add_element(anchor, `@empty()`, parent_nodes && `@empty()`, parent_node);
16256 }
16257 this.branches.forEach(branch => {
16258 branch.fragment.render(branch.block, null, 'nodes');
16259 });
16260 }
16261 render_compound(block, parent_node, _parent_nodes, dynamic, { name, anchor, has_else, if_name, has_transitions }, detaching) {
16262 const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
16263 const current_block_type = block.get_unique_name(`current_block_type`);
16264 const current_block_type_and = has_else ? '' : `${current_block_type} && `;
16265 /* eslint-disable @typescript-eslint/indent,indent */
16266 block.builders.init.add_block(deindent `
16267 function ${select_block_type}(ctx) {
16268 ${this.branches
16269 .map(({ condition, block }) => `${condition ? `if (${condition}) ` : ''}return ${block.name};`)
16270 .join('\n')}
16271 }
16272 `);
16273 /* eslint-enable @typescript-eslint/indent,indent */
16274 block.builders.init.add_block(deindent `
16275 var ${current_block_type} = ${select_block_type}(ctx);
16276 var ${name} = ${current_block_type_and}${current_block_type}(ctx);
16277 `);
16278 const initial_mount_node = parent_node || '#target';
16279 const anchor_node = parent_node ? 'null' : 'anchor';
16280 block.builders.mount.add_line(`${if_name}${name}.m(${initial_mount_node}, ${anchor_node});`);
16281 const update_mount_node = this.get_update_mount_node(anchor);
16282 const change_block = deindent `
16283 ${if_name}${name}.d(1);
16284 ${name} = ${current_block_type_and}${current_block_type}(ctx);
16285 if (${name}) {
16286 ${name}.c();
16287 ${has_transitions && `@transition_in(${name}, 1);`}
16288 ${name}.m(${update_mount_node}, ${anchor});
16289 }
16290 `;
16291 if (dynamic) {
16292 block.builders.update.add_block(deindent `
16293 if (${current_block_type} === (${current_block_type} = ${select_block_type}(ctx)) && ${name}) {
16294 ${name}.p(changed, ctx);
16295 } else {
16296 ${change_block}
16297 }
16298 `);
16299 }
16300 else {
16301 block.builders.update.add_block(deindent `
16302 if (${current_block_type} !== (${current_block_type} = ${select_block_type}(ctx))) {
16303 ${change_block}
16304 }
16305 `);
16306 }
16307 block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
16308 }
16309 // if any of the siblings have outros, we need to keep references to the blocks
16310 // (TODO does this only apply to bidi transitions?)
16311 render_compound_with_outros(block, parent_node, _parent_nodes, dynamic, { name, anchor, has_else, has_transitions }, detaching) {
16312 const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
16313 const current_block_type_index = block.get_unique_name(`current_block_type_index`);
16314 const previous_block_index = block.get_unique_name(`previous_block_index`);
16315 const if_block_creators = block.get_unique_name(`if_block_creators`);
16316 const if_blocks = block.get_unique_name(`if_blocks`);
16317 const if_current_block_type_index = has_else
16318 ? ''
16319 : `if (~${current_block_type_index}) `;
16320 block.add_variable(current_block_type_index);
16321 block.add_variable(name);
16322 /* eslint-disable @typescript-eslint/indent,indent */
16323 block.builders.init.add_block(deindent `
16324 var ${if_block_creators} = [
16325 ${this.branches.map(branch => branch.block.name).join(',\n')}
16326 ];
16327
16328 var ${if_blocks} = [];
16329
16330 function ${select_block_type}(ctx) {
16331 ${this.branches
16332 .map(({ condition }, i) => `${condition ? `if (${condition}) ` : ''}return ${i};`)
16333 .join('\n')}
16334 ${!has_else && `return -1;`}
16335 }
16336 `);
16337 /* eslint-enable @typescript-eslint/indent,indent */
16338 if (has_else) {
16339 block.builders.init.add_block(deindent `
16340 ${current_block_type_index} = ${select_block_type}(ctx);
16341 ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
16342 `);
16343 }
16344 else {
16345 block.builders.init.add_block(deindent `
16346 if (~(${current_block_type_index} = ${select_block_type}(ctx))) {
16347 ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
16348 }
16349 `);
16350 }
16351 const initial_mount_node = parent_node || '#target';
16352 const anchor_node = parent_node ? 'null' : 'anchor';
16353 block.builders.mount.add_line(`${if_current_block_type_index}${if_blocks}[${current_block_type_index}].m(${initial_mount_node}, ${anchor_node});`);
16354 const update_mount_node = this.get_update_mount_node(anchor);
16355 const destroy_old_block = deindent `
16356 @group_outros();
16357 @transition_out(${if_blocks}[${previous_block_index}], 1, 1, () => {
16358 ${if_blocks}[${previous_block_index}] = null;
16359 });
16360 @check_outros();
16361 `;
16362 const create_new_block = deindent `
16363 ${name} = ${if_blocks}[${current_block_type_index}];
16364 if (!${name}) {
16365 ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](ctx);
16366 ${name}.c();
16367 }
16368 ${has_transitions && `@transition_in(${name}, 1);`}
16369 ${name}.m(${update_mount_node}, ${anchor});
16370 `;
16371 const change_block = has_else
16372 ? deindent `
16373 ${destroy_old_block}
16374
16375 ${create_new_block}
16376 `
16377 : deindent `
16378 if (${name}) {
16379 ${destroy_old_block}
16380 }
16381
16382 if (~${current_block_type_index}) {
16383 ${create_new_block}
16384 } else {
16385 ${name} = null;
16386 }
16387 `;
16388 if (dynamic) {
16389 block.builders.update.add_block(deindent `
16390 var ${previous_block_index} = ${current_block_type_index};
16391 ${current_block_type_index} = ${select_block_type}(ctx);
16392 if (${current_block_type_index} === ${previous_block_index}) {
16393 ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(changed, ctx);
16394 } else {
16395 ${change_block}
16396 }
16397 `);
16398 }
16399 else {
16400 block.builders.update.add_block(deindent `
16401 var ${previous_block_index} = ${current_block_type_index};
16402 ${current_block_type_index} = ${select_block_type}(ctx);
16403 if (${current_block_type_index} !== ${previous_block_index}) {
16404 ${change_block}
16405 }
16406 `);
16407 }
16408 block.builders.destroy.add_line(deindent `
16409 ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${detaching});
16410 `);
16411 }
16412 render_simple(block, parent_node, _parent_nodes, dynamic, { name, anchor, if_name, has_transitions }, detaching) {
16413 const branch = this.branches[0];
16414 block.builders.init.add_block(deindent `
16415 var ${name} = (${branch.condition}) && ${branch.block.name}(ctx);
16416 `);
16417 const initial_mount_node = parent_node || '#target';
16418 const anchor_node = parent_node ? 'null' : 'anchor';
16419 block.builders.mount.add_line(`if (${name}) ${name}.m(${initial_mount_node}, ${anchor_node});`);
16420 const update_mount_node = this.get_update_mount_node(anchor);
16421 const enter = dynamic
16422 ? deindent `
16423 if (${name}) {
16424 ${name}.p(changed, ctx);
16425 ${has_transitions && `@transition_in(${name}, 1);`}
16426 } else {
16427 ${name} = ${branch.block.name}(ctx);
16428 ${name}.c();
16429 ${has_transitions && `@transition_in(${name}, 1);`}
16430 ${name}.m(${update_mount_node}, ${anchor});
16431 }
16432 `
16433 : deindent `
16434 if (!${name}) {
16435 ${name} = ${branch.block.name}(ctx);
16436 ${name}.c();
16437 ${has_transitions && `@transition_in(${name}, 1);`}
16438 ${name}.m(${update_mount_node}, ${anchor});
16439 ${has_transitions && `} else {
16440 @transition_in(${name}, 1);`}
16441 }
16442 `;
16443 // no `p()` here — we don't want to update outroing nodes,
16444 // as that will typically result in glitching
16445 if (branch.block.has_outro_method) {
16446 block.builders.update.add_block(deindent `
16447 if (${branch.condition}) {
16448 ${enter}
16449 } else if (${name}) {
16450 @group_outros();
16451 @transition_out(${name}, 1, 1, () => {
16452 ${name} = null;
16453 });
16454 @check_outros();
16455 }
16456 `);
16457 }
16458 else {
16459 block.builders.update.add_block(deindent `
16460 if (${branch.condition}) {
16461 ${enter}
16462 } else if (${name}) {
16463 ${name}.d(1);
16464 ${name} = null;
16465 }
16466 `);
16467 }
16468 block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
16469 }
16470 }
16471
16472 function stringify_props(props) {
16473 if (!props.length)
16474 return '{}';
16475 const joined = props.join(', ');
16476 if (joined.length > 40) {
16477 // make larger data objects readable
16478 return `{\n\t${props.join(',\n\t')}\n}`;
16479 }
16480 return `{ ${joined} }`;
16481 }
16482
16483 function is_dynamic$1(variable) {
16484 if (variable) {
16485 if (variable.mutated || variable.reassigned)
16486 return true; // dynamic internal state
16487 if (!variable.module && variable.writable && variable.export_name)
16488 return true; // writable props
16489 }
16490 return false;
16491 }
16492
16493 class InlineComponentWrapper extends Wrapper {
16494 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
16495 super(renderer, block, parent, node);
16496 this.slots = new Map();
16497 this.cannot_use_innerhtml();
16498 if (this.node.expression) {
16499 block.add_dependencies(this.node.expression.dependencies);
16500 }
16501 this.node.attributes.forEach(attr => {
16502 block.add_dependencies(attr.dependencies);
16503 });
16504 this.node.bindings.forEach(binding => {
16505 if (binding.is_contextual) {
16506 // we need to ensure that the each block creates a context including
16507 // the list and the index, if they're not otherwise referenced
16508 const { name } = get_object(binding.expression.node);
16509 const each_block = this.node.scope.get_owner(name);
16510 each_block.has_binding = true;
16511 }
16512 block.add_dependencies(binding.expression.dependencies);
16513 });
16514 this.node.handlers.forEach(handler => {
16515 if (handler.expression) {
16516 block.add_dependencies(handler.expression.dependencies);
16517 }
16518 });
16519 this.var = (this.node.name === 'svelte:self' ? renderer.component.name :
16520 this.node.name === 'svelte:component' ? 'switch_instance' :
16521 sanitize(this.node.name)).toLowerCase();
16522 if (this.node.children.length) {
16523 const default_slot = block.child({
16524 comment: create_debugging_comment(node, renderer.component),
16525 name: renderer.component.get_unique_name(`create_default_slot`)
16526 });
16527 this.renderer.blocks.push(default_slot);
16528 const fn = get_context_merger(this.node.lets);
16529 this.slots.set('default', {
16530 block: default_slot,
16531 scope: this.node.scope,
16532 fn
16533 });
16534 this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, strip_whitespace, next_sibling);
16535 const dependencies = new Set();
16536 // TODO is this filtering necessary? (I *think* so)
16537 default_slot.dependencies.forEach(name => {
16538 if (!this.node.scope.is_let(name)) {
16539 dependencies.add(name);
16540 }
16541 });
16542 block.add_dependencies(dependencies);
16543 }
16544 block.add_outro();
16545 }
16546 render(block, parent_node, parent_nodes) {
16547 const { renderer } = this;
16548 const { component } = renderer;
16549 const name = this.var;
16550 const component_opts = [];
16551 const statements = [];
16552 const updates = [];
16553 let props;
16554 const name_changes = block.get_unique_name(`${name}_changes`);
16555 const uses_spread = !!this.node.attributes.find(a => a.is_spread);
16556 const slot_props = Array.from(this.slots).map(([name, slot]) => `${quote_name_if_necessary(name)}: [${slot.block.name}${slot.fn ? `, ${slot.fn}` : ''}]`);
16557 const initial_props = slot_props.length > 0
16558 ? [`$$slots: ${stringify_props(slot_props)}`, `$$scope: { ctx }`]
16559 : [];
16560 const attribute_object = uses_spread
16561 ? stringify_props(initial_props)
16562 : stringify_props(this.node.attributes.map(attr => `${quote_name_if_necessary(attr.name)}: ${attr.get_value(block)}`).concat(initial_props));
16563 if (this.node.attributes.length || this.node.bindings.length || initial_props.length) {
16564 if (!uses_spread && this.node.bindings.length === 0) {
16565 component_opts.push(`props: ${attribute_object}`);
16566 }
16567 else {
16568 props = block.get_unique_name(`${name}_props`);
16569 component_opts.push(`props: ${props}`);
16570 }
16571 }
16572 if (this.fragment) {
16573 const default_slot = this.slots.get('default');
16574 this.fragment.nodes.forEach((child) => {
16575 child.render(default_slot.block, null, 'nodes');
16576 });
16577 }
16578 if (component.compile_options.dev) {
16579 // TODO this is a terrible hack, but without it the component
16580 // will complain that options.target is missing. This would
16581 // work better if components had separate public and private
16582 // APIs
16583 component_opts.push(`$$inline: true`);
16584 }
16585 const fragment_dependencies = new Set(this.fragment ? ['$$scope'] : []);
16586 this.slots.forEach(slot => {
16587 slot.block.dependencies.forEach(name => {
16588 const is_let = slot.scope.is_let(name);
16589 const variable = renderer.component.var_lookup.get(name);
16590 if (is_let || is_dynamic$1(variable))
16591 fragment_dependencies.add(name);
16592 });
16593 });
16594 const non_let_dependencies = Array.from(fragment_dependencies).filter(name => !this.node.scope.is_let(name));
16595 if (!uses_spread && (this.node.attributes.filter(a => a.is_dynamic).length || this.node.bindings.length || non_let_dependencies.length > 0)) {
16596 updates.push(`var ${name_changes} = {};`);
16597 }
16598 if (this.node.attributes.length) {
16599 if (uses_spread) {
16600 const levels = block.get_unique_name(`${this.var}_spread_levels`);
16601 const initial_props = [];
16602 const changes = [];
16603 const all_dependencies = new Set();
16604 this.node.attributes.forEach(attr => {
16605 add_to_set(all_dependencies, attr.dependencies);
16606 });
16607 this.node.attributes.forEach(attr => {
16608 const { name, dependencies } = attr;
16609 const condition = dependencies.size > 0 && (dependencies.size !== all_dependencies.size)
16610 ? `(${Array.from(dependencies).map(d => `changed.${d}`).join(' || ')})`
16611 : null;
16612 if (attr.is_spread) {
16613 const value = attr.expression.render(block);
16614 initial_props.push(value);
16615 changes.push(condition ? `${condition} && ${value}` : value);
16616 }
16617 else {
16618 const obj = `{ ${quote_name_if_necessary(name)}: ${attr.get_value(block)} }`;
16619 initial_props.push(obj);
16620 changes.push(condition ? `${condition} && ${obj}` : obj);
16621 }
16622 });
16623 block.builders.init.add_block(deindent `
16624 var ${levels} = [
16625 ${initial_props.join(',\n')}
16626 ];
16627 `);
16628 statements.push(deindent `
16629 for (var #i = 0; #i < ${levels}.length; #i += 1) {
16630 ${props} = @assign(${props}, ${levels}[#i]);
16631 }
16632 `);
16633 const conditions = Array.from(all_dependencies).map(dep => `changed.${dep}`).join(' || ');
16634 updates.push(deindent `
16635 var ${name_changes} = ${all_dependencies.size === 1 ? `${conditions}` : `(${conditions})`} ? @get_spread_update(${levels}, [
16636 ${changes.join(',\n')}
16637 ]) : {};
16638 `);
16639 }
16640 else {
16641 this.node.attributes
16642 .filter((attribute) => attribute.is_dynamic)
16643 .forEach((attribute) => {
16644 if (attribute.dependencies.size > 0) {
16645 /* eslint-disable @typescript-eslint/indent,indent */
16646 updates.push(deindent `
16647 if (${[...attribute.dependencies]
16648 .map(dependency => `changed.${dependency}`)
16649 .join(' || ')}) ${name_changes}${quote_prop_if_necessary(attribute.name)} = ${attribute.get_value(block)};
16650 `);
16651 /* eslint-enable @typescript-eslint/indent,indent */
16652 }
16653 });
16654 }
16655 }
16656 if (non_let_dependencies.length > 0) {
16657 updates.push(`if (${non_let_dependencies.map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed, ctx };`);
16658 }
16659 const munged_bindings = this.node.bindings.map(binding => {
16660 component.has_reactive_assignments = true;
16661 if (binding.name === 'this') {
16662 return bind_this(component, block, binding, this.var);
16663 }
16664 const name = component.get_unique_name(`${this.var}_${binding.name}_binding`);
16665 component.add_var({
16666 name,
16667 internal: true,
16668 referenced: true
16669 });
16670 const updating = block.get_unique_name(`updating_${binding.name}`);
16671 block.add_variable(updating);
16672 const snippet = binding.expression.render(block);
16673 statements.push(deindent `
16674 if (${snippet} !== void 0) {
16675 ${props}${quote_prop_if_necessary(binding.name)} = ${snippet};
16676 }`);
16677 updates.push(deindent `
16678 if (!${updating} && ${[...binding.expression.dependencies].map((dependency) => `changed.${dependency}`).join(' || ')}) {
16679 ${name_changes}${quote_prop_if_necessary(binding.name)} = ${snippet};
16680 }
16681 `);
16682 const contextual_dependencies = Array.from(binding.expression.contextual_dependencies);
16683 const dependencies = Array.from(binding.expression.dependencies);
16684 let lhs = component.source.slice(binding.expression.node.start, binding.expression.node.end).trim();
16685 if (binding.is_contextual && binding.expression.node.type === 'Identifier') {
16686 // bind:x={y} — we can't just do `y = x`, we need to
16687 // to `array[index] = x;
16688 const { name } = binding.expression.node;
16689 const { object, property, snippet } = block.bindings.get(name);
16690 lhs = snippet;
16691 contextual_dependencies.push(object, property);
16692 }
16693 const value = block.get_unique_name('value');
16694 const args = [value];
16695 if (contextual_dependencies.length > 0) {
16696 args.push(`{ ${contextual_dependencies.join(', ')} }`);
16697 block.builders.init.add_block(deindent `
16698 function ${name}(${value}) {
16699 ctx.${name}.call(null, ${value}, ctx);
16700 ${updating} = true;
16701 @add_flush_callback(() => ${updating} = false);
16702 }
16703 `);
16704 block.maintain_context = true; // TODO put this somewhere more logical
16705 }
16706 else {
16707 block.builders.init.add_block(deindent `
16708 function ${name}(${value}) {
16709 ctx.${name}.call(null, ${value});
16710 ${updating} = true;
16711 @add_flush_callback(() => ${updating} = false);
16712 }
16713 `);
16714 }
16715 const body = deindent `
16716 function ${name}(${args.join(', ')}) {
16717 ${lhs} = ${value};
16718 ${component.invalidate(dependencies[0])};
16719 }
16720 `;
16721 component.partly_hoisted.push(body);
16722 return `@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${name}));`;
16723 });
16724 const munged_handlers = this.node.handlers.map(handler => {
16725 let snippet = handler.render(block);
16726 if (handler.modifiers.has('once'))
16727 snippet = `@once(${snippet})`;
16728 return `${name}.$on("${handler.name}", ${snippet});`;
16729 });
16730 if (this.node.name === 'svelte:component') {
16731 const switch_value = block.get_unique_name('switch_value');
16732 const switch_props = block.get_unique_name('switch_props');
16733 const snippet = this.node.expression.render(block);
16734 block.builders.init.add_block(deindent `
16735 var ${switch_value} = ${snippet};
16736
16737 function ${switch_props}(ctx) {
16738 ${(this.node.attributes.length || this.node.bindings.length) && deindent `
16739 ${props && `let ${props} = ${attribute_object};`}`}
16740 ${statements}
16741 return ${stringify_props(component_opts)};
16742 }
16743
16744 if (${switch_value}) {
16745 var ${name} = new ${switch_value}(${switch_props}(ctx));
16746
16747 ${munged_bindings}
16748 ${munged_handlers}
16749 }
16750 `);
16751 block.builders.create.add_line(`if (${name}) ${name}.$$.fragment.c();`);
16752 if (parent_nodes && this.renderer.options.hydratable) {
16753 block.builders.claim.add_line(`if (${name}) ${name}.$$.fragment.l(${parent_nodes});`);
16754 }
16755 block.builders.mount.add_block(deindent `
16756 if (${name}) {
16757 @mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : 'anchor'});
16758 }
16759 `);
16760 const anchor = this.get_or_create_anchor(block, parent_node, parent_nodes);
16761 const update_mount_node = this.get_update_mount_node(anchor);
16762 if (updates.length) {
16763 block.builders.update.add_block(deindent `
16764 ${updates}
16765 `);
16766 }
16767 block.builders.update.add_block(deindent `
16768 if (${switch_value} !== (${switch_value} = ${snippet})) {
16769 if (${name}) {
16770 @group_outros();
16771 const old_component = ${name};
16772 @transition_out(old_component.$$.fragment, 1, 0, () => {
16773 @destroy_component(old_component, 1);
16774 });
16775 @check_outros();
16776 }
16777
16778 if (${switch_value}) {
16779 ${name} = new ${switch_value}(${switch_props}(ctx));
16780
16781 ${munged_bindings}
16782 ${munged_handlers}
16783
16784 ${name}.$$.fragment.c();
16785 @transition_in(${name}.$$.fragment, 1);
16786 @mount_component(${name}, ${update_mount_node}, ${anchor});
16787 } else {
16788 ${name} = null;
16789 }
16790 }
16791 `);
16792 block.builders.intro.add_block(deindent `
16793 if (${name}) @transition_in(${name}.$$.fragment, #local);
16794 `);
16795 if (updates.length) {
16796 block.builders.update.add_block(deindent `
16797 else if (${switch_value}) {
16798 ${name}.$set(${name_changes});
16799 }
16800 `);
16801 }
16802 block.builders.outro.add_line(`if (${name}) @transition_out(${name}.$$.fragment, #local);`);
16803 block.builders.destroy.add_line(`if (${name}) @destroy_component(${name}, ${parent_node ? '' : 'detaching'});`);
16804 }
16805 else {
16806 const expression = this.node.name === 'svelte:self'
16807 ? '__svelte:self__' // TODO conflict-proof this
16808 : component.qualify(this.node.name);
16809 block.builders.init.add_block(deindent `
16810 ${(this.node.attributes.length || this.node.bindings.length) && deindent `
16811 ${props && `let ${props} = ${attribute_object};`}`}
16812 ${statements}
16813 var ${name} = new ${expression}(${stringify_props(component_opts)});
16814
16815 ${munged_bindings}
16816 ${munged_handlers}
16817 `);
16818 block.builders.create.add_line(`${name}.$$.fragment.c();`);
16819 if (parent_nodes && this.renderer.options.hydratable) {
16820 block.builders.claim.add_line(`${name}.$$.fragment.l(${parent_nodes});`);
16821 }
16822 block.builders.mount.add_line(`@mount_component(${name}, ${parent_node || '#target'}, ${parent_node ? 'null' : 'anchor'});`);
16823 block.builders.intro.add_block(deindent `
16824 @transition_in(${name}.$$.fragment, #local);
16825 `);
16826 if (updates.length) {
16827 block.builders.update.add_block(deindent `
16828 ${updates}
16829 ${name}.$set(${name_changes});
16830 `);
16831 }
16832 block.builders.destroy.add_block(deindent `
16833 @destroy_component(${name}, ${parent_node ? '' : 'detaching'});
16834 `);
16835 block.builders.outro.add_line(`@transition_out(${name}.$$.fragment, #local);`);
16836 }
16837 }
16838 }
16839
16840 class Tag extends Wrapper {
16841 constructor(renderer, block, parent, node) {
16842 super(renderer, block, parent, node);
16843 this.cannot_use_innerhtml();
16844 block.add_dependencies(node.expression.dependencies);
16845 }
16846 rename_this_method(block, update) {
16847 const dependencies = this.node.expression.dynamic_dependencies();
16848 const snippet = this.node.expression.render(block);
16849 const value = this.node.should_cache && block.get_unique_name(`${this.var}_value`);
16850 const content = this.node.should_cache ? value : snippet;
16851 if (this.node.should_cache)
16852 block.add_variable(value, snippet);
16853 if (dependencies.length > 0) {
16854 const changed_check = ((block.has_outros ? `!#current || ` : '') +
16855 dependencies.map((dependency) => `changed.${dependency}`).join(' || '));
16856 const update_cached_value = `${value} !== (${value} = ${snippet})`;
16857 const condition = this.node.should_cache
16858 ? `(${changed_check}) && ${update_cached_value}`
16859 : changed_check;
16860 block.builders.update.add_conditional(condition, update(content));
16861 }
16862 return { init: content };
16863 }
16864 }
16865
16866 class MustacheTagWrapper extends Tag {
16867 constructor(renderer, block, parent, node) {
16868 super(renderer, block, parent, node);
16869 this.var = 't';
16870 this.cannot_use_innerhtml();
16871 }
16872 render(block, parent_node, parent_nodes) {
16873 const { init } = this.rename_this_method(block, value => `@set_data(${this.var}, ${value});`);
16874 block.add_element(this.var, `@text(${init})`, parent_nodes && `@claim_text(${parent_nodes}, ${init})`, parent_node);
16875 }
16876 }
16877
16878 class RawMustacheTagWrapper extends Tag {
16879 constructor(renderer, block, parent, node) {
16880 super(renderer, block, parent, node);
16881 this.var = 'raw';
16882 this.cannot_use_innerhtml();
16883 }
16884 render(block, parent_node, parent_nodes) {
16885 const name = this.var;
16886 const in_head = parent_node === '@_document.head';
16887 const needs_anchors = !parent_node || in_head;
16888 // if in head always needs anchors
16889 if (in_head) {
16890 this.prev = null;
16891 this.next = null;
16892 }
16893 // TODO use is_dom_node instead of type === 'Element'?
16894 const needs_anchor_before = this.prev ? this.prev.node.type !== 'Element' : needs_anchors;
16895 const needs_anchor_after = this.next ? this.next.node.type !== 'Element' : needs_anchors;
16896 const anchor_before = needs_anchor_before
16897 ? block.get_unique_name(`${name}_before`)
16898 : (this.prev && this.prev.var) || 'null';
16899 const anchor_after = needs_anchor_after
16900 ? block.get_unique_name(`${name}_after`)
16901 : (this.next && this.next.var) || 'null';
16902 let detach;
16903 let insert;
16904 let use_innerhtml = false;
16905 if (anchor_before === 'null' && anchor_after === 'null') {
16906 use_innerhtml = true;
16907 detach = `${parent_node}.innerHTML = '';`;
16908 insert = content => `${parent_node}.innerHTML = ${content};`;
16909 }
16910 else if (anchor_before === 'null') {
16911 detach = `@detach_before(${anchor_after});`;
16912 insert = content => `${anchor_after}.insertAdjacentHTML("beforebegin", ${content});`;
16913 }
16914 else if (anchor_after === 'null') {
16915 detach = `@detach_after(${anchor_before});`;
16916 insert = content => `${anchor_before}.insertAdjacentHTML("afterend", ${content});`;
16917 }
16918 else {
16919 detach = `@detach_between(${anchor_before}, ${anchor_after});`;
16920 insert = content => `${anchor_before}.insertAdjacentHTML("afterend", ${content});`;
16921 }
16922 const { init } = this.rename_this_method(block, content => deindent `
16923 ${!use_innerhtml && detach}
16924 ${insert(content)}
16925 `);
16926 // we would have used comments here, but the `insertAdjacentHTML` api only
16927 // exists for `Element`s.
16928 if (needs_anchor_before) {
16929 block.add_element(anchor_before, `@element('noscript')`, parent_nodes && `@element('noscript')`, parent_node, true);
16930 }
16931 function add_anchor_after() {
16932 block.add_element(anchor_after, `@element('noscript')`, parent_nodes && `@element('noscript')`, parent_node);
16933 }
16934 if (needs_anchor_after && anchor_before === 'null') {
16935 // anchor_after needs to be in the DOM before we
16936 // insert the HTML...
16937 add_anchor_after();
16938 }
16939 block.builders.mount.add_line(insert(init));
16940 if (needs_anchors) {
16941 block.builders.destroy.add_conditional('detaching', needs_anchor_before
16942 ? `${detach}\n@detach(${anchor_before});`
16943 : detach);
16944 }
16945 if (needs_anchor_after && anchor_before !== 'null') {
16946 // ...otherwise it should go afterwards
16947 add_anchor_after();
16948 }
16949 }
16950 }
16951
16952 function snip(expression) {
16953 return `[✂${expression.node.start}-${expression.node.end}✂]`;
16954 }
16955
16956 function stringify_attribute(attribute, is_ssr) {
16957 return attribute.chunks
16958 .map((chunk) => {
16959 if (chunk.type === 'Text') {
16960 return escape_template(escape(chunk.data).replace(/"/g, '&quot;'));
16961 }
16962 return is_ssr
16963 ? '${@escape(' + snip(chunk) + ')}'
16964 : '${' + snip(chunk) + '}';
16965 })
16966 .join('');
16967 }
16968
16969 function get_slot_data(values, is_ssr) {
16970 return Array.from(values.values())
16971 .filter(attribute => attribute.name !== 'name')
16972 .map(attribute => {
16973 const value = attribute.is_true
16974 ? 'true'
16975 : attribute.chunks.length === 0
16976 ? '""'
16977 : attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text'
16978 ? snip(attribute.chunks[0])
16979 : '`' + stringify_attribute(attribute, is_ssr) + '`';
16980 return `${attribute.name}: ${value}`;
16981 });
16982 }
16983
16984 class SlotWrapper extends Wrapper {
16985 constructor(renderer, block, parent, node, strip_whitespace, next_sibling) {
16986 super(renderer, block, parent, node);
16987 this.var = 'slot';
16988 this.dependencies = new Set(['$$scope']);
16989 this.cannot_use_innerhtml();
16990 this.fragment = new FragmentWrapper(renderer, block, node.children, parent, strip_whitespace, next_sibling);
16991 this.node.values.forEach(attribute => {
16992 add_to_set(this.dependencies, attribute.dependencies);
16993 });
16994 block.add_dependencies(this.dependencies);
16995 // we have to do this, just in case
16996 block.add_intro();
16997 block.add_outro();
16998 }
16999 render(block, parent_node, parent_nodes) {
17000 const { renderer } = this;
17001 const { slot_name } = this.node;
17002 let get_slot_changes;
17003 let get_slot_context;
17004 if (this.node.values.size > 0) {
17005 get_slot_changes = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_changes`);
17006 get_slot_context = renderer.component.get_unique_name(`get_${sanitize(slot_name)}_slot_context`);
17007 const context_props = get_slot_data(this.node.values, false);
17008 const changes_props = [];
17009 const dependencies = new Set();
17010 this.node.values.forEach(attribute => {
17011 attribute.chunks.forEach(chunk => {
17012 if (chunk.dependencies) {
17013 add_to_set(dependencies, chunk.contextual_dependencies);
17014 // add_to_set(dependencies, (chunk as Expression).dependencies);
17015 chunk.dependencies.forEach(name => {
17016 const variable = renderer.component.var_lookup.get(name);
17017 if (variable && !variable.hoistable)
17018 dependencies.add(name);
17019 });
17020 }
17021 });
17022 const dynamic_dependencies = Array.from(attribute.dependencies).filter(name => {
17023 const variable = renderer.component.var_lookup.get(name);
17024 return is_dynamic$1(variable);
17025 });
17026 if (dynamic_dependencies.length > 0) {
17027 changes_props.push(`${attribute.name}: ${dynamic_dependencies.join(' || ')}`);
17028 }
17029 });
17030 const arg = dependencies.size > 0 ? `{ ${Array.from(dependencies).join(', ')} }` : '';
17031 renderer.blocks.push(deindent `
17032 const ${get_slot_changes} = (${arg}) => (${stringify_props(changes_props)});
17033 const ${get_slot_context} = (${arg}) => (${stringify_props(context_props)});
17034 `);
17035 }
17036 else {
17037 get_slot_changes = 'null';
17038 get_slot_context = 'null';
17039 }
17040 const slot = block.get_unique_name(`${sanitize(slot_name)}_slot`);
17041 const slot_definition = block.get_unique_name(`${sanitize(slot_name)}_slot`);
17042 block.builders.init.add_block(deindent `
17043 const ${slot_definition} = ctx.$$slots${quote_prop_if_necessary(slot_name)};
17044 const ${slot} = @create_slot(${slot_definition}, ctx, ${get_slot_context});
17045 `);
17046 const mount_before = block.builders.mount.toString();
17047 block.builders.create.push_condition(`!${slot}`);
17048 block.builders.claim.push_condition(`!${slot}`);
17049 block.builders.hydrate.push_condition(`!${slot}`);
17050 block.builders.mount.push_condition(`!${slot}`);
17051 block.builders.update.push_condition(`!${slot}`);
17052 block.builders.destroy.push_condition(`!${slot}`);
17053 const listeners = block.event_listeners;
17054 block.event_listeners = [];
17055 this.fragment.render(block, parent_node, parent_nodes);
17056 block.render_listeners(`_${slot}`);
17057 block.event_listeners = listeners;
17058 block.builders.create.pop_condition();
17059 block.builders.claim.pop_condition();
17060 block.builders.hydrate.pop_condition();
17061 block.builders.mount.pop_condition();
17062 block.builders.update.pop_condition();
17063 block.builders.destroy.pop_condition();
17064 block.builders.create.add_line(`if (${slot}) ${slot}.c();`);
17065 block.builders.claim.add_line(`if (${slot}) ${slot}.l(${parent_nodes});`);
17066 const mount_leadin = block.builders.mount.toString() !== mount_before
17067 ? `else`
17068 : `if (${slot})`;
17069 block.builders.mount.add_block(deindent `
17070 ${mount_leadin} {
17071 ${slot}.m(${parent_node || '#target'}, ${parent_node ? 'null' : 'anchor'});
17072 }
17073 `);
17074 block.builders.intro.add_line(`@transition_in(${slot}, #local);`);
17075 block.builders.outro.add_line(`@transition_out(${slot}, #local);`);
17076 const dynamic_dependencies = Array.from(this.dependencies).filter(name => {
17077 if (name === '$$scope')
17078 return true;
17079 const variable = renderer.component.var_lookup.get(name);
17080 return is_dynamic$1(variable);
17081 });
17082 let update_conditions = dynamic_dependencies.map(name => `changed.${name}`).join(' || ');
17083 if (dynamic_dependencies.length > 1)
17084 update_conditions = `(${update_conditions})`;
17085 block.builders.update.add_block(deindent `
17086 if (${slot} && ${slot}.p && ${update_conditions}) {
17087 ${slot}.p(@get_slot_changes(${slot_definition}, ctx, changed, ${get_slot_changes}), @get_slot_context(${slot_definition}, ctx, ${get_slot_context}));
17088 }
17089 `);
17090 block.builders.destroy.add_line(`if (${slot}) ${slot}.d(detaching);`);
17091 }
17092 }
17093
17094 // Whitespace inside one of these elements will not result in
17095 // a whitespace node being created in any circumstances. (This
17096 // list is almost certainly very incomplete)
17097 const elements_without_text = new Set([
17098 'audio',
17099 'datalist',
17100 'dl',
17101 'optgroup',
17102 'select',
17103 'video',
17104 ]);
17105 // TODO this should probably be in Fragment
17106 function should_skip(node) {
17107 if (/\S/.test(node.data))
17108 return false;
17109 const parent_element = node.find_nearest(/(?:Element|InlineComponent|Head)/);
17110 if (!parent_element)
17111 return false;
17112 if (parent_element.type === 'Head')
17113 return true;
17114 if (parent_element.type === 'InlineComponent')
17115 return parent_element.children.length === 1 && node === parent_element.children[0];
17116 return parent_element.namespace || elements_without_text.has(parent_element.name);
17117 }
17118 class TextWrapper extends Wrapper {
17119 constructor(renderer, block, parent, node, data) {
17120 super(renderer, block, parent, node);
17121 this.skip = should_skip(this.node);
17122 this.data = data;
17123 this.var = this.skip ? null : 't';
17124 }
17125 use_space() {
17126 if (this.renderer.component.component_options.preserveWhitespace)
17127 return false;
17128 if (/[\S\u00A0]/.test(this.data))
17129 return false;
17130 let node = this.parent && this.parent.node;
17131 while (node) {
17132 if (node.type === 'Element' && node.name === 'pre') {
17133 return false;
17134 }
17135 node = node.parent;
17136 }
17137 return true;
17138 }
17139 render(block, parent_node, parent_nodes) {
17140 if (this.skip)
17141 return;
17142 block.add_element(this.var, this.use_space() ? `@space()` : `@text(${stringify(this.data)})`, parent_nodes && `@claim_text(${parent_nodes}, ${stringify(this.data)})`, parent_node);
17143 }
17144 }
17145
17146 class TitleWrapper extends Wrapper {
17147 constructor(renderer, block, parent, node, _strip_whitespace, _next_sibling) {
17148 super(renderer, block, parent, node);
17149 }
17150 render(block, _parent_node, _parent_nodes) {
17151 const is_dynamic = !!this.node.children.find(node => node.type !== 'Text');
17152 if (is_dynamic) {
17153 let value;
17154 const all_dependencies = new Set();
17155 // TODO some of this code is repeated in Tag.ts — would be good to
17156 // DRY it out if that's possible without introducing crazy indirection
17157 if (this.node.children.length === 1) {
17158 // single {tag} — may be a non-string
17159 // @ts-ignore todo: check this
17160 const { expression } = this.node.children[0];
17161 value = expression.render(block);
17162 add_to_set(all_dependencies, expression.dependencies);
17163 }
17164 else {
17165 // '{foo} {bar}' — treat as string concatenation
17166 value =
17167 (this.node.children[0].type === 'Text' ? '' : `"" + `) +
17168 this.node.children
17169 .map((chunk) => {
17170 if (chunk.type === 'Text') {
17171 return stringify(chunk.data);
17172 }
17173 else {
17174 // @ts-ignore todo: check this
17175 const snippet = chunk.expression.render(block);
17176 // @ts-ignore todo: check this
17177 chunk.expression.dependencies.forEach(d => {
17178 all_dependencies.add(d);
17179 });
17180 // @ts-ignore todo: check this
17181 return chunk.expression.get_precedence() <= 13 ? `(${snippet})` : snippet;
17182 }
17183 })
17184 .join(' + ');
17185 }
17186 const last = this.node.should_cache && block.get_unique_name(`title_value`);
17187 if (this.node.should_cache)
17188 block.add_variable(last);
17189 const init = this.node.should_cache ? `${last} = ${value}` : value;
17190 block.builders.init.add_line(`@_document.title = ${init};`);
17191 const updater = `@_document.title = ${this.node.should_cache ? last : value};`;
17192 if (all_dependencies.size) {
17193 const dependencies = Array.from(all_dependencies);
17194 const changed_check = ((block.has_outros ? `!#current || ` : '') +
17195 dependencies.map(dependency => `changed.${dependency}`).join(' || '));
17196 const update_cached_value = `${last} !== (${last} = ${value})`;
17197 const condition = this.node.should_cache ?
17198 (dependencies.length ? `(${changed_check}) && ${update_cached_value}` : update_cached_value) :
17199 changed_check;
17200 block.builders.update.add_conditional(condition, updater);
17201 }
17202 }
17203 else {
17204 const value = this.node.children.length > 0
17205 ? stringify(this.node.children[0].data)
17206 : '""';
17207 block.builders.hydrate.add_line(`@_document.title = ${value};`);
17208 }
17209 }
17210 }
17211
17212 const associated_events = {
17213 innerWidth: 'resize',
17214 innerHeight: 'resize',
17215 outerWidth: 'resize',
17216 outerHeight: 'resize',
17217 scrollX: 'scroll',
17218 scrollY: 'scroll',
17219 };
17220 const properties = {
17221 scrollX: 'pageXOffset',
17222 scrollY: 'pageYOffset'
17223 };
17224 const readonly = new Set([
17225 'innerWidth',
17226 'innerHeight',
17227 'outerWidth',
17228 'outerHeight',
17229 'online',
17230 ]);
17231 class WindowWrapper extends Wrapper {
17232 constructor(renderer, block, parent, node) {
17233 super(renderer, block, parent, node);
17234 }
17235 render(block, _parent_node, _parent_nodes) {
17236 const { renderer } = this;
17237 const { component } = renderer;
17238 const events = {};
17239 const bindings = {};
17240 add_actions(component, block, '@_window', this.node.actions);
17241 add_event_handlers(block, '@_window', this.node.handlers);
17242 this.node.bindings.forEach(binding => {
17243 // in dev mode, throw if read-only values are written to
17244 if (readonly.has(binding.name)) {
17245 renderer.readonly.add(binding.expression.node.name);
17246 }
17247 bindings[binding.name] = binding.expression.node.name;
17248 // bind:online is a special case, we need to listen for two separate events
17249 if (binding.name === 'online')
17250 return;
17251 const associated_event = associated_events[binding.name];
17252 const property = properties[binding.name] || binding.name;
17253 if (!events[associated_event])
17254 events[associated_event] = [];
17255 events[associated_event].push({
17256 name: binding.expression.node.name,
17257 value: property
17258 });
17259 });
17260 const scrolling = block.get_unique_name(`scrolling`);
17261 const clear_scrolling = block.get_unique_name(`clear_scrolling`);
17262 const scrolling_timeout = block.get_unique_name(`scrolling_timeout`);
17263 Object.keys(events).forEach(event => {
17264 const handler_name = block.get_unique_name(`onwindow${event}`);
17265 const props = events[event];
17266 if (event === 'scroll') {
17267 // TODO other bidirectional bindings...
17268 block.add_variable(scrolling, 'false');
17269 block.add_variable(clear_scrolling, `() => { ${scrolling} = false }`);
17270 block.add_variable(scrolling_timeout);
17271 const condition = [
17272 bindings.scrollX && `"${bindings.scrollX}" in this._state`,
17273 bindings.scrollY && `"${bindings.scrollY}" in this._state`
17274 ].filter(Boolean).join(' || ');
17275 const x = bindings.scrollX && `this._state.${bindings.scrollX}`;
17276 const y = bindings.scrollY && `this._state.${bindings.scrollY}`;
17277 renderer.meta_bindings.add_block(deindent `
17278 if (${condition}) {
17279 @_scrollTo(${x || '@_window.pageXOffset'}, ${y || '@_window.pageYOffset'});
17280 }
17281 ${x && `${x} = @_window.pageXOffset;`}
17282 ${y && `${y} = @_window.pageYOffset;`}
17283 `);
17284 block.event_listeners.push(deindent `
17285 @listen(@_window, "${event}", () => {
17286 ${scrolling} = true;
17287 @_clearTimeout(${scrolling_timeout});
17288 ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100);
17289 ctx.${handler_name}();
17290 })
17291 `);
17292 }
17293 else {
17294 props.forEach(prop => {
17295 renderer.meta_bindings.add_line(`this._state.${prop.name} = @_window.${prop.value};`);
17296 });
17297 block.event_listeners.push(deindent `
17298 @listen(@_window, "${event}", ctx.${handler_name})
17299 `);
17300 }
17301 component.add_var({
17302 name: handler_name,
17303 internal: true,
17304 referenced: true
17305 });
17306 component.partly_hoisted.push(deindent `
17307 function ${handler_name}() {
17308 ${props.map(prop => `${prop.name} = @_window.${prop.value}; $$invalidate('${prop.name}', ${prop.name});`)}
17309 }
17310 `);
17311 block.builders.init.add_block(deindent `
17312 @add_render_callback(ctx.${handler_name});
17313 `);
17314 component.has_reactive_assignments = true;
17315 });
17316 // special case... might need to abstract this out if we add more special cases
17317 if (bindings.scrollX || bindings.scrollY) {
17318 block.builders.update.add_block(deindent `
17319 if (${[bindings.scrollX, bindings.scrollY].filter(Boolean).map(b => `changed.${b}`).join(' || ')} && !${scrolling}) {
17320 ${scrolling} = true;
17321 @_clearTimeout(${scrolling_timeout});
17322 @_scrollTo(${bindings.scrollX ? `ctx.${bindings.scrollX}` : `@_window.pageXOffset`}, ${bindings.scrollY ? `ctx.${bindings.scrollY}` : `@_window.pageYOffset`});
17323 ${scrolling_timeout} = @_setTimeout(${clear_scrolling}, 100);
17324 }
17325 `);
17326 }
17327 // another special case. (I'm starting to think these are all special cases.)
17328 if (bindings.online) {
17329 const handler_name = block.get_unique_name(`onlinestatuschanged`);
17330 const name = bindings.online;
17331 component.add_var({
17332 name: handler_name,
17333 internal: true,
17334 referenced: true
17335 });
17336 component.partly_hoisted.push(deindent `
17337 function ${handler_name}() {
17338 ${name} = @_navigator.onLine; $$invalidate('${name}', ${name});
17339 }
17340 `);
17341 block.builders.init.add_block(deindent `
17342 @add_render_callback(ctx.${handler_name});
17343 `);
17344 block.event_listeners.push(`@listen(@_window, "online", ctx.${handler_name})`, `@listen(@_window, "offline", ctx.${handler_name})`);
17345 component.has_reactive_assignments = true;
17346 }
17347 }
17348 }
17349
17350 const wrappers = {
17351 AwaitBlock: AwaitBlockWrapper,
17352 Body: BodyWrapper,
17353 Comment: null,
17354 DebugTag: DebugTagWrapper,
17355 EachBlock: EachBlockWrapper,
17356 Element: ElementWrapper,
17357 Head: HeadWrapper,
17358 IfBlock: IfBlockWrapper,
17359 InlineComponent: InlineComponentWrapper,
17360 MustacheTag: MustacheTagWrapper,
17361 Options: null,
17362 RawMustacheTag: RawMustacheTagWrapper,
17363 Slot: SlotWrapper,
17364 Text: TextWrapper,
17365 Title: TitleWrapper,
17366 Window: WindowWrapper
17367 };
17368 function link(next, prev) {
17369 prev.next = next;
17370 if (next)
17371 next.prev = prev;
17372 }
17373 function trimmable_at(child, next_sibling) {
17374 // Whitespace is trimmable if one of the following is true:
17375 // The child and its sibling share a common nearest each block (not at an each block boundary)
17376 // The next sibling's previous node is an each block
17377 return (next_sibling.node.find_nearest(/EachBlock/) === child.find_nearest(/EachBlock/)) || next_sibling.node.prev.type === 'EachBlock';
17378 }
17379 class FragmentWrapper {
17380 constructor(renderer, block, nodes, parent, strip_whitespace, next_sibling) {
17381 this.nodes = [];
17382 let last_child;
17383 let window_wrapper;
17384 let i = nodes.length;
17385 while (i--) {
17386 const child = nodes[i];
17387 if (!child.type) {
17388 throw new Error(`missing type`);
17389 }
17390 if (!(child.type in wrappers)) {
17391 throw new Error(`TODO implement ${child.type}`);
17392 }
17393 // special case — this is an easy way to remove whitespace surrounding
17394 // <svelte:window/>. lil hacky but it works
17395 if (child.type === 'Window') {
17396 window_wrapper = new WindowWrapper(renderer, block, parent, child);
17397 continue;
17398 }
17399 if (child.type === 'Text') {
17400 let { data } = child;
17401 // We want to remove trailing whitespace inside an element/component/block,
17402 // *unless* there is no whitespace between this node and its next sibling
17403 if (this.nodes.length === 0) {
17404 const should_trim = (next_sibling ? (next_sibling.node.type === 'Text' && /^\s/.test(next_sibling.node.data) && trimmable_at(child, next_sibling)) : !child.has_ancestor('EachBlock'));
17405 if (should_trim) {
17406 data = trim_end(data);
17407 if (!data)
17408 continue;
17409 }
17410 }
17411 // glue text nodes (which could e.g. be separated by comments) together
17412 if (last_child && last_child.node.type === 'Text') {
17413 last_child.data = data + last_child.data;
17414 continue;
17415 }
17416 const wrapper = new TextWrapper(renderer, block, parent, child, data);
17417 if (wrapper.skip)
17418 continue;
17419 this.nodes.unshift(wrapper);
17420 link(last_child, last_child = wrapper);
17421 }
17422 else {
17423 const Wrapper = wrappers[child.type];
17424 if (!Wrapper)
17425 continue;
17426 const wrapper = new Wrapper(renderer, block, parent, child, strip_whitespace, last_child || next_sibling);
17427 this.nodes.unshift(wrapper);
17428 link(last_child, last_child = wrapper);
17429 }
17430 }
17431 if (strip_whitespace) {
17432 const first = this.nodes[0];
17433 if (first && first.node.type === 'Text') {
17434 first.data = trim_start(first.data);
17435 if (!first.data) {
17436 first.var = null;
17437 this.nodes.shift();
17438 if (this.nodes[0]) {
17439 this.nodes[0].prev = null;
17440 }
17441 }
17442 }
17443 }
17444 if (window_wrapper) {
17445 this.nodes.unshift(window_wrapper);
17446 link(last_child, window_wrapper);
17447 }
17448 }
17449 render(block, parent_node, parent_nodes) {
17450 for (let i = 0; i < this.nodes.length; i += 1) {
17451 this.nodes[i].render(block, parent_node, parent_nodes);
17452 }
17453 }
17454 }
17455
17456 class Renderer {
17457 constructor(component, options) {
17458 this.blocks = [];
17459 this.readonly = new Set();
17460 this.meta_bindings = new CodeBuilder(); // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
17461 this.binding_groups = [];
17462 this.component = component;
17463 this.options = options;
17464 this.locate = component.locate; // TODO messy
17465 this.file_var = options.dev && this.component.get_unique_name('file');
17466 // main block
17467 this.block = new Block$1({
17468 renderer: this,
17469 name: null,
17470 key: null,
17471 bindings: new Map(),
17472 dependencies: new Set(),
17473 });
17474 this.block.has_update_method = true;
17475 this.fragment = new FragmentWrapper(this, this.block, component.fragment.children, null, true, null);
17476 this.blocks.forEach(block => {
17477 if (typeof block !== 'string') {
17478 block.assign_variable_names();
17479 }
17480 });
17481 this.block.assign_variable_names();
17482 this.fragment.render(this.block, null, 'nodes');
17483 }
17484 }
17485
17486 function isReference(node, parent) {
17487 if (node.type === 'MemberExpression') {
17488 return !node.computed && isReference(node.object, node);
17489 }
17490 if (node.type === 'Identifier') {
17491 if (!parent)
17492 return true;
17493 switch (parent.type) {
17494 // disregard `bar` in `foo.bar`
17495 case 'MemberExpression': return parent.computed || node === parent.object;
17496 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
17497 case 'MethodDefinition': return parent.computed;
17498 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
17499 case 'Property': return parent.computed || node === parent.value;
17500 // disregard the `bar` in `export { foo as bar }`
17501 case 'ExportSpecifier': return node === parent.local;
17502 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
17503 case 'LabeledStatement':
17504 case 'BreakStatement':
17505 case 'ContinueStatement': return false;
17506 default: return true;
17507 }
17508 }
17509 return false;
17510 }
17511
17512 function create_scopes(expression) {
17513 const map = new WeakMap();
17514 const globals = new Map();
17515 let scope = new Scope$1(null, false);
17516 walk(expression, {
17517 enter(node, parent) {
17518 if (node.type === 'ImportDeclaration') {
17519 node.specifiers.forEach(specifier => {
17520 scope.declarations.set(specifier.local.name, specifier);
17521 });
17522 }
17523 else if (/Function/.test(node.type)) {
17524 if (node.type === 'FunctionDeclaration') {
17525 scope.declarations.set(node.id.name, node);
17526 scope = new Scope$1(scope, false);
17527 map.set(node, scope);
17528 }
17529 else {
17530 scope = new Scope$1(scope, false);
17531 map.set(node, scope);
17532 if (node.id)
17533 scope.declarations.set(node.id.name, node);
17534 }
17535 node.params.forEach((param) => {
17536 extract_names(param).forEach(name => {
17537 scope.declarations.set(name, node);
17538 });
17539 });
17540 }
17541 else if (/For(?:In|Of)?Statement/.test(node.type)) {
17542 scope = new Scope$1(scope, true);
17543 map.set(node, scope);
17544 }
17545 else if (node.type === 'BlockStatement') {
17546 scope = new Scope$1(scope, true);
17547 map.set(node, scope);
17548 }
17549 else if (/(Class|Variable)Declaration/.test(node.type)) {
17550 scope.add_declaration(node);
17551 }
17552 else if (node.type === 'CatchClause') {
17553 scope = new Scope$1(scope, true);
17554 map.set(node, scope);
17555 extract_names(node.param).forEach(name => {
17556 scope.declarations.set(name, node.param);
17557 });
17558 }
17559 else if (node.type === 'Identifier' && isReference(node, parent)) {
17560 if (!scope.has(node.name) && !globals.has(node.name)) {
17561 globals.set(node.name, node);
17562 }
17563 }
17564 },
17565 leave(node) {
17566 if (map.has(node)) {
17567 scope = scope.parent;
17568 }
17569 }
17570 });
17571 scope.declarations.forEach((_node, name) => {
17572 globals.delete(name);
17573 });
17574 return { map, scope, globals };
17575 }
17576 class Scope$1 {
17577 constructor(parent, block) {
17578 this.declarations = new Map();
17579 this.initialised_declarations = new Set();
17580 this.parent = parent;
17581 this.block = block;
17582 }
17583 add_declaration(node) {
17584 if (node.kind === 'var' && this.block && this.parent) {
17585 this.parent.add_declaration(node);
17586 }
17587 else if (node.type === 'VariableDeclaration') {
17588 node.declarations.forEach((declarator) => {
17589 extract_names(declarator.id).forEach(name => {
17590 this.declarations.set(name, node);
17591 if (declarator.init)
17592 this.initialised_declarations.add(name);
17593 });
17594 });
17595 }
17596 else {
17597 this.declarations.set(node.id.name, node);
17598 }
17599 }
17600 find_owner(name) {
17601 if (this.declarations.has(name))
17602 return this;
17603 return this.parent && this.parent.find_owner(name);
17604 }
17605 has(name) {
17606 return (this.declarations.has(name) || (this.parent && this.parent.has(name)));
17607 }
17608 }
17609 function extract_names(param) {
17610 return extract_identifiers(param).map(node => node.name);
17611 }
17612 function extract_identifiers(param) {
17613 const nodes = [];
17614 extractors[param.type] && extractors[param.type](nodes, param);
17615 return nodes;
17616 }
17617 const extractors = {
17618 Identifier(nodes, param) {
17619 nodes.push(param);
17620 },
17621 MemberExpression(nodes, param) {
17622 nodes.push(get_object(param));
17623 },
17624 ObjectPattern(nodes, param) {
17625 param.properties.forEach((prop) => {
17626 if (prop.type === 'RestElement') {
17627 nodes.push(prop.argument);
17628 }
17629 else {
17630 extractors[prop.value.type](nodes, prop.value);
17631 }
17632 });
17633 },
17634 ArrayPattern(nodes, param) {
17635 param.elements.forEach((element) => {
17636 if (element)
17637 extractors[element.type](nodes, element);
17638 });
17639 },
17640 RestElement(nodes, param) {
17641 extractors[param.argument.type](nodes, param.argument);
17642 },
17643 AssignmentPattern(nodes, param) {
17644 extractors[param.left.type](nodes, param.left);
17645 }
17646 };
17647
17648 function nodes_match(a, b) {
17649 if (!!a !== !!b)
17650 return false;
17651 if (Array.isArray(a) !== Array.isArray(b))
17652 return false;
17653 if (a && typeof a === 'object') {
17654 if (Array.isArray(a)) {
17655 if (a.length !== b.length)
17656 return false;
17657 return a.every((child, i) => nodes_match(child, b[i]));
17658 }
17659 const a_keys = Object.keys(a).sort();
17660 const b_keys = Object.keys(b).sort();
17661 if (a_keys.length !== b_keys.length)
17662 return false;
17663 let i = a_keys.length;
17664 while (i--) {
17665 const key = a_keys[i];
17666 if (b_keys[i] !== key)
17667 return false;
17668 if (key === 'start' || key === 'end')
17669 continue;
17670 if (!nodes_match(a[key], b[key])) {
17671 return false;
17672 }
17673 }
17674 return true;
17675 }
17676 return a === b;
17677 }
17678
17679 function dom(component, options) {
17680 const { name, code } = component;
17681 const renderer = new Renderer(component, options);
17682 const { block } = renderer;
17683 block.has_outro_method = true;
17684 // prevent fragment being created twice (#1063)
17685 if (options.customElement)
17686 block.builders.create.add_line(`this.c = @noop;`);
17687 const builder = new CodeBuilder();
17688 if (component.compile_options.dev) {
17689 builder.add_line(`const ${renderer.file_var} = ${component.file && stringify(component.file, { only_escape_at_symbol: true })};`);
17690 }
17691 const css = component.stylesheet.render(options.filename, !options.customElement);
17692 const styles = component.stylesheet.has_styles && stringify(options.dev ?
17693 `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` :
17694 css.code, { only_escape_at_symbol: true });
17695 const add_css = component.get_unique_name('add_css');
17696 if (styles && component.compile_options.css !== false && !options.customElement) {
17697 builder.add_block(deindent `
17698 function ${add_css}() {
17699 var style = @element("style");
17700 style.id = '${component.stylesheet.id}-style';
17701 style.textContent = ${styles};
17702 @append(@_document.head, style);
17703 }
17704 `);
17705 }
17706 // fix order
17707 // TODO the deconflicted names of blocks are reversed... should set them here
17708 const blocks = renderer.blocks.slice().reverse();
17709 blocks.forEach(block => {
17710 builder.add_block(block.toString());
17711 });
17712 if (options.dev && !options.hydratable) {
17713 block.builders.claim.add_line('throw new @_Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");');
17714 }
17715 // TODO injecting CSS this way is kinda dirty. Maybe it should be an
17716 // explicit opt-in, or something?
17717 const should_add_css = (!options.customElement &&
17718 component.stylesheet.has_styles &&
17719 options.css !== false);
17720 const uses_props = component.var_lookup.has('$$props');
17721 const $$props = uses_props ? `$$new_props` : `$$props`;
17722 const props = component.vars.filter(variable => !variable.module && variable.export_name);
17723 const writable_props = props.filter(variable => variable.writable);
17724 /* eslint-disable @typescript-eslint/indent,indent */
17725 const set = (uses_props || writable_props.length > 0 || component.slots.size > 0)
17726 ? deindent `
17727 ${$$props} => {
17728 ${uses_props && component.invalidate('$$props', `$$props = @assign(@assign({}, $$props), $$new_props)`)}
17729 ${writable_props.map(prop => `if ('${prop.export_name}' in ${$$props}) ${component.invalidate(prop.name, `${prop.name} = ${$$props}.${prop.export_name}`)};`)}
17730 ${component.slots.size > 0 &&
17731 `if ('$$scope' in ${$$props}) ${component.invalidate('$$scope', `$$scope = ${$$props}.$$scope`)};`}
17732 }
17733 `
17734 : null;
17735 /* eslint-enable @typescript-eslint/indent,indent */
17736 const body = [];
17737 const not_equal = component.component_options.immutable ? `@not_equal` : `@safe_not_equal`;
17738 let dev_props_check;
17739 props.forEach(x => {
17740 const variable = component.var_lookup.get(x.name);
17741 if (!variable.writable || component.component_options.accessors) {
17742 body.push(deindent `
17743 get ${x.export_name}() {
17744 return ${x.hoistable ? x.name : 'this.$$.ctx.' + x.name};
17745 }
17746 `);
17747 }
17748 else if (component.compile_options.dev) {
17749 body.push(deindent `
17750 get ${x.export_name}() {
17751 throw new @_Error("<${component.tag}>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
17752 }
17753 `);
17754 }
17755 if (component.component_options.accessors) {
17756 if (variable.writable && !renderer.readonly.has(x.name)) {
17757 body.push(deindent `
17758 set ${x.export_name}(${x.name}) {
17759 this.$set({ ${x.name === x.export_name ? x.name : `${x.export_name}: ${x.name}`} });
17760 @flush();
17761 }
17762 `);
17763 }
17764 else if (component.compile_options.dev) {
17765 body.push(deindent `
17766 set ${x.export_name}(value) {
17767 throw new @_Error("<${component.tag}>: Cannot set read-only property '${x.export_name}'");
17768 }
17769 `);
17770 }
17771 }
17772 else if (component.compile_options.dev) {
17773 body.push(deindent `
17774 set ${x.export_name}(value) {
17775 throw new @_Error("<${component.tag}>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
17776 }
17777 `);
17778 }
17779 });
17780 if (component.compile_options.dev) {
17781 // checking that expected ones were passed
17782 const expected = props.filter(prop => !prop.initialised);
17783 if (expected.length) {
17784 dev_props_check = deindent `
17785 const { ctx } = this.$$;
17786 const props = ${options.customElement ? `this.attributes` : `options.props || {}`};
17787 ${expected.map(prop => deindent `
17788 if (ctx.${prop.name} === undefined && !('${prop.export_name}' in props)) {
17789 @_console.warn("<${component.tag}> was created without expected prop '${prop.export_name}'");
17790 }`)}
17791 `;
17792 }
17793 }
17794 // instrument assignments
17795 if (component.ast.instance) {
17796 let scope = component.instance_scope;
17797 const map = component.instance_scope_map;
17798 let pending_assignments = new Set();
17799 walk(component.ast.instance.content, {
17800 enter: (node) => {
17801 if (map.has(node)) {
17802 scope = map.get(node);
17803 }
17804 },
17805 leave(node, parent) {
17806 if (map.has(node)) {
17807 scope = scope.parent;
17808 }
17809 if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') {
17810 const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument;
17811 let names = [];
17812 if (assignee.type === 'MemberExpression') {
17813 const left_object_name = get_object(assignee).name;
17814 left_object_name && (names = [left_object_name]);
17815 }
17816 else {
17817 names = extract_names(assignee);
17818 }
17819 if (node.operator === '=' && nodes_match(node.left, node.right)) {
17820 const dirty = names.filter(name => {
17821 return name[0] === '$' || scope.find_owner(name) === component.instance_scope;
17822 });
17823 if (dirty.length)
17824 component.has_reactive_assignments = true;
17825 code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
17826 }
17827 else {
17828 const single = (node.type === 'AssignmentExpression' &&
17829 assignee.type === 'Identifier' &&
17830 parent.type === 'ExpressionStatement' &&
17831 assignee.name[0] !== '$');
17832 names.forEach(name => {
17833 const owner = scope.find_owner(name);
17834 if (owner && owner !== component.instance_scope)
17835 return;
17836 const variable = component.var_lookup.get(name);
17837 if (variable && (variable.hoistable || variable.global || variable.module))
17838 return;
17839 if (single && !(variable.subscribable && variable.reassigned)) {
17840 if (variable.referenced || variable.is_reactive_dependency || variable.export_name) {
17841 code.prependRight(node.start, `$$invalidate('${name}', `);
17842 code.appendLeft(node.end, `)`);
17843 }
17844 }
17845 else {
17846 pending_assignments.add(name);
17847 }
17848 component.has_reactive_assignments = true;
17849 });
17850 }
17851 }
17852 if (pending_assignments.size > 0) {
17853 if (node.type === 'ArrowFunctionExpression') {
17854 const insert = Array.from(pending_assignments).map(name => component.invalidate(name)).join('; ');
17855 pending_assignments = new Set();
17856 code.prependRight(node.body.start, `{ const $$result = `);
17857 code.appendLeft(node.body.end, `; ${insert}; return $$result; }`);
17858 pending_assignments = new Set();
17859 }
17860 else if (/Statement/.test(node.type)) {
17861 const insert = Array.from(pending_assignments).map(name => component.invalidate(name)).join('; ');
17862 if (/^(Break|Continue|Return)Statement/.test(node.type)) {
17863 if (node.argument) {
17864 code.overwrite(node.start, node.argument.start, `var $$result = `);
17865 code.appendLeft(node.argument.end, `; ${insert}; return $$result`);
17866 }
17867 else {
17868 code.prependRight(node.start, `${insert}; `);
17869 }
17870 }
17871 else if (parent && /(If|For(In|Of)?|While)Statement/.test(parent.type) && node.type !== 'BlockStatement') {
17872 code.prependRight(node.start, '{ ');
17873 code.appendLeft(node.end, `${code.original[node.end - 1] === ';' ? '' : ';'} ${insert}; }`);
17874 }
17875 else {
17876 code.appendLeft(node.end, `${code.original[node.end - 1] === ';' ? '' : ';'} ${insert};`);
17877 }
17878 pending_assignments = new Set();
17879 }
17880 }
17881 }
17882 });
17883 if (pending_assignments.size > 0) {
17884 throw new Error(`TODO this should not happen!`);
17885 }
17886 component.rewrite_props(({ name, reassigned }) => {
17887 const value = `$${name}`;
17888 const callback = `$value => { ${value} = $$value; $$invalidate('${value}', ${value}) }`;
17889 if (reassigned) {
17890 return `$$subscribe_${name}()`;
17891 }
17892 const subscribe = component.helper('subscribe');
17893 let insert = `${subscribe}($$self, ${name}, $${callback})`;
17894 if (component.compile_options.dev) {
17895 const validate_store = component.helper('validate_store');
17896 insert = `${validate_store}(${name}, '${name}'); ${insert}`;
17897 }
17898 return insert;
17899 });
17900 }
17901 const args = ['$$self'];
17902 if (props.length > 0 || component.has_reactive_assignments || component.slots.size > 0) {
17903 args.push('$$props', '$$invalidate');
17904 }
17905 builder.add_block(deindent `
17906 function create_fragment(ctx) {
17907 ${block.get_contents()}
17908 }
17909
17910 ${component.module_javascript}
17911
17912 ${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')}
17913 `);
17914 const filtered_declarations = component.vars
17915 .filter(v => ((v.referenced || v.export_name) && !v.hoistable))
17916 .map(v => v.name);
17917 if (uses_props)
17918 filtered_declarations.push(`$$props: $$props = ${component.helper('exclude_internal_props')}($$props)`);
17919 const filtered_props = props.filter(prop => {
17920 const variable = component.var_lookup.get(prop.name);
17921 if (variable.hoistable)
17922 return false;
17923 if (prop.name[0] === '$')
17924 return false;
17925 return true;
17926 });
17927 const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
17928 if (component.slots.size > 0) {
17929 filtered_declarations.push('$$slots', '$$scope');
17930 }
17931 if (renderer.binding_groups.length > 0) {
17932 filtered_declarations.push(`$$binding_groups`);
17933 }
17934 const has_definition = (component.javascript ||
17935 filtered_props.length > 0 ||
17936 uses_props ||
17937 component.partly_hoisted.length > 0 ||
17938 filtered_declarations.length > 0 ||
17939 component.reactive_declarations.length > 0);
17940 const definition = has_definition
17941 ? component.alias('instance')
17942 : 'null';
17943 const all_reactive_dependencies = new Set();
17944 component.reactive_declarations.forEach(d => {
17945 add_to_set(all_reactive_dependencies, d.dependencies);
17946 });
17947 const reactive_store_subscriptions = reactive_stores
17948 .filter(store => {
17949 const variable = component.var_lookup.get(store.name.slice(1));
17950 return !variable || variable.hoistable;
17951 })
17952 .map(({ name }) => deindent `
17953 ${component.compile_options.dev && `@validate_store(${name.slice(1)}, '${name.slice(1)}');`}
17954 @subscribe($$self, ${name.slice(1)}, $$value => { ${name} = $$value; $$invalidate('${name}', ${name}); });
17955 `);
17956 const resubscribable_reactive_store_unsubscribers = reactive_stores
17957 .filter(store => {
17958 const variable = component.var_lookup.get(store.name.slice(1));
17959 return variable && variable.reassigned;
17960 })
17961 .map(({ name }) => `$$self.$$.on_destroy.push(() => $$unsubscribe_${name.slice(1)}());`);
17962 if (has_definition) {
17963 const reactive_declarations = [];
17964 const fixed_reactive_declarations = []; // not really 'reactive' but whatever
17965 component.reactive_declarations
17966 .forEach(d => {
17967 let uses_props;
17968 const condition = Array.from(d.dependencies)
17969 .filter(n => {
17970 if (n === '$$props') {
17971 uses_props = true;
17972 return false;
17973 }
17974 const variable = component.var_lookup.get(n);
17975 return variable && (variable.writable || variable.mutated);
17976 })
17977 .map(n => `$$dirty.${n}`).join(' || ');
17978 let snippet = `[✂${d.node.body.start}-${d.node.end}✂]`;
17979 if (condition)
17980 snippet = `if (${condition}) { ${snippet} }`;
17981 if (condition || uses_props) {
17982 reactive_declarations.push(snippet);
17983 }
17984 else {
17985 fixed_reactive_declarations.push(snippet);
17986 }
17987 });
17988 const injected = Array.from(component.injected_reactive_declaration_vars).filter(name => {
17989 const variable = component.var_lookup.get(name);
17990 return variable.injected && variable.name[0] !== '$';
17991 });
17992 const reactive_store_declarations = reactive_stores.map(variable => {
17993 const $name = variable.name;
17994 const name = $name.slice(1);
17995 const store = component.var_lookup.get(name);
17996 if (store && store.reassigned) {
17997 return `${$name}, $$unsubscribe_${name} = @noop, $$subscribe_${name} = () => { $$unsubscribe_${name}(); $$unsubscribe_${name} = ${name}.subscribe($$value => { ${$name} = $$value; $$invalidate('${$name}', ${$name}); }) }`;
17998 }
17999 return $name;
18000 });
18001 let unknown_props_check;
18002 if (component.compile_options.dev && !component.var_lookup.has('$$props') && writable_props.length) {
18003 unknown_props_check = deindent `
18004 const writable_props = [${writable_props.map(prop => `'${prop.export_name}'`).join(', ')}];
18005 @_Object.keys($$props).forEach(key => {
18006 if (!writable_props.includes(key) && !key.startsWith('$$')) @_console.warn(\`<${component.tag}> was created with unknown prop '\${key}'\`);
18007 });
18008 `;
18009 }
18010 builder.add_block(deindent `
18011 function ${definition}(${args.join(', ')}) {
18012 ${reactive_store_declarations.length > 0 && `let ${reactive_store_declarations.join(', ')};`}
18013
18014 ${reactive_store_subscriptions}
18015
18016 ${resubscribable_reactive_store_unsubscribers}
18017
18018 ${component.javascript}
18019
18020 ${unknown_props_check}
18021
18022 ${component.slots.size && `let { $$slots = {}, $$scope } = $$props;`}
18023
18024 ${renderer.binding_groups.length > 0 && `const $$binding_groups = [${renderer.binding_groups.map(_ => `[]`).join(', ')}];`}
18025
18026 ${component.partly_hoisted.length > 0 && component.partly_hoisted.join('\n\n')}
18027
18028 ${set && `$$self.$set = ${set};`}
18029
18030 ${injected.length && `let ${injected.join(', ')};`}
18031
18032 ${reactive_declarations.length > 0 && deindent `
18033 $$self.$$.update = ($$dirty = { ${Array.from(all_reactive_dependencies).map(n => `${n}: 1`).join(', ')} }) => {
18034 ${reactive_declarations}
18035 };
18036 `}
18037
18038 ${fixed_reactive_declarations}
18039
18040 return ${stringify_props(filtered_declarations)};
18041 }
18042 `);
18043 }
18044 const prop_names = `[${props.map(v => JSON.stringify(v.export_name)).join(', ')}]`;
18045 if (options.customElement) {
18046 builder.add_block(deindent `
18047 class ${name} extends @SvelteElement {
18048 constructor(options) {
18049 super();
18050
18051 ${css.code && `this.shadowRoot.innerHTML = \`<style>${escape(css.code, { only_escape_at_symbol: true }).replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
18052
18053 @init(this, { target: this.shadowRoot }, ${definition}, create_fragment, ${not_equal}, ${prop_names});
18054
18055 ${dev_props_check}
18056
18057 if (options) {
18058 if (options.target) {
18059 @insert(options.target, this, options.anchor);
18060 }
18061
18062 ${(props.length > 0 || uses_props) && deindent `
18063 if (options.props) {
18064 this.$set(options.props);
18065 @flush();
18066 }`}
18067 }
18068 }
18069
18070 ${props.length > 0 && deindent `
18071 static get observedAttributes() {
18072 return ${JSON.stringify(props.map(x => x.export_name))};
18073 }`}
18074
18075 ${body.length > 0 && body.join('\n\n')}
18076 }
18077 `);
18078 if (component.tag != null) {
18079 builder.add_block(deindent `
18080 @_customElements.define("${component.tag}", ${name});
18081 `);
18082 }
18083 }
18084 else {
18085 const superclass = options.dev ? 'SvelteComponentDev' : 'SvelteComponent';
18086 builder.add_block(deindent `
18087 class ${name} extends @${superclass} {
18088 constructor(options) {
18089 super(${options.dev && `options`});
18090 ${should_add_css && `if (!@_document.getElementById("${component.stylesheet.id}-style")) ${add_css}();`}
18091 @init(this, options, ${definition}, create_fragment, ${not_equal}, ${prop_names});
18092
18093 ${dev_props_check}
18094 }
18095
18096 ${body.length > 0 && body.join('\n\n')}
18097 }
18098 `);
18099 }
18100 return builder.toString();
18101 }
18102
18103 function AwaitBlock (node, renderer, options) {
18104 renderer.append('${(function(__value) { if(@is_promise(__value)) return `');
18105 renderer.render(node.pending.children, options);
18106 renderer.append('`; return function(' + (node.value || '') + ') { return `');
18107 renderer.render(node.then.children, options);
18108 const snippet = snip(node.expression);
18109 renderer.append(`\`;}(__value);}(${snippet})) }`);
18110 }
18111
18112 function Comment$1 (node, renderer, options) {
18113 if (options.preserveComments) {
18114 renderer.append(`<!--${node.data}-->`);
18115 }
18116 }
18117
18118 function DebugTag (node, renderer, options) {
18119 if (!options.dev)
18120 return;
18121 const filename = options.filename || null;
18122 const { line, column } = options.locate(node.start + 1);
18123 const obj = node.expressions.length === 0
18124 ? `{}`
18125 : `{ ${node.expressions
18126 .map(e => e.node.name)
18127 .join(', ')} }`;
18128 const str = '${@debug(' + `${filename && stringify(filename)}, ${line}, ${column}, ${obj})}`;
18129 renderer.append(str);
18130 }
18131
18132 function EachBlock (node, renderer, options) {
18133 const snippet = snip(node.expression);
18134 const { start, end } = node.context_node;
18135 const ctx = node.index
18136 ? `([✂${start}-${end}✂], ${node.index})`
18137 : `([✂${start}-${end}✂])`;
18138 const open = `\${${node.else ? `${snippet}.length ? ` : ''}@each(${snippet}, ${ctx} => \``;
18139 renderer.append(open);
18140 renderer.render(node.children, options);
18141 const close = `\`)`;
18142 renderer.append(close);
18143 if (node.else) {
18144 renderer.append(` : \``);
18145 renderer.render(node.else.children, options);
18146 renderer.append(`\``);
18147 }
18148 renderer.append('}');
18149 }
18150
18151 function get_slot_scope(lets) {
18152 if (lets.length === 0)
18153 return '';
18154 return `{ ${lets.map(l => l.value ? `${l.name}: ${l.value}` : l.name).join(', ')} }`;
18155 }
18156
18157 // source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
18158 const boolean_attributes = new Set([
18159 'async',
18160 'autocomplete',
18161 'autofocus',
18162 'autoplay',
18163 'border',
18164 'challenge',
18165 'checked',
18166 'compact',
18167 'contenteditable',
18168 'controls',
18169 'default',
18170 'defer',
18171 'disabled',
18172 'formnovalidate',
18173 'frameborder',
18174 'hidden',
18175 'indeterminate',
18176 'ismap',
18177 'loop',
18178 'multiple',
18179 'muted',
18180 'nohref',
18181 'noresize',
18182 'noshade',
18183 'novalidate',
18184 'nowrap',
18185 'open',
18186 'readonly',
18187 'required',
18188 'reversed',
18189 'scoped',
18190 'scrolling',
18191 'seamless',
18192 'selected',
18193 'sortable',
18194 'spellcheck',
18195 'translate'
18196 ]);
18197 function Element (node, renderer, options) {
18198 let opening_tag = `<${node.name}`;
18199 // awkward special case
18200 let node_contents;
18201 let value;
18202 const contenteditable = (node.name !== 'textarea' &&
18203 node.name !== 'input' &&
18204 node.attributes.some((attribute) => attribute.name === 'contenteditable'));
18205 const slot = node.get_static_attribute_value('slot');
18206 const component = node.find_nearest(/InlineComponent/);
18207 if (slot && component) {
18208 const slot = node.attributes.find((attribute) => attribute.name === 'slot');
18209 const slot_name = slot.chunks[0].data;
18210 const target = renderer.targets[renderer.targets.length - 1];
18211 target.slot_stack.push(slot_name);
18212 target.slots[slot_name] = '';
18213 const lets = node.lets;
18214 const seen = new Set(lets.map(l => l.name));
18215 component.lets.forEach(l => {
18216 if (!seen.has(l.name))
18217 lets.push(l);
18218 });
18219 options.slot_scopes.set(slot_name, get_slot_scope(node.lets));
18220 }
18221 const class_expression = node.classes.map((class_directive) => {
18222 const { expression, name } = class_directive;
18223 const snippet = expression ? snip(expression) : `ctx${quote_prop_if_necessary(name)}`;
18224 return `${snippet} ? "${name}" : ""`;
18225 }).join(', ');
18226 let add_class_attribute = class_expression ? true : false;
18227 if (node.attributes.find(attr => attr.is_spread)) {
18228 // TODO dry this out
18229 const args = [];
18230 node.attributes.forEach(attribute => {
18231 if (attribute.is_spread) {
18232 args.push(snip(attribute.expression));
18233 }
18234 else {
18235 if (attribute.name === 'value' && node.name === 'textarea') {
18236 node_contents = stringify_attribute(attribute, true);
18237 }
18238 else if (attribute.is_true) {
18239 args.push(`{ ${quote_name_if_necessary(attribute.name)}: true }`);
18240 }
18241 else if (boolean_attributes.has(attribute.name) &&
18242 attribute.chunks.length === 1 &&
18243 attribute.chunks[0].type !== 'Text') {
18244 // a boolean attribute with one non-Text chunk
18245 args.push(`{ ${quote_name_if_necessary(attribute.name)}: ${snip(attribute.chunks[0])} }`);
18246 }
18247 else {
18248 args.push(`{ ${quote_name_if_necessary(attribute.name)}: \`${stringify_attribute(attribute, true)}\` }`);
18249 }
18250 }
18251 });
18252 opening_tag += "${@spread([" + args.join(', ') + "])}";
18253 }
18254 else {
18255 node.attributes.forEach((attribute) => {
18256 if (attribute.type !== 'Attribute')
18257 return;
18258 if (attribute.name === 'value' && node.name === 'textarea') {
18259 node_contents = stringify_attribute(attribute, true);
18260 }
18261 else if (attribute.is_true) {
18262 opening_tag += ` ${attribute.name}`;
18263 }
18264 else if (boolean_attributes.has(attribute.name) &&
18265 attribute.chunks.length === 1 &&
18266 attribute.chunks[0].type !== 'Text') {
18267 // a boolean attribute with one non-Text chunk
18268 opening_tag += '${' + snip(attribute.chunks[0]) + ' ? " ' + attribute.name + '" : "" }';
18269 }
18270 else if (attribute.name === 'class' && class_expression) {
18271 add_class_attribute = false;
18272 opening_tag += ` class="\${[\`${stringify_attribute(attribute, true)}\`, ${class_expression}].join(' ').trim() }"`;
18273 }
18274 else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
18275 const { name } = attribute;
18276 const snippet = snip(attribute.chunks[0]);
18277 opening_tag += '${(v => v == null ? "" : ` ' + name + '="${@escape(' + snippet + ')}"`)(' + snippet + ')}';
18278 }
18279 else {
18280 opening_tag += ` ${attribute.name}="${stringify_attribute(attribute, true)}"`;
18281 }
18282 });
18283 }
18284 node.bindings.forEach(binding => {
18285 const { name, expression } = binding;
18286 if (binding.is_readonly) {
18287 return;
18288 }
18289 if (name === 'group') ;
18290 else if (contenteditable && (name === 'textContent' || name === 'innerHTML')) {
18291 node_contents = snip(expression);
18292 value = name === 'textContent' ? '@escape($$value)' : '$$value';
18293 }
18294 else if (binding.name === 'value' && node.name === 'textarea') {
18295 const snippet = snip(expression);
18296 node_contents = '${(' + snippet + ') || ""}';
18297 }
18298 else {
18299 const snippet = snip(expression);
18300 opening_tag += '${@add_attribute("' + name + '", ' + snippet + ')}';
18301 }
18302 });
18303 if (add_class_attribute) {
18304 opening_tag += `\${@add_classes([${class_expression}].join(' ').trim())}`;
18305 }
18306 opening_tag += '>';
18307 renderer.append(opening_tag);
18308 if (node_contents !== undefined) {
18309 if (contenteditable) {
18310 renderer.append('${($$value => $$value === void 0 ? `');
18311 renderer.render(node.children, options);
18312 renderer.append('` : ' + value + ')(' + node_contents + ')}');
18313 }
18314 else {
18315 renderer.append(node_contents);
18316 }
18317 }
18318 else {
18319 renderer.render(node.children, options);
18320 }
18321 if (!is_void(node.name)) {
18322 renderer.append(`</${node.name}>`);
18323 }
18324 }
18325
18326 function Head (node, renderer, options) {
18327 renderer.append('${($$result.head += `');
18328 renderer.render(node.children, options);
18329 renderer.append('`, "")}');
18330 }
18331
18332 function HtmlTag (node, renderer, _options) {
18333 renderer.append('${' + snip(node.expression) + '}');
18334 }
18335
18336 function IfBlock (node, renderer, options) {
18337 const snippet = snip(node.expression);
18338 renderer.append('${ ' + snippet + ' ? `');
18339 renderer.render(node.children, options);
18340 renderer.append('` : `');
18341 if (node.else) {
18342 renderer.render(node.else.children, options);
18343 }
18344 renderer.append('` }');
18345 }
18346
18347 function stringify_attribute$1(chunk) {
18348 if (chunk.type === 'Text') {
18349 return escape_template(escape(chunk.data));
18350 }
18351 return '${@escape(' + snip(chunk) + ')}';
18352 }
18353 function get_attribute_value(attribute) {
18354 if (attribute.is_true)
18355 return `true`;
18356 if (attribute.chunks.length === 0)
18357 return `''`;
18358 if (attribute.chunks.length === 1) {
18359 const chunk = attribute.chunks[0];
18360 if (chunk.type === 'Text') {
18361 return stringify(chunk.data);
18362 }
18363 return snip(chunk);
18364 }
18365 return '`' + attribute.chunks.map(stringify_attribute$1).join('') + '`';
18366 }
18367 function InlineComponent (node, renderer, options) {
18368 const binding_props = [];
18369 const binding_fns = [];
18370 node.bindings.forEach(binding => {
18371 renderer.has_bindings = true;
18372 // TODO this probably won't work for contextual bindings
18373 const snippet = snip(binding.expression);
18374 binding_props.push(`${binding.name}: ${snippet}`);
18375 binding_fns.push(`${binding.name}: $$value => { ${snippet} = $$value; $$settled = false }`);
18376 });
18377 const uses_spread = node.attributes.find(attr => attr.is_spread);
18378 let props;
18379 if (uses_spread) {
18380 props = `@_Object.assign(${node.attributes
18381 .map(attribute => {
18382 if (attribute.is_spread) {
18383 return snip(attribute.expression);
18384 }
18385 else {
18386 return `{ ${attribute.name}: ${get_attribute_value(attribute)} }`;
18387 }
18388 })
18389 .concat(binding_props.map(p => `{ ${p} }`))
18390 .join(', ')})`;
18391 }
18392 else {
18393 props = stringify_props(node.attributes
18394 .map(attribute => `${attribute.name}: ${get_attribute_value(attribute)}`)
18395 .concat(binding_props));
18396 }
18397 const bindings = stringify_props(binding_fns);
18398 const expression = (node.name === 'svelte:self'
18399 ? '__svelte:self__' // TODO conflict-proof this
18400 : node.name === 'svelte:component'
18401 ? `((${snip(node.expression)}) || @missing_component)`
18402 : node.name);
18403 const slot_fns = [];
18404 if (node.children.length) {
18405 const target = {
18406 slots: { default: '' },
18407 slot_stack: ['default']
18408 };
18409 renderer.targets.push(target);
18410 const slot_scopes = new Map();
18411 slot_scopes.set('default', get_slot_scope(node.lets));
18412 renderer.render(node.children, Object.assign({}, options, {
18413 slot_scopes
18414 }));
18415 Object.keys(target.slots).forEach(name => {
18416 const slot_scope = slot_scopes.get(name);
18417 slot_fns.push(`${quote_name_if_necessary(name)}: (${slot_scope}) => \`${target.slots[name]}\``);
18418 });
18419 renderer.targets.pop();
18420 }
18421 const slots = stringify_props(slot_fns);
18422 renderer.append(`\${@validate_component(${expression}, '${node.name}').$$render($$result, ${props}, ${bindings}, ${slots})}`);
18423 }
18424
18425 function Slot (node, renderer, options) {
18426 const prop = quote_prop_if_necessary(node.slot_name);
18427 const slot_data = get_slot_data(node.values, true);
18428 const arg = slot_data.length > 0 ? `{ ${slot_data.join(', ')} }` : '';
18429 renderer.append(`\${$$slots${prop} ? $$slots${prop}(${arg}) : \``);
18430 renderer.render(node.children, options);
18431 renderer.append(`\`}`);
18432 }
18433
18434 function Tag$1 (node, renderer, _options) {
18435 const snippet = snip(node.expression);
18436 renderer.append(node.parent &&
18437 node.parent.type === 'Element' &&
18438 node.parent.name === 'style'
18439 ? '${' + snippet + '}'
18440 : '${@escape(' + snippet + ')}');
18441 }
18442
18443 function Text (node, renderer, _options) {
18444 let text = node.data;
18445 if (!node.parent ||
18446 node.parent.type !== 'Element' ||
18447 (node.parent.name !== 'script' && node.parent.name !== 'style')) {
18448 // unless this Text node is inside a <script> or <style> element, escape &,<,>
18449 text = escape_html(text);
18450 }
18451 renderer.append(escape(escape_template(text)));
18452 }
18453
18454 function Title (node, renderer, options) {
18455 renderer.append(`<title>`);
18456 renderer.render(node.children, options);
18457 renderer.append(`</title>`);
18458 }
18459
18460 function noop$1() { }
18461 const handlers = {
18462 AwaitBlock,
18463 Body: noop$1,
18464 Comment: Comment$1,
18465 DebugTag,
18466 EachBlock,
18467 Element,
18468 Head,
18469 IfBlock,
18470 InlineComponent,
18471 MustacheTag: Tag$1,
18472 Options: noop$1,
18473 RawMustacheTag: HtmlTag,
18474 Slot,
18475 Text,
18476 Title,
18477 Window: noop$1
18478 };
18479 class Renderer$1 {
18480 constructor() {
18481 this.has_bindings = false;
18482 this.code = '';
18483 this.targets = [];
18484 }
18485 append(code) {
18486 if (this.targets.length) {
18487 const target = this.targets[this.targets.length - 1];
18488 const slot_name = target.slot_stack[target.slot_stack.length - 1];
18489 target.slots[slot_name] += code;
18490 }
18491 else {
18492 this.code += code;
18493 }
18494 }
18495 render(nodes, options) {
18496 nodes.forEach(node => {
18497 const handler = handlers[node.type];
18498 if (!handler) {
18499 throw new Error(`No handler for '${node.type}' nodes`);
18500 }
18501 handler(node, this, options);
18502 });
18503 }
18504 }
18505
18506 function ssr(component, options) {
18507 const renderer = new Renderer$1();
18508 const { name } = component;
18509 // create $$render function
18510 renderer.render(trim(component.fragment.children), Object.assign({
18511 locate: component.locate
18512 }, options));
18513 // TODO concatenate CSS maps
18514 const css = options.customElement ?
18515 { code: null, map: null } :
18516 component.stylesheet.render(options.filename, true);
18517 const reactive_stores = component.vars.filter(variable => variable.name[0] === '$' && variable.name[1] !== '$');
18518 const reactive_store_values = reactive_stores
18519 .map(({ name }) => {
18520 const store_name = name.slice(1);
18521 const store = component.var_lookup.get(store_name);
18522 if (store && store.hoistable)
18523 return;
18524 const assignment = `${name} = @get_store_value(${store_name});`;
18525 return component.compile_options.dev
18526 ? `@validate_store(${store_name}, '${store_name}'); ${assignment}`
18527 : assignment;
18528 });
18529 // TODO remove this, just use component.vars everywhere
18530 const props = component.vars.filter(variable => !variable.module && variable.export_name);
18531 if (component.javascript) {
18532 component.rewrite_props(({ name }) => {
18533 const value = `$${name}`;
18534 const get_store_value = component.helper('get_store_value');
18535 let insert = `${value} = ${get_store_value}(${name})`;
18536 if (component.compile_options.dev) {
18537 const validate_store = component.helper('validate_store');
18538 insert = `${validate_store}(${name}, '${name}'); ${insert}`;
18539 }
18540 return insert;
18541 });
18542 }
18543 // TODO only do this for props with a default value
18544 const parent_bindings = component.javascript
18545 ? props.map(prop => {
18546 return `if ($$props.${prop.export_name} === void 0 && $$bindings.${prop.export_name} && ${prop.name} !== void 0) $$bindings.${prop.export_name}(${prop.name});`;
18547 })
18548 : [];
18549 const reactive_declarations = component.reactive_declarations.map(d => {
18550 let snippet = `[✂${d.node.body.start}-${d.node.end}✂]`;
18551 if (d.declaration) {
18552 const declared = extract_names(d.declaration);
18553 const injected = declared.filter(name => {
18554 return name[0] !== '$' && component.var_lookup.get(name).injected;
18555 });
18556 const self_dependencies = injected.filter(name => d.dependencies.has(name));
18557 if (injected.length) {
18558 // in some cases we need to do `let foo; [expression]`, in
18559 // others we can do `let [expression]`
18560 const separate = (self_dependencies.length > 0 ||
18561 declared.length > injected.length ||
18562 d.node.body.expression.type === 'ParenthesizedExpression');
18563 snippet = separate
18564 ? `let ${injected.join(', ')}; ${snippet}`
18565 : `let ${snippet}`;
18566 }
18567 }
18568 return snippet;
18569 });
18570 const main = renderer.has_bindings
18571 ? deindent `
18572 let $$settled;
18573 let $$rendered;
18574
18575 do {
18576 $$settled = true;
18577
18578 ${reactive_store_values}
18579
18580 ${reactive_declarations}
18581
18582 $$rendered = \`${renderer.code}\`;
18583 } while (!$$settled);
18584
18585 return $$rendered;
18586 `
18587 : deindent `
18588 ${reactive_store_values}
18589
18590 ${reactive_declarations}
18591
18592 return \`${renderer.code}\`;`;
18593 const blocks = [
18594 reactive_stores.length > 0 && `let ${reactive_stores
18595 .map(({ name }) => {
18596 const store_name = name.slice(1);
18597 const store = component.var_lookup.get(store_name);
18598 if (store && store.hoistable) {
18599 const get_store_value = component.helper('get_store_value');
18600 return `${name} = ${get_store_value}(${store_name})`;
18601 }
18602 return name;
18603 })
18604 .join(', ')};`,
18605 component.javascript,
18606 parent_bindings.join('\n'),
18607 css.code && `$$result.css.add(#css);`,
18608 main
18609 ].filter(Boolean);
18610 return (deindent `
18611 ${css.code && deindent `
18612 const #css = {
18613 code: ${css.code ? stringify(css.code) : `''`},
18614 map: ${css.map ? stringify(css.map.toString()) : 'null'}
18615 };`}
18616
18617 ${component.module_javascript}
18618
18619 ${component.fully_hoisted.length > 0 && component.fully_hoisted.join('\n\n')}
18620
18621 const ${name} = @create_ssr_component(($$result, $$props, $$bindings, $$slots) => {
18622 ${blocks.join('\n\n')}
18623 });
18624 `).trim();
18625 }
18626 function trim(nodes) {
18627 let start = 0;
18628 for (; start < nodes.length; start += 1) {
18629 const node = nodes[start];
18630 if (node.type !== 'Text')
18631 break;
18632 node.data = node.data.replace(/^\s+/, '');
18633 if (node.data)
18634 break;
18635 }
18636 let end = nodes.length;
18637 for (; end > start; end -= 1) {
18638 const node = nodes[end - 1];
18639 if (node.type !== 'Text')
18640 break;
18641 node.data = node.data.replace(/\s+$/, '');
18642 if (node.data)
18643 break;
18644 }
18645 return nodes.slice(start, end);
18646 }
18647
18648 var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
18649 function encode(decoded) {
18650 var sourceFileIndex = 0; // second field
18651 var sourceCodeLine = 0; // third field
18652 var sourceCodeColumn = 0; // fourth field
18653 var nameIndex = 0; // fifth field
18654 var mappings = '';
18655 for (var i = 0; i < decoded.length; i++) {
18656 var line = decoded[i];
18657 if (i > 0)
18658 mappings += ';';
18659 if (line.length === 0)
18660 continue;
18661 var generatedCodeColumn = 0; // first field
18662 var lineMappings = [];
18663 for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
18664 var segment = line_1[_i];
18665 var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
18666 generatedCodeColumn = segment[0];
18667 if (segment.length > 1) {
18668 segmentMappings +=
18669 encodeInteger(segment[1] - sourceFileIndex) +
18670 encodeInteger(segment[2] - sourceCodeLine) +
18671 encodeInteger(segment[3] - sourceCodeColumn);
18672 sourceFileIndex = segment[1];
18673 sourceCodeLine = segment[2];
18674 sourceCodeColumn = segment[3];
18675 }
18676 if (segment.length === 5) {
18677 segmentMappings += encodeInteger(segment[4] - nameIndex);
18678 nameIndex = segment[4];
18679 }
18680 lineMappings.push(segmentMappings);
18681 }
18682 mappings += lineMappings.join(',');
18683 }
18684 return mappings;
18685 }
18686 function encodeInteger(num) {
18687 var result = '';
18688 num = num < 0 ? (-num << 1) | 1 : num << 1;
18689 do {
18690 var clamped = num & 31;
18691 num >>>= 5;
18692 if (num > 0) {
18693 clamped |= 32;
18694 }
18695 result += chars[clamped];
18696 } while (num > 0);
18697 return result;
18698 }
18699
18700 var Chunk = function Chunk(start, end, content) {
18701 this.start = start;
18702 this.end = end;
18703 this.original = content;
18704
18705 this.intro = '';
18706 this.outro = '';
18707
18708 this.content = content;
18709 this.storeName = false;
18710 this.edited = false;
18711
18712 // we make these non-enumerable, for sanity while debugging
18713 Object.defineProperties(this, {
18714 previous: { writable: true, value: null },
18715 next: { writable: true, value: null }
18716 });
18717 };
18718
18719 Chunk.prototype.appendLeft = function appendLeft (content) {
18720 this.outro += content;
18721 };
18722
18723 Chunk.prototype.appendRight = function appendRight (content) {
18724 this.intro = this.intro + content;
18725 };
18726
18727 Chunk.prototype.clone = function clone () {
18728 var chunk = new Chunk(this.start, this.end, this.original);
18729
18730 chunk.intro = this.intro;
18731 chunk.outro = this.outro;
18732 chunk.content = this.content;
18733 chunk.storeName = this.storeName;
18734 chunk.edited = this.edited;
18735
18736 return chunk;
18737 };
18738
18739 Chunk.prototype.contains = function contains (index) {
18740 return this.start < index && index < this.end;
18741 };
18742
18743 Chunk.prototype.eachNext = function eachNext (fn) {
18744 var chunk = this;
18745 while (chunk) {
18746 fn(chunk);
18747 chunk = chunk.next;
18748 }
18749 };
18750
18751 Chunk.prototype.eachPrevious = function eachPrevious (fn) {
18752 var chunk = this;
18753 while (chunk) {
18754 fn(chunk);
18755 chunk = chunk.previous;
18756 }
18757 };
18758
18759 Chunk.prototype.edit = function edit (content, storeName, contentOnly) {
18760 this.content = content;
18761 if (!contentOnly) {
18762 this.intro = '';
18763 this.outro = '';
18764 }
18765 this.storeName = storeName;
18766
18767 this.edited = true;
18768
18769 return this;
18770 };
18771
18772 Chunk.prototype.prependLeft = function prependLeft (content) {
18773 this.outro = content + this.outro;
18774 };
18775
18776 Chunk.prototype.prependRight = function prependRight (content) {
18777 this.intro = content + this.intro;
18778 };
18779
18780 Chunk.prototype.split = function split (index) {
18781 var sliceIndex = index - this.start;
18782
18783 var originalBefore = this.original.slice(0, sliceIndex);
18784 var originalAfter = this.original.slice(sliceIndex);
18785
18786 this.original = originalBefore;
18787
18788 var newChunk = new Chunk(index, this.end, originalAfter);
18789 newChunk.outro = this.outro;
18790 this.outro = '';
18791
18792 this.end = index;
18793
18794 if (this.edited) {
18795 // TODO is this block necessary?...
18796 newChunk.edit('', false);
18797 this.content = '';
18798 } else {
18799 this.content = originalBefore;
18800 }
18801
18802 newChunk.next = this.next;
18803 if (newChunk.next) { newChunk.next.previous = newChunk; }
18804 newChunk.previous = this;
18805 this.next = newChunk;
18806
18807 return newChunk;
18808 };
18809
18810 Chunk.prototype.toString = function toString () {
18811 return this.intro + this.content + this.outro;
18812 };
18813
18814 Chunk.prototype.trimEnd = function trimEnd (rx) {
18815 this.outro = this.outro.replace(rx, '');
18816 if (this.outro.length) { return true; }
18817
18818 var trimmed = this.content.replace(rx, '');
18819
18820 if (trimmed.length) {
18821 if (trimmed !== this.content) {
18822 this.split(this.start + trimmed.length).edit('', undefined, true);
18823 }
18824 return true;
18825
18826 } else {
18827 this.edit('', undefined, true);
18828
18829 this.intro = this.intro.replace(rx, '');
18830 if (this.intro.length) { return true; }
18831 }
18832 };
18833
18834 Chunk.prototype.trimStart = function trimStart (rx) {
18835 this.intro = this.intro.replace(rx, '');
18836 if (this.intro.length) { return true; }
18837
18838 var trimmed = this.content.replace(rx, '');
18839
18840 if (trimmed.length) {
18841 if (trimmed !== this.content) {
18842 this.split(this.end - trimmed.length);
18843 this.edit('', undefined, true);
18844 }
18845 return true;
18846
18847 } else {
18848 this.edit('', undefined, true);
18849
18850 this.outro = this.outro.replace(rx, '');
18851 if (this.outro.length) { return true; }
18852 }
18853 };
18854
18855 var btoa = function () {
18856 throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
18857 };
18858 if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
18859 btoa = function (str) { return window.btoa(unescape(encodeURIComponent(str))); };
18860 } else if (typeof Buffer === 'function') {
18861 btoa = function (str) { return Buffer.from(str, 'utf-8').toString('base64'); };
18862 }
18863
18864 var SourceMap = function SourceMap(properties) {
18865 this.version = 3;
18866 this.file = properties.file;
18867 this.sources = properties.sources;
18868 this.sourcesContent = properties.sourcesContent;
18869 this.names = properties.names;
18870 this.mappings = encode(properties.mappings);
18871 };
18872
18873 SourceMap.prototype.toString = function toString () {
18874 return JSON.stringify(this);
18875 };
18876
18877 SourceMap.prototype.toUrl = function toUrl () {
18878 return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
18879 };
18880
18881 function guessIndent(code) {
18882 var lines = code.split('\n');
18883
18884 var tabbed = lines.filter(function (line) { return /^\t+/.test(line); });
18885 var spaced = lines.filter(function (line) { return /^ {2,}/.test(line); });
18886
18887 if (tabbed.length === 0 && spaced.length === 0) {
18888 return null;
18889 }
18890
18891 // More lines tabbed than spaced? Assume tabs, and
18892 // default to tabs in the case of a tie (or nothing
18893 // to go on)
18894 if (tabbed.length >= spaced.length) {
18895 return '\t';
18896 }
18897
18898 // Otherwise, we need to guess the multiple
18899 var min = spaced.reduce(function (previous, current) {
18900 var numSpaces = /^ +/.exec(current)[0].length;
18901 return Math.min(numSpaces, previous);
18902 }, Infinity);
18903
18904 return new Array(min + 1).join(' ');
18905 }
18906
18907 function getRelativePath(from, to) {
18908 var fromParts = from.split(/[/\\]/);
18909 var toParts = to.split(/[/\\]/);
18910
18911 fromParts.pop(); // get dirname
18912
18913 while (fromParts[0] === toParts[0]) {
18914 fromParts.shift();
18915 toParts.shift();
18916 }
18917
18918 if (fromParts.length) {
18919 var i = fromParts.length;
18920 while (i--) { fromParts[i] = '..'; }
18921 }
18922
18923 return fromParts.concat(toParts).join('/');
18924 }
18925
18926 var toString$2 = Object.prototype.toString;
18927
18928 function isObject(thing) {
18929 return toString$2.call(thing) === '[object Object]';
18930 }
18931
18932 function getLocator$1(source) {
18933 var originalLines = source.split('\n');
18934 var lineOffsets = [];
18935
18936 for (var i = 0, pos = 0; i < originalLines.length; i++) {
18937 lineOffsets.push(pos);
18938 pos += originalLines[i].length + 1;
18939 }
18940
18941 return function locate(index) {
18942 var i = 0;
18943 var j = lineOffsets.length;
18944 while (i < j) {
18945 var m = (i + j) >> 1;
18946 if (index < lineOffsets[m]) {
18947 j = m;
18948 } else {
18949 i = m + 1;
18950 }
18951 }
18952 var line = i - 1;
18953 var column = index - lineOffsets[line];
18954 return { line: line, column: column };
18955 };
18956 }
18957
18958 var Mappings = function Mappings(hires) {
18959 this.hires = hires;
18960 this.generatedCodeLine = 0;
18961 this.generatedCodeColumn = 0;
18962 this.raw = [];
18963 this.rawSegments = this.raw[this.generatedCodeLine] = [];
18964 this.pending = null;
18965 };
18966
18967 Mappings.prototype.addEdit = function addEdit (sourceIndex, content, loc, nameIndex) {
18968 if (content.length) {
18969 var segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
18970 if (nameIndex >= 0) {
18971 segment.push(nameIndex);
18972 }
18973 this.rawSegments.push(segment);
18974 } else if (this.pending) {
18975 this.rawSegments.push(this.pending);
18976 }
18977
18978 this.advance(content);
18979 this.pending = null;
18980 };
18981
18982 Mappings.prototype.addUneditedChunk = function addUneditedChunk (sourceIndex, chunk, original, loc, sourcemapLocations) {
18983 var originalCharIndex = chunk.start;
18984 var first = true;
18985
18986 while (originalCharIndex < chunk.end) {
18987 if (this.hires || first || sourcemapLocations[originalCharIndex]) {
18988 this.rawSegments.push([this.generatedCodeColumn, sourceIndex, loc.line, loc.column]);
18989 }
18990
18991 if (original[originalCharIndex] === '\n') {
18992 loc.line += 1;
18993 loc.column = 0;
18994 this.generatedCodeLine += 1;
18995 this.raw[this.generatedCodeLine] = this.rawSegments = [];
18996 this.generatedCodeColumn = 0;
18997 } else {
18998 loc.column += 1;
18999 this.generatedCodeColumn += 1;
19000 }
19001
19002 originalCharIndex += 1;
19003 first = false;
19004 }
19005
19006 this.pending = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
19007 };
19008
19009 Mappings.prototype.advance = function advance (str) {
19010 if (!str) { return; }
19011
19012 var lines = str.split('\n');
19013
19014 if (lines.length > 1) {
19015 for (var i = 0; i < lines.length - 1; i++) {
19016 this.generatedCodeLine++;
19017 this.raw[this.generatedCodeLine] = this.rawSegments = [];
19018 }
19019 this.generatedCodeColumn = 0;
19020 }
19021
19022 this.generatedCodeColumn += lines[lines.length - 1].length;
19023 };
19024
19025 var n = '\n';
19026
19027 var warned = {
19028 insertLeft: false,
19029 insertRight: false,
19030 storeName: false
19031 };
19032
19033 var MagicString = function MagicString(string, options) {
19034 if ( options === void 0 ) options = {};
19035
19036 var chunk = new Chunk(0, string.length, string);
19037
19038 Object.defineProperties(this, {
19039 original: { writable: true, value: string },
19040 outro: { writable: true, value: '' },
19041 intro: { writable: true, value: '' },
19042 firstChunk: { writable: true, value: chunk },
19043 lastChunk: { writable: true, value: chunk },
19044 lastSearchedChunk: { writable: true, value: chunk },
19045 byStart: { writable: true, value: {} },
19046 byEnd: { writable: true, value: {} },
19047 filename: { writable: true, value: options.filename },
19048 indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
19049 sourcemapLocations: { writable: true, value: {} },
19050 storedNames: { writable: true, value: {} },
19051 indentStr: { writable: true, value: guessIndent(string) }
19052 });
19053
19054 this.byStart[0] = chunk;
19055 this.byEnd[string.length] = chunk;
19056 };
19057
19058 MagicString.prototype.addSourcemapLocation = function addSourcemapLocation (char) {
19059 this.sourcemapLocations[char] = true;
19060 };
19061
19062 MagicString.prototype.append = function append (content) {
19063 if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
19064
19065 this.outro += content;
19066 return this;
19067 };
19068
19069 MagicString.prototype.appendLeft = function appendLeft (index, content) {
19070 if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
19071
19072 this._split(index);
19073
19074 var chunk = this.byEnd[index];
19075
19076 if (chunk) {
19077 chunk.appendLeft(content);
19078 } else {
19079 this.intro += content;
19080 }
19081 return this;
19082 };
19083
19084 MagicString.prototype.appendRight = function appendRight (index, content) {
19085 if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
19086
19087 this._split(index);
19088
19089 var chunk = this.byStart[index];
19090
19091 if (chunk) {
19092 chunk.appendRight(content);
19093 } else {
19094 this.outro += content;
19095 }
19096 return this;
19097 };
19098
19099 MagicString.prototype.clone = function clone () {
19100 var cloned = new MagicString(this.original, { filename: this.filename });
19101
19102 var originalChunk = this.firstChunk;
19103 var clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());
19104
19105 while (originalChunk) {
19106 cloned.byStart[clonedChunk.start] = clonedChunk;
19107 cloned.byEnd[clonedChunk.end] = clonedChunk;
19108
19109 var nextOriginalChunk = originalChunk.next;
19110 var nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
19111
19112 if (nextClonedChunk) {
19113 clonedChunk.next = nextClonedChunk;
19114 nextClonedChunk.previous = clonedChunk;
19115
19116 clonedChunk = nextClonedChunk;
19117 }
19118
19119 originalChunk = nextOriginalChunk;
19120 }
19121
19122 cloned.lastChunk = clonedChunk;
19123
19124 if (this.indentExclusionRanges) {
19125 cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
19126 }
19127
19128 Object.keys(this.sourcemapLocations).forEach(function (loc) {
19129 cloned.sourcemapLocations[loc] = true;
19130 });
19131
19132 return cloned;
19133 };
19134
19135 MagicString.prototype.generateDecodedMap = function generateDecodedMap (options) {
19136 var this$1 = this;
19137
19138 options = options || {};
19139
19140 var sourceIndex = 0;
19141 var names = Object.keys(this.storedNames);
19142 var mappings = new Mappings(options.hires);
19143
19144 var locate = getLocator$1(this.original);
19145
19146 if (this.intro) {
19147 mappings.advance(this.intro);
19148 }
19149
19150 this.firstChunk.eachNext(function (chunk) {
19151 var loc = locate(chunk.start);
19152
19153 if (chunk.intro.length) { mappings.advance(chunk.intro); }
19154
19155 if (chunk.edited) {
19156 mappings.addEdit(
19157 sourceIndex,
19158 chunk.content,
19159 loc,
19160 chunk.storeName ? names.indexOf(chunk.original) : -1
19161 );
19162 } else {
19163 mappings.addUneditedChunk(sourceIndex, chunk, this$1.original, loc, this$1.sourcemapLocations);
19164 }
19165
19166 if (chunk.outro.length) { mappings.advance(chunk.outro); }
19167 });
19168
19169 return {
19170 file: options.file ? options.file.split(/[/\\]/).pop() : null,
19171 sources: [options.source ? getRelativePath(options.file || '', options.source) : null],
19172 sourcesContent: options.includeContent ? [this.original] : [null],
19173 names: names,
19174 mappings: mappings.raw
19175 };
19176 };
19177
19178 MagicString.prototype.generateMap = function generateMap (options) {
19179 return new SourceMap(this.generateDecodedMap(options));
19180 };
19181
19182 MagicString.prototype.getIndentString = function getIndentString () {
19183 return this.indentStr === null ? '\t' : this.indentStr;
19184 };
19185
19186 MagicString.prototype.indent = function indent (indentStr, options) {
19187 var pattern = /^[^\r\n]/gm;
19188
19189 if (isObject(indentStr)) {
19190 options = indentStr;
19191 indentStr = undefined;
19192 }
19193
19194 indentStr = indentStr !== undefined ? indentStr : this.indentStr || '\t';
19195
19196 if (indentStr === '') { return this; } // noop
19197
19198 options = options || {};
19199
19200 // Process exclusion ranges
19201 var isExcluded = {};
19202
19203 if (options.exclude) {
19204 var exclusions =
19205 typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
19206 exclusions.forEach(function (exclusion) {
19207 for (var i = exclusion[0]; i < exclusion[1]; i += 1) {
19208 isExcluded[i] = true;
19209 }
19210 });
19211 }
19212
19213 var shouldIndentNextCharacter = options.indentStart !== false;
19214 var replacer = function (match) {
19215 if (shouldIndentNextCharacter) { return ("" + indentStr + match); }
19216 shouldIndentNextCharacter = true;
19217 return match;
19218 };
19219
19220 this.intro = this.intro.replace(pattern, replacer);
19221
19222 var charIndex = 0;
19223 var chunk = this.firstChunk;
19224
19225 while (chunk) {
19226 var end = chunk.end;
19227
19228 if (chunk.edited) {
19229 if (!isExcluded[charIndex]) {
19230 chunk.content = chunk.content.replace(pattern, replacer);
19231
19232 if (chunk.content.length) {
19233 shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
19234 }
19235 }
19236 } else {
19237 charIndex = chunk.start;
19238
19239 while (charIndex < end) {
19240 if (!isExcluded[charIndex]) {
19241 var char = this.original[charIndex];
19242
19243 if (char === '\n') {
19244 shouldIndentNextCharacter = true;
19245 } else if (char !== '\r' && shouldIndentNextCharacter) {
19246 shouldIndentNextCharacter = false;
19247
19248 if (charIndex === chunk.start) {
19249 chunk.prependRight(indentStr);
19250 } else {
19251 this._splitChunk(chunk, charIndex);
19252 chunk = chunk.next;
19253 chunk.prependRight(indentStr);
19254 }
19255 }
19256 }
19257
19258 charIndex += 1;
19259 }
19260 }
19261
19262 charIndex = chunk.end;
19263 chunk = chunk.next;
19264 }
19265
19266 this.outro = this.outro.replace(pattern, replacer);
19267
19268 return this;
19269 };
19270
19271 MagicString.prototype.insert = function insert () {
19272 throw new Error('magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)');
19273 };
19274
19275 MagicString.prototype.insertLeft = function insertLeft (index, content) {
19276 if (!warned.insertLeft) {
19277 console.warn('magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'); // eslint-disable-line no-console
19278 warned.insertLeft = true;
19279 }
19280
19281 return this.appendLeft(index, content);
19282 };
19283
19284 MagicString.prototype.insertRight = function insertRight (index, content) {
19285 if (!warned.insertRight) {
19286 console.warn('magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'); // eslint-disable-line no-console
19287 warned.insertRight = true;
19288 }
19289
19290 return this.prependRight(index, content);
19291 };
19292
19293 MagicString.prototype.move = function move (start, end, index) {
19294 if (index >= start && index <= end) { throw new Error('Cannot move a selection inside itself'); }
19295
19296 this._split(start);
19297 this._split(end);
19298 this._split(index);
19299
19300 var first = this.byStart[start];
19301 var last = this.byEnd[end];
19302
19303 var oldLeft = first.previous;
19304 var oldRight = last.next;
19305
19306 var newRight = this.byStart[index];
19307 if (!newRight && last === this.lastChunk) { return this; }
19308 var newLeft = newRight ? newRight.previous : this.lastChunk;
19309
19310 if (oldLeft) { oldLeft.next = oldRight; }
19311 if (oldRight) { oldRight.previous = oldLeft; }
19312
19313 if (newLeft) { newLeft.next = first; }
19314 if (newRight) { newRight.previous = last; }
19315
19316 if (!first.previous) { this.firstChunk = last.next; }
19317 if (!last.next) {
19318 this.lastChunk = first.previous;
19319 this.lastChunk.next = null;
19320 }
19321
19322 first.previous = newLeft;
19323 last.next = newRight || null;
19324
19325 if (!newLeft) { this.firstChunk = first; }
19326 if (!newRight) { this.lastChunk = last; }
19327 return this;
19328 };
19329
19330 MagicString.prototype.overwrite = function overwrite (start, end, content, options) {
19331 if (typeof content !== 'string') { throw new TypeError('replacement content must be a string'); }
19332
19333 while (start < 0) { start += this.original.length; }
19334 while (end < 0) { end += this.original.length; }
19335
19336 if (end > this.original.length) { throw new Error('end is out of bounds'); }
19337 if (start === end)
19338 { throw new Error('Cannot overwrite a zero-length range – use appendLeft or prependRight instead'); }
19339
19340 this._split(start);
19341 this._split(end);
19342
19343 if (options === true) {
19344 if (!warned.storeName) {
19345 console.warn('The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'); // eslint-disable-line no-console
19346 warned.storeName = true;
19347 }
19348
19349 options = { storeName: true };
19350 }
19351 var storeName = options !== undefined ? options.storeName : false;
19352 var contentOnly = options !== undefined ? options.contentOnly : false;
19353
19354 if (storeName) {
19355 var original = this.original.slice(start, end);
19356 this.storedNames[original] = true;
19357 }
19358
19359 var first = this.byStart[start];
19360 var last = this.byEnd[end];
19361
19362 if (first) {
19363 if (end > first.end && first.next !== this.byStart[first.end]) {
19364 throw new Error('Cannot overwrite across a split point');
19365 }
19366
19367 first.edit(content, storeName, contentOnly);
19368
19369 if (first !== last) {
19370 var chunk = first.next;
19371 while (chunk !== last) {
19372 chunk.edit('', false);
19373 chunk = chunk.next;
19374 }
19375
19376 chunk.edit('', false);
19377 }
19378 } else {
19379 // must be inserting at the end
19380 var newChunk = new Chunk(start, end, '').edit(content, storeName);
19381
19382 // TODO last chunk in the array may not be the last chunk, if it's moved...
19383 last.next = newChunk;
19384 newChunk.previous = last;
19385 }
19386 return this;
19387 };
19388
19389 MagicString.prototype.prepend = function prepend (content) {
19390 if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
19391
19392 this.intro = content + this.intro;
19393 return this;
19394 };
19395
19396 MagicString.prototype.prependLeft = function prependLeft (index, content) {
19397 if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
19398
19399 this._split(index);
19400
19401 var chunk = this.byEnd[index];
19402
19403 if (chunk) {
19404 chunk.prependLeft(content);
19405 } else {
19406 this.intro = content + this.intro;
19407 }
19408 return this;
19409 };
19410
19411 MagicString.prototype.prependRight = function prependRight (index, content) {
19412 if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
19413
19414 this._split(index);
19415
19416 var chunk = this.byStart[index];
19417
19418 if (chunk) {
19419 chunk.prependRight(content);
19420 } else {
19421 this.outro = content + this.outro;
19422 }
19423 return this;
19424 };
19425
19426 MagicString.prototype.remove = function remove (start, end) {
19427 while (start < 0) { start += this.original.length; }
19428 while (end < 0) { end += this.original.length; }
19429
19430 if (start === end) { return this; }
19431
19432 if (start < 0 || end > this.original.length) { throw new Error('Character is out of bounds'); }
19433 if (start > end) { throw new Error('end must be greater than start'); }
19434
19435 this._split(start);
19436 this._split(end);
19437
19438 var chunk = this.byStart[start];
19439
19440 while (chunk) {
19441 chunk.intro = '';
19442 chunk.outro = '';
19443 chunk.edit('');
19444
19445 chunk = end > chunk.end ? this.byStart[chunk.end] : null;
19446 }
19447 return this;
19448 };
19449
19450 MagicString.prototype.lastChar = function lastChar () {
19451 if (this.outro.length)
19452 { return this.outro[this.outro.length - 1]; }
19453 var chunk = this.lastChunk;
19454 do {
19455 if (chunk.outro.length)
19456 { return chunk.outro[chunk.outro.length - 1]; }
19457 if (chunk.content.length)
19458 { return chunk.content[chunk.content.length - 1]; }
19459 if (chunk.intro.length)
19460 { return chunk.intro[chunk.intro.length - 1]; }
19461 } while (chunk = chunk.previous);
19462 if (this.intro.length)
19463 { return this.intro[this.intro.length - 1]; }
19464 return '';
19465 };
19466
19467 MagicString.prototype.lastLine = function lastLine () {
19468 var lineIndex = this.outro.lastIndexOf(n);
19469 if (lineIndex !== -1)
19470 { return this.outro.substr(lineIndex + 1); }
19471 var lineStr = this.outro;
19472 var chunk = this.lastChunk;
19473 do {
19474 if (chunk.outro.length > 0) {
19475 lineIndex = chunk.outro.lastIndexOf(n);
19476 if (lineIndex !== -1)
19477 { return chunk.outro.substr(lineIndex + 1) + lineStr; }
19478 lineStr = chunk.outro + lineStr;
19479 }
19480
19481 if (chunk.content.length > 0) {
19482 lineIndex = chunk.content.lastIndexOf(n);
19483 if (lineIndex !== -1)
19484 { return chunk.content.substr(lineIndex + 1) + lineStr; }
19485 lineStr = chunk.content + lineStr;
19486 }
19487
19488 if (chunk.intro.length > 0) {
19489 lineIndex = chunk.intro.lastIndexOf(n);
19490 if (lineIndex !== -1)
19491 { return chunk.intro.substr(lineIndex + 1) + lineStr; }
19492 lineStr = chunk.intro + lineStr;
19493 }
19494 } while (chunk = chunk.previous);
19495 lineIndex = this.intro.lastIndexOf(n);
19496 if (lineIndex !== -1)
19497 { return this.intro.substr(lineIndex + 1) + lineStr; }
19498 return this.intro + lineStr;
19499 };
19500
19501 MagicString.prototype.slice = function slice (start, end) {
19502 if ( start === void 0 ) start = 0;
19503 if ( end === void 0 ) end = this.original.length;
19504
19505 while (start < 0) { start += this.original.length; }
19506 while (end < 0) { end += this.original.length; }
19507
19508 var result = '';
19509
19510 // find start chunk
19511 var chunk = this.firstChunk;
19512 while (chunk && (chunk.start > start || chunk.end <= start)) {
19513 // found end chunk before start
19514 if (chunk.start < end && chunk.end >= end) {
19515 return result;
19516 }
19517
19518 chunk = chunk.next;
19519 }
19520
19521 if (chunk && chunk.edited && chunk.start !== start)
19522 { throw new Error(("Cannot use replaced character " + start + " as slice start anchor.")); }
19523
19524 var startChunk = chunk;
19525 while (chunk) {
19526 if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
19527 result += chunk.intro;
19528 }
19529
19530 var containsEnd = chunk.start < end && chunk.end >= end;
19531 if (containsEnd && chunk.edited && chunk.end !== end)
19532 { throw new Error(("Cannot use replaced character " + end + " as slice end anchor.")); }
19533
19534 var sliceStart = startChunk === chunk ? start - chunk.start : 0;
19535 var sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
19536
19537 result += chunk.content.slice(sliceStart, sliceEnd);
19538
19539 if (chunk.outro && (!containsEnd || chunk.end === end)) {
19540 result += chunk.outro;
19541 }
19542
19543 if (containsEnd) {
19544 break;
19545 }
19546
19547 chunk = chunk.next;
19548 }
19549
19550 return result;
19551 };
19552
19553 // TODO deprecate this? not really very useful
19554 MagicString.prototype.snip = function snip (start, end) {
19555 var clone = this.clone();
19556 clone.remove(0, start);
19557 clone.remove(end, clone.original.length);
19558
19559 return clone;
19560 };
19561
19562 MagicString.prototype._split = function _split (index) {
19563 if (this.byStart[index] || this.byEnd[index]) { return; }
19564
19565 var chunk = this.lastSearchedChunk;
19566 var searchForward = index > chunk.end;
19567
19568 while (chunk) {
19569 if (chunk.contains(index)) { return this._splitChunk(chunk, index); }
19570
19571 chunk = searchForward ? this.byStart[chunk.end] : this.byEnd[chunk.start];
19572 }
19573 };
19574
19575 MagicString.prototype._splitChunk = function _splitChunk (chunk, index) {
19576 if (chunk.edited && chunk.content.length) {
19577 // zero-length edited chunks are a special case (overlapping replacements)
19578 var loc = getLocator$1(this.original)(index);
19579 throw new Error(
19580 ("Cannot split a chunk that has already been edited (" + (loc.line) + ":" + (loc.column) + " – \"" + (chunk.original) + "\")")
19581 );
19582 }
19583
19584 var newChunk = chunk.split(index);
19585
19586 this.byEnd[index] = chunk;
19587 this.byStart[index] = newChunk;
19588 this.byEnd[newChunk.end] = newChunk;
19589
19590 if (chunk === this.lastChunk) { this.lastChunk = newChunk; }
19591
19592 this.lastSearchedChunk = chunk;
19593 return true;
19594 };
19595
19596 MagicString.prototype.toString = function toString () {
19597 var str = this.intro;
19598
19599 var chunk = this.firstChunk;
19600 while (chunk) {
19601 str += chunk.toString();
19602 chunk = chunk.next;
19603 }
19604
19605 return str + this.outro;
19606 };
19607
19608 MagicString.prototype.isEmpty = function isEmpty () {
19609 var chunk = this.firstChunk;
19610 do {
19611 if (chunk.intro.length && chunk.intro.trim() ||
19612 chunk.content.length && chunk.content.trim() ||
19613 chunk.outro.length && chunk.outro.trim())
19614 { return false; }
19615 } while (chunk = chunk.next);
19616 return true;
19617 };
19618
19619 MagicString.prototype.length = function length () {
19620 var chunk = this.firstChunk;
19621 var length = 0;
19622 do {
19623 length += chunk.intro.length + chunk.content.length + chunk.outro.length;
19624 } while (chunk = chunk.next);
19625 return length;
19626 };
19627
19628 MagicString.prototype.trimLines = function trimLines () {
19629 return this.trim('[\\r\\n]');
19630 };
19631
19632 MagicString.prototype.trim = function trim (charType) {
19633 return this.trimStart(charType).trimEnd(charType);
19634 };
19635
19636 MagicString.prototype.trimEndAborted = function trimEndAborted (charType) {
19637 var rx = new RegExp((charType || '\\s') + '+$');
19638
19639 this.outro = this.outro.replace(rx, '');
19640 if (this.outro.length) { return true; }
19641
19642 var chunk = this.lastChunk;
19643
19644 do {
19645 var end = chunk.end;
19646 var aborted = chunk.trimEnd(rx);
19647
19648 // if chunk was trimmed, we have a new lastChunk
19649 if (chunk.end !== end) {
19650 if (this.lastChunk === chunk) {
19651 this.lastChunk = chunk.next;
19652 }
19653
19654 this.byEnd[chunk.end] = chunk;
19655 this.byStart[chunk.next.start] = chunk.next;
19656 this.byEnd[chunk.next.end] = chunk.next;
19657 }
19658
19659 if (aborted) { return true; }
19660 chunk = chunk.previous;
19661 } while (chunk);
19662
19663 return false;
19664 };
19665
19666 MagicString.prototype.trimEnd = function trimEnd (charType) {
19667 this.trimEndAborted(charType);
19668 return this;
19669 };
19670 MagicString.prototype.trimStartAborted = function trimStartAborted (charType) {
19671 var rx = new RegExp('^' + (charType || '\\s') + '+');
19672
19673 this.intro = this.intro.replace(rx, '');
19674 if (this.intro.length) { return true; }
19675
19676 var chunk = this.firstChunk;
19677
19678 do {
19679 var end = chunk.end;
19680 var aborted = chunk.trimStart(rx);
19681
19682 if (chunk.end !== end) {
19683 // special case...
19684 if (chunk === this.lastChunk) { this.lastChunk = chunk.next; }
19685
19686 this.byEnd[chunk.end] = chunk;
19687 this.byStart[chunk.next.start] = chunk.next;
19688 this.byEnd[chunk.next.end] = chunk.next;
19689 }
19690
19691 if (aborted) { return true; }
19692 chunk = chunk.next;
19693 } while (chunk);
19694
19695 return false;
19696 };
19697
19698 MagicString.prototype.trimStart = function trimStart (charType) {
19699 this.trimStartAborted(charType);
19700 return this;
19701 };
19702
19703 var hasOwnProp = Object.prototype.hasOwnProperty;
19704
19705 var Bundle = function Bundle(options) {
19706 if ( options === void 0 ) options = {};
19707
19708 this.intro = options.intro || '';
19709 this.separator = options.separator !== undefined ? options.separator : '\n';
19710 this.sources = [];
19711 this.uniqueSources = [];
19712 this.uniqueSourceIndexByFilename = {};
19713 };
19714
19715 Bundle.prototype.addSource = function addSource (source) {
19716 if (source instanceof MagicString) {
19717 return this.addSource({
19718 content: source,
19719 filename: source.filename,
19720 separator: this.separator
19721 });
19722 }
19723
19724 if (!isObject(source) || !source.content) {
19725 throw new Error('bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`');
19726 }
19727
19728 ['filename', 'indentExclusionRanges', 'separator'].forEach(function (option) {
19729 if (!hasOwnProp.call(source, option)) { source[option] = source.content[option]; }
19730 });
19731
19732 if (source.separator === undefined) {
19733 // TODO there's a bunch of this sort of thing, needs cleaning up
19734 source.separator = this.separator;
19735 }
19736
19737 if (source.filename) {
19738 if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {
19739 this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;
19740 this.uniqueSources.push({ filename: source.filename, content: source.content.original });
19741 } else {
19742 var uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];
19743 if (source.content.original !== uniqueSource.content) {
19744 throw new Error(("Illegal source: same filename (" + (source.filename) + "), different contents"));
19745 }
19746 }
19747 }
19748
19749 this.sources.push(source);
19750 return this;
19751 };
19752
19753 Bundle.prototype.append = function append (str, options) {
19754 this.addSource({
19755 content: new MagicString(str),
19756 separator: (options && options.separator) || ''
19757 });
19758
19759 return this;
19760 };
19761
19762 Bundle.prototype.clone = function clone () {
19763 var bundle = new Bundle({
19764 intro: this.intro,
19765 separator: this.separator
19766 });
19767
19768 this.sources.forEach(function (source) {
19769 bundle.addSource({
19770 filename: source.filename,
19771 content: source.content.clone(),
19772 separator: source.separator
19773 });
19774 });
19775
19776 return bundle;
19777 };
19778
19779 Bundle.prototype.generateDecodedMap = function generateDecodedMap (options) {
19780 var this$1 = this;
19781 if ( options === void 0 ) options = {};
19782
19783 var names = [];
19784 this.sources.forEach(function (source) {
19785 Object.keys(source.content.storedNames).forEach(function (name) {
19786 if (!~names.indexOf(name)) { names.push(name); }
19787 });
19788 });
19789
19790 var mappings = new Mappings(options.hires);
19791
19792 if (this.intro) {
19793 mappings.advance(this.intro);
19794 }
19795
19796 this.sources.forEach(function (source, i) {
19797 if (i > 0) {
19798 mappings.advance(this$1.separator);
19799 }
19800
19801 var sourceIndex = source.filename ? this$1.uniqueSourceIndexByFilename[source.filename] : -1;
19802 var magicString = source.content;
19803 var locate = getLocator$1(magicString.original);
19804
19805 if (magicString.intro) {
19806 mappings.advance(magicString.intro);
19807 }
19808
19809 magicString.firstChunk.eachNext(function (chunk) {
19810 var loc = locate(chunk.start);
19811
19812 if (chunk.intro.length) { mappings.advance(chunk.intro); }
19813
19814 if (source.filename) {
19815 if (chunk.edited) {
19816 mappings.addEdit(
19817 sourceIndex,
19818 chunk.content,
19819 loc,
19820 chunk.storeName ? names.indexOf(chunk.original) : -1
19821 );
19822 } else {
19823 mappings.addUneditedChunk(
19824 sourceIndex,
19825 chunk,
19826 magicString.original,
19827 loc,
19828 magicString.sourcemapLocations
19829 );
19830 }
19831 } else {
19832 mappings.advance(chunk.content);
19833 }
19834
19835 if (chunk.outro.length) { mappings.advance(chunk.outro); }
19836 });
19837
19838 if (magicString.outro) {
19839 mappings.advance(magicString.outro);
19840 }
19841 });
19842
19843 return {
19844 file: options.file ? options.file.split(/[/\\]/).pop() : null,
19845 sources: this.uniqueSources.map(function (source) {
19846 return options.file ? getRelativePath(options.file, source.filename) : source.filename;
19847 }),
19848 sourcesContent: this.uniqueSources.map(function (source) {
19849 return options.includeContent ? source.content : null;
19850 }),
19851 names: names,
19852 mappings: mappings.raw
19853 };
19854 };
19855
19856 Bundle.prototype.generateMap = function generateMap (options) {
19857 return new SourceMap(this.generateDecodedMap(options));
19858 };
19859
19860 Bundle.prototype.getIndentString = function getIndentString () {
19861 var indentStringCounts = {};
19862
19863 this.sources.forEach(function (source) {
19864 var indentStr = source.content.indentStr;
19865
19866 if (indentStr === null) { return; }
19867
19868 if (!indentStringCounts[indentStr]) { indentStringCounts[indentStr] = 0; }
19869 indentStringCounts[indentStr] += 1;
19870 });
19871
19872 return (
19873 Object.keys(indentStringCounts).sort(function (a, b) {
19874 return indentStringCounts[a] - indentStringCounts[b];
19875 })[0] || '\t'
19876 );
19877 };
19878
19879 Bundle.prototype.indent = function indent (indentStr) {
19880 var this$1 = this;
19881
19882 if (!arguments.length) {
19883 indentStr = this.getIndentString();
19884 }
19885
19886 if (indentStr === '') { return this; } // noop
19887
19888 var trailingNewline = !this.intro || this.intro.slice(-1) === '\n';
19889
19890 this.sources.forEach(function (source, i) {
19891 var separator = source.separator !== undefined ? source.separator : this$1.separator;
19892 var indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator));
19893
19894 source.content.indent(indentStr, {
19895 exclude: source.indentExclusionRanges,
19896 indentStart: indentStart //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator )
19897 });
19898
19899 trailingNewline = source.content.lastChar() === '\n';
19900 });
19901
19902 if (this.intro) {
19903 this.intro =
19904 indentStr +
19905 this.intro.replace(/^[^\n]/gm, function (match, index) {
19906 return index > 0 ? indentStr + match : match;
19907 });
19908 }
19909
19910 return this;
19911 };
19912
19913 Bundle.prototype.prepend = function prepend (str) {
19914 this.intro = str + this.intro;
19915 return this;
19916 };
19917
19918 Bundle.prototype.toString = function toString () {
19919 var this$1 = this;
19920
19921 var body = this.sources
19922 .map(function (source, i) {
19923 var separator = source.separator !== undefined ? source.separator : this$1.separator;
19924 var str = (i > 0 ? separator : '') + source.content.toString();
19925
19926 return str;
19927 })
19928 .join('');
19929
19930 return this.intro + body;
19931 };
19932
19933 Bundle.prototype.isEmpty = function isEmpty () {
19934 if (this.intro.length && this.intro.trim())
19935 { return false; }
19936 if (this.sources.some(function (source) { return !source.content.isEmpty(); }))
19937 { return false; }
19938 return true;
19939 };
19940
19941 Bundle.prototype.length = function length () {
19942 return this.sources.reduce(function (length, source) { return length + source.content.length(); }, this.intro.length);
19943 };
19944
19945 Bundle.prototype.trimLines = function trimLines () {
19946 return this.trim('[\\r\\n]');
19947 };
19948
19949 Bundle.prototype.trim = function trim (charType) {
19950 return this.trimStart(charType).trimEnd(charType);
19951 };
19952
19953 Bundle.prototype.trimStart = function trimStart (charType) {
19954 var rx = new RegExp('^' + (charType || '\\s') + '+');
19955 this.intro = this.intro.replace(rx, '');
19956
19957 if (!this.intro) {
19958 var source;
19959 var i = 0;
19960
19961 do {
19962 source = this.sources[i++];
19963 if (!source) {
19964 break;
19965 }
19966 } while (!source.content.trimStartAborted(charType));
19967 }
19968
19969 return this;
19970 };
19971
19972 Bundle.prototype.trimEnd = function trimEnd (charType) {
19973 var rx = new RegExp((charType || '\\s') + '+$');
19974
19975 var source;
19976 var i = this.sources.length - 1;
19977
19978 do {
19979 source = this.sources[i--];
19980 if (!source) {
19981 this.intro = this.intro.replace(rx, '');
19982 break;
19983 }
19984 } while (!source.content.trimEndAborted(charType));
19985
19986 return this;
19987 };
19988
19989 const wrappers$1 = { esm, cjs };
19990 function create_module(code, format, name, banner, sveltePath = 'svelte', helpers, globals, imports, module_exports, source) {
19991 const internal_path = `${sveltePath}/internal`;
19992 if (format === 'esm') {
19993 return esm(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports, source);
19994 }
19995 if (format === 'cjs')
19996 return cjs(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports);
19997 throw new Error(`options.format is invalid (must be ${list$1(Object.keys(wrappers$1))})`);
19998 }
19999 function edit_source(source, sveltePath) {
20000 return source === 'svelte' || source.startsWith('svelte/')
20001 ? source.replace('svelte', sveltePath)
20002 : source;
20003 }
20004 function esm(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports, source) {
20005 const internal_imports = helpers.length > 0 && (`import ${stringify_props(helpers.map(h => h.name === h.alias ? h.name : `${h.name} as ${h.alias}`).sort())} from ${JSON.stringify(internal_path)};`);
20006 const internal_globals = globals.length > 0 && (`const ${stringify_props(globals.map(g => `${g.name}: ${g.alias}`).sort())} = ${helpers.find(({ name }) => name === 'globals').alias};`);
20007 const user_imports = imports.length > 0 && (imports
20008 .map((declaration) => {
20009 const import_source = edit_source(declaration.source.value, sveltePath);
20010 return (source.slice(declaration.start, declaration.source.start) +
20011 JSON.stringify(import_source) +
20012 source.slice(declaration.source.end, declaration.end));
20013 })
20014 .join('\n'));
20015 return deindent `
20016 ${banner}
20017 ${internal_imports}
20018 ${internal_globals}
20019 ${user_imports}
20020
20021 ${code}
20022
20023 export default ${name};
20024 ${module_exports.length > 0 && `export { ${module_exports.map(e => e.name === e.as ? e.name : `${e.name} as ${e.as}`).join(', ')} };`}`;
20025 }
20026 function cjs(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports) {
20027 const declarations = helpers.map(h => `${h.alias === h.name ? h.name : `${h.name}: ${h.alias}`}`).sort();
20028 const internal_imports = helpers.length > 0 && (`const ${stringify_props(declarations)} = require(${JSON.stringify(internal_path)});\n`);
20029 const internal_globals = globals.length > 0 && (`const ${stringify_props(globals.map(g => `${g.name}: ${g.alias}`).sort())} = ${helpers.find(({ name }) => name === 'globals').alias};`);
20030 const requires = imports.map(node => {
20031 let lhs;
20032 if (node.specifiers[0].type === 'ImportNamespaceSpecifier') {
20033 lhs = node.specifiers[0].local.name;
20034 }
20035 else {
20036 const properties = node.specifiers.map(s => {
20037 if (s.type === 'ImportDefaultSpecifier') {
20038 return `default: ${s.local.name}`;
20039 }
20040 return s.local.name === s.imported.name
20041 ? s.local.name
20042 : `${s.imported.name}: ${s.local.name}`;
20043 });
20044 lhs = `{ ${properties.join(', ')} }`;
20045 }
20046 const source = edit_source(node.source.value, sveltePath);
20047 return `const ${lhs} = require("${source}");`;
20048 });
20049 const exports = [`exports.default = ${name};`].concat(module_exports.map(x => `exports.${x.as} = ${x.name};`));
20050 return deindent `
20051 ${banner}
20052 "use strict";
20053
20054 ${internal_imports}
20055 ${internal_globals}
20056 ${requires}
20057
20058 ${code}
20059
20060 ${exports}`;
20061 }
20062
20063 const UNKNOWN = {};
20064 function gather_possible_values(node, set) {
20065 if (node.type === 'Literal') {
20066 set.add(node.value);
20067 }
20068 else if (node.type === 'ConditionalExpression') {
20069 gather_possible_values(node.consequent, set);
20070 gather_possible_values(node.alternate, set);
20071 }
20072 else {
20073 set.add(UNKNOWN);
20074 }
20075 }
20076
20077 class Selector$1 {
20078 constructor(node, stylesheet) {
20079 this.node = node;
20080 this.stylesheet = stylesheet;
20081 this.blocks = group_selectors(node);
20082 // take trailing :global(...) selectors out of consideration
20083 let i = this.blocks.length;
20084 while (i > 0) {
20085 if (!this.blocks[i - 1].global)
20086 break;
20087 i -= 1;
20088 }
20089 this.local_blocks = this.blocks.slice(0, i);
20090 this.used = this.blocks[0].global;
20091 }
20092 apply(node, stack) {
20093 const to_encapsulate = [];
20094 apply_selector(this.stylesheet, this.local_blocks.slice(), node, stack.slice(), to_encapsulate);
20095 if (to_encapsulate.length > 0) {
20096 to_encapsulate.filter((_, i) => i === 0 || i === to_encapsulate.length - 1).forEach(({ node, block }) => {
20097 this.stylesheet.nodes_with_css_class.add(node);
20098 block.should_encapsulate = true;
20099 });
20100 this.used = true;
20101 }
20102 }
20103 minify(code) {
20104 let c = null;
20105 this.blocks.forEach((block, i) => {
20106 if (i > 0) {
20107 if (block.start - c > 1) {
20108 code.overwrite(c, block.start, block.combinator.name || ' ');
20109 }
20110 }
20111 c = block.end;
20112 });
20113 }
20114 transform(code, attr) {
20115 function encapsulate_block(block) {
20116 let i = block.selectors.length;
20117 while (i--) {
20118 const selector = block.selectors[i];
20119 if (selector.type === 'PseudoElementSelector' || selector.type === 'PseudoClassSelector') {
20120 if (i === 0)
20121 code.prependRight(selector.start, attr);
20122 continue;
20123 }
20124 if (selector.type === 'TypeSelector' && selector.name === '*') {
20125 code.overwrite(selector.start, selector.end, attr);
20126 }
20127 else {
20128 code.appendLeft(selector.end, attr);
20129 }
20130 break;
20131 }
20132 }
20133 this.blocks.forEach((block) => {
20134 if (block.global) {
20135 const selector = block.selectors[0];
20136 const first = selector.children[0];
20137 const last = selector.children[selector.children.length - 1];
20138 code.remove(selector.start, first.start).remove(last.end, selector.end);
20139 }
20140 if (block.should_encapsulate)
20141 encapsulate_block(block);
20142 });
20143 }
20144 validate(component) {
20145 this.blocks.forEach((block) => {
20146 let i = block.selectors.length;
20147 while (i-- > 1) {
20148 const selector = block.selectors[i];
20149 if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
20150 component.error(selector, {
20151 code: `css-invalid-global`,
20152 message: `:global(...) must be the first element in a compound selector`
20153 });
20154 }
20155 }
20156 });
20157 let start = 0;
20158 let end = this.blocks.length;
20159 for (; start < end; start += 1) {
20160 if (!this.blocks[start].global)
20161 break;
20162 }
20163 for (; end > start; end -= 1) {
20164 if (!this.blocks[end - 1].global)
20165 break;
20166 }
20167 for (let i = start; i < end; i += 1) {
20168 if (this.blocks[i].global) {
20169 component.error(this.blocks[i].selectors[0], {
20170 code: `css-invalid-global`,
20171 message: `:global(...) can be at the start or end of a selector sequence, but not in the middle`
20172 });
20173 }
20174 }
20175 }
20176 }
20177 function apply_selector(stylesheet, blocks, node, stack, to_encapsulate) {
20178 const block = blocks.pop();
20179 if (!block)
20180 return false;
20181 if (!node) {
20182 return blocks.every(block => block.global);
20183 }
20184 let i = block.selectors.length;
20185 while (i--) {
20186 const selector = block.selectors[i];
20187 if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
20188 // TODO shouldn't see this here... maybe we should enforce that :global(...)
20189 // cannot be sandwiched between non-global selectors?
20190 return false;
20191 }
20192 if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
20193 continue;
20194 }
20195 if (selector.type === 'ClassSelector') {
20196 if (!attribute_matches(node, 'class', selector.name, '~=', false) && !class_matches(node, selector.name))
20197 return false;
20198 }
20199 else if (selector.type === 'IdSelector') {
20200 if (!attribute_matches(node, 'id', selector.name, '=', false))
20201 return false;
20202 }
20203 else if (selector.type === 'AttributeSelector') {
20204 if (!attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags))
20205 return false;
20206 }
20207 else if (selector.type === 'TypeSelector') {
20208 // remove toLowerCase() in v2, when uppercase elements will be forbidden
20209 if (node.name.toLowerCase() !== selector.name.toLowerCase() && selector.name !== '*')
20210 return false;
20211 }
20212 else {
20213 // bail. TODO figure out what these could be
20214 to_encapsulate.push({ node, block });
20215 return true;
20216 }
20217 }
20218 if (block.combinator) {
20219 if (block.combinator.type === 'WhiteSpace') {
20220 while (stack.length) {
20221 if (apply_selector(stylesheet, blocks.slice(), stack.pop(), stack, to_encapsulate)) {
20222 to_encapsulate.push({ node, block });
20223 return true;
20224 }
20225 }
20226 if (blocks.every(block => block.global)) {
20227 to_encapsulate.push({ node, block });
20228 return true;
20229 }
20230 return false;
20231 }
20232 else if (block.combinator.name === '>') {
20233 if (apply_selector(stylesheet, blocks, stack.pop(), stack, to_encapsulate)) {
20234 to_encapsulate.push({ node, block });
20235 return true;
20236 }
20237 return false;
20238 }
20239 // TODO other combinators
20240 to_encapsulate.push({ node, block });
20241 return true;
20242 }
20243 to_encapsulate.push({ node, block });
20244 return true;
20245 }
20246 const operators = {
20247 '=': (value, flags) => new RegExp(`^${value}$`, flags),
20248 '~=': (value, flags) => new RegExp(`\\b${value}\\b`, flags),
20249 '|=': (value, flags) => new RegExp(`^${value}(-.+)?$`, flags),
20250 '^=': (value, flags) => new RegExp(`^${value}`, flags),
20251 '$=': (value, flags) => new RegExp(`${value}$`, flags),
20252 '*=': (value, flags) => new RegExp(value, flags)
20253 };
20254 function attribute_matches(node, name, expected_value, operator, case_insensitive) {
20255 const spread = node.attributes.find(attr => attr.type === 'Spread');
20256 if (spread)
20257 return true;
20258 const attr = node.attributes.find((attr) => attr.name === name);
20259 if (!attr)
20260 return false;
20261 if (attr.is_true)
20262 return operator === null;
20263 if (attr.chunks.length > 1)
20264 return true;
20265 if (!expected_value)
20266 return true;
20267 const pattern = operators[operator](expected_value, case_insensitive ? 'i' : '');
20268 const value = attr.chunks[0];
20269 if (!value)
20270 return false;
20271 if (value.type === 'Text')
20272 return pattern.test(value.data);
20273 const possible_values = new Set();
20274 gather_possible_values(value.node, possible_values);
20275 if (possible_values.has(UNKNOWN))
20276 return true;
20277 for (const x of Array.from(possible_values)) { // TypeScript for-of is slightly unlike JS
20278 if (pattern.test(x))
20279 return true;
20280 }
20281 return false;
20282 }
20283 function class_matches(node, name) {
20284 return node.classes.some((class_directive) => {
20285 return new RegExp(`\\b${name}\\b`).test(class_directive.name);
20286 });
20287 }
20288 function unquote(value) {
20289 if (value.type === 'Identifier')
20290 return value.name;
20291 const str = value.value;
20292 if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
20293 return str.slice(1, str.length - 1);
20294 }
20295 return str;
20296 }
20297 class Block$2 {
20298 constructor(combinator) {
20299 this.combinator = combinator;
20300 this.global = false;
20301 this.selectors = [];
20302 this.start = null;
20303 this.end = null;
20304 this.should_encapsulate = false;
20305 }
20306 add(selector) {
20307 if (this.selectors.length === 0) {
20308 this.start = selector.start;
20309 this.global = selector.type === 'PseudoClassSelector' && selector.name === 'global';
20310 }
20311 this.selectors.push(selector);
20312 this.end = selector.end;
20313 }
20314 }
20315 function group_selectors(selector) {
20316 let block = new Block$2(null);
20317 const blocks = [block];
20318 selector.children.forEach((child) => {
20319 if (child.type === 'WhiteSpace' || child.type === 'Combinator') {
20320 block = new Block$2(child);
20321 blocks.push(block);
20322 }
20323 else {
20324 block.add(child);
20325 }
20326 });
20327 return blocks;
20328 }
20329
20330 function remove_css_prefix(name) {
20331 return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, '');
20332 }
20333 const is_keyframes_node = (node) => remove_css_prefix(node.name) === 'keyframes';
20334 // https://github.com/darkskyapp/string-hash/blob/master/index.js
20335 function hash(str) {
20336 let hash = 5381;
20337 let i = str.length;
20338 while (i--)
20339 hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
20340 return (hash >>> 0).toString(36);
20341 }
20342 class Rule$1 {
20343 constructor(node, stylesheet, parent) {
20344 this.node = node;
20345 this.parent = parent;
20346 this.selectors = node.selector.children.map((node) => new Selector$1(node, stylesheet));
20347 this.declarations = node.block.children.map((node) => new Declaration$1(node));
20348 }
20349 apply(node, stack) {
20350 this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here?
20351 }
20352 is_used(dev) {
20353 if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node))
20354 return true;
20355 if (this.declarations.length === 0)
20356 return dev;
20357 return this.selectors.some(s => s.used);
20358 }
20359 minify(code, _dev) {
20360 let c = this.node.start;
20361 let started = false;
20362 this.selectors.forEach((selector) => {
20363 if (selector.used) {
20364 const separator = started ? ',' : '';
20365 if ((selector.node.start - c) > separator.length) {
20366 code.overwrite(c, selector.node.start, separator);
20367 }
20368 selector.minify(code);
20369 c = selector.node.end;
20370 started = true;
20371 }
20372 });
20373 code.remove(c, this.node.block.start);
20374 c = this.node.block.start + 1;
20375 this.declarations.forEach((declaration, i) => {
20376 const separator = i > 0 ? ';' : '';
20377 if ((declaration.node.start - c) > separator.length) {
20378 code.overwrite(c, declaration.node.start, separator);
20379 }
20380 declaration.minify(code);
20381 c = declaration.node.end;
20382 });
20383 code.remove(c, this.node.block.end - 1);
20384 }
20385 transform(code, id, keyframes) {
20386 if (this.parent && this.parent.node.type === 'Atrule' && is_keyframes_node(this.parent.node))
20387 return true;
20388 const attr = `.${id}`;
20389 this.selectors.forEach(selector => selector.transform(code, attr));
20390 this.declarations.forEach(declaration => declaration.transform(code, keyframes));
20391 }
20392 validate(component) {
20393 this.selectors.forEach(selector => {
20394 selector.validate(component);
20395 });
20396 }
20397 warn_on_unused_selector(handler) {
20398 this.selectors.forEach(selector => {
20399 if (!selector.used)
20400 handler(selector);
20401 });
20402 }
20403 }
20404 class Declaration$1 {
20405 constructor(node) {
20406 this.node = node;
20407 }
20408 transform(code, keyframes) {
20409 const property = this.node.property && remove_css_prefix(this.node.property.toLowerCase());
20410 if (property === 'animation' || property === 'animation-name') {
20411 this.node.value.children.forEach((block) => {
20412 if (block.type === 'Identifier') {
20413 const name = block.name;
20414 if (keyframes.has(name)) {
20415 code.overwrite(block.start, block.end, keyframes.get(name));
20416 }
20417 }
20418 });
20419 }
20420 }
20421 minify(code) {
20422 if (!this.node.property)
20423 return; // @apply, and possibly other weird cases?
20424 const c = this.node.start + this.node.property.length;
20425 const first = this.node.value.children
20426 ? this.node.value.children[0]
20427 : this.node.value;
20428 let start = first.start;
20429 while (/\s/.test(code.original[start]))
20430 start += 1;
20431 if (start - c > 1) {
20432 code.overwrite(c, start, ':');
20433 }
20434 }
20435 }
20436 class Atrule$1 {
20437 constructor(node) {
20438 this.node = node;
20439 this.children = [];
20440 }
20441 apply(node, stack) {
20442 if (this.node.name === 'media' || this.node.name === 'supports') {
20443 this.children.forEach(child => {
20444 child.apply(node, stack);
20445 });
20446 }
20447 else if (is_keyframes_node(this.node)) {
20448 this.children.forEach((rule) => {
20449 rule.selectors.forEach(selector => {
20450 selector.used = true;
20451 });
20452 });
20453 }
20454 }
20455 is_used(_dev) {
20456 return true; // TODO
20457 }
20458 minify(code, dev) {
20459 if (this.node.name === 'media') {
20460 const expression_char = code.original[this.node.expression.start];
20461 let c = this.node.start + (expression_char === '(' ? 6 : 7);
20462 if (this.node.expression.start > c)
20463 code.remove(c, this.node.expression.start);
20464 this.node.expression.children.forEach((query) => {
20465 // TODO minify queries
20466 c = query.end;
20467 });
20468 code.remove(c, this.node.block.start);
20469 }
20470 else if (is_keyframes_node(this.node)) {
20471 let c = this.node.start + this.node.name.length + 1;
20472 if (this.node.expression.start - c > 1)
20473 code.overwrite(c, this.node.expression.start, ' ');
20474 c = this.node.expression.end;
20475 if (this.node.block.start - c > 0)
20476 code.remove(c, this.node.block.start);
20477 }
20478 else if (this.node.name === 'supports') {
20479 let c = this.node.start + 9;
20480 if (this.node.expression.start - c > 1)
20481 code.overwrite(c, this.node.expression.start, ' ');
20482 this.node.expression.children.forEach((query) => {
20483 // TODO minify queries
20484 c = query.end;
20485 });
20486 code.remove(c, this.node.block.start);
20487 }
20488 // TODO other atrules
20489 if (this.node.block) {
20490 let c = this.node.block.start + 1;
20491 this.children.forEach(child => {
20492 if (child.is_used(dev)) {
20493 code.remove(c, child.node.start);
20494 child.minify(code, dev);
20495 c = child.node.end;
20496 }
20497 });
20498 code.remove(c, this.node.block.end - 1);
20499 }
20500 }
20501 transform(code, id, keyframes) {
20502 if (is_keyframes_node(this.node)) {
20503 this.node.expression.children.forEach(({ type, name, start, end }) => {
20504 if (type === 'Identifier') {
20505 if (name.startsWith('-global-')) {
20506 code.remove(start, start + 8);
20507 }
20508 else {
20509 code.overwrite(start, end, keyframes.get(name));
20510 }
20511 }
20512 });
20513 }
20514 this.children.forEach(child => {
20515 child.transform(code, id, keyframes);
20516 });
20517 }
20518 validate(component) {
20519 this.children.forEach(child => {
20520 child.validate(component);
20521 });
20522 }
20523 warn_on_unused_selector(handler) {
20524 if (this.node.name !== 'media')
20525 return;
20526 this.children.forEach(child => {
20527 child.warn_on_unused_selector(handler);
20528 });
20529 }
20530 }
20531 class Stylesheet {
20532 constructor(source, ast, filename, dev) {
20533 this.children = [];
20534 this.keyframes = new Map();
20535 this.nodes_with_css_class = new Set();
20536 this.source = source;
20537 this.ast = ast;
20538 this.filename = filename;
20539 this.dev = dev;
20540 if (ast.css && ast.css.children.length) {
20541 this.id = `svelte-${hash(ast.css.content.styles)}`;
20542 this.has_styles = true;
20543 const stack = [];
20544 let depth = 0;
20545 let current_atrule = null;
20546 walk(ast.css, {
20547 enter: (node) => {
20548 if (node.type === 'Atrule') {
20549 const atrule = new Atrule$1(node);
20550 stack.push(atrule);
20551 if (current_atrule) {
20552 current_atrule.children.push(atrule);
20553 }
20554 else if (depth <= 1) {
20555 this.children.push(atrule);
20556 }
20557 if (is_keyframes_node(node)) {
20558 node.expression.children.forEach((expression) => {
20559 if (expression.type === 'Identifier' && !expression.name.startsWith('-global-')) {
20560 this.keyframes.set(expression.name, `${this.id}-${expression.name}`);
20561 }
20562 });
20563 }
20564 current_atrule = atrule;
20565 }
20566 if (node.type === 'Rule') {
20567 const rule = new Rule$1(node, this, current_atrule);
20568 if (current_atrule) {
20569 current_atrule.children.push(rule);
20570 }
20571 else if (depth <= 1) {
20572 this.children.push(rule);
20573 }
20574 }
20575 depth += 1;
20576 },
20577 leave: (node) => {
20578 if (node.type === 'Atrule') {
20579 stack.pop();
20580 current_atrule = stack[stack.length - 1];
20581 }
20582 depth -= 1;
20583 }
20584 });
20585 }
20586 else {
20587 this.has_styles = false;
20588 }
20589 }
20590 apply(node) {
20591 if (!this.has_styles)
20592 return;
20593 const stack = [];
20594 let parent = node;
20595 while (parent = parent.parent) {
20596 if (parent.type === 'Element')
20597 stack.unshift(parent);
20598 }
20599 for (let i = 0; i < this.children.length; i += 1) {
20600 const child = this.children[i];
20601 child.apply(node, stack);
20602 }
20603 }
20604 reify() {
20605 this.nodes_with_css_class.forEach((node) => {
20606 node.add_css_class();
20607 });
20608 }
20609 render(file, should_transform_selectors) {
20610 if (!this.has_styles) {
20611 return { code: null, map: null };
20612 }
20613 const code = new MagicString(this.source);
20614 walk(this.ast.css, {
20615 enter: (node) => {
20616 code.addSourcemapLocation(node.start);
20617 code.addSourcemapLocation(node.end);
20618 }
20619 });
20620 if (should_transform_selectors) {
20621 this.children.forEach((child) => {
20622 child.transform(code, this.id, this.keyframes);
20623 });
20624 }
20625 let c = 0;
20626 this.children.forEach(child => {
20627 if (child.is_used(this.dev)) {
20628 code.remove(c, child.node.start);
20629 child.minify(code, this.dev);
20630 c = child.node.end;
20631 }
20632 });
20633 code.remove(c, this.source.length);
20634 return {
20635 code: code.toString(),
20636 map: code.generateMap({
20637 includeContent: true,
20638 source: this.filename,
20639 file
20640 })
20641 };
20642 }
20643 validate(component) {
20644 this.children.forEach(child => {
20645 child.validate(component);
20646 });
20647 }
20648 warn_on_unused_selectors(component) {
20649 this.children.forEach(child => {
20650 child.warn_on_unused_selector((selector) => {
20651 component.warn(selector.node, {
20652 code: `css-unused-selector`,
20653 message: `Unused CSS selector`
20654 });
20655 });
20656 });
20657 }
20658 }
20659
20660 const test = typeof process !== 'undefined' && process.env.TEST;
20661
20662 class Node$1 {
20663 constructor(component, parent, _scope, info) {
20664 this.start = info.start;
20665 this.end = info.end;
20666 this.type = info.type;
20667 // this makes properties non-enumerable, which makes logging
20668 // bearable. might have a performance cost. TODO remove in prod?
20669 Object.defineProperties(this, {
20670 component: {
20671 value: component
20672 },
20673 parent: {
20674 value: parent
20675 }
20676 });
20677 }
20678 cannot_use_innerhtml() {
20679 if (this.can_use_innerhtml !== false) {
20680 this.can_use_innerhtml = false;
20681 if (this.parent)
20682 this.parent.cannot_use_innerhtml();
20683 }
20684 }
20685 find_nearest(selector) {
20686 if (selector.test(this.type))
20687 return this;
20688 if (this.parent)
20689 return this.parent.find_nearest(selector);
20690 }
20691 get_static_attribute_value(name) {
20692 const attribute = this.attributes && this.attributes.find((attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name);
20693 if (!attribute)
20694 return null;
20695 if (attribute.is_true)
20696 return true;
20697 if (attribute.chunks.length === 0)
20698 return '';
20699 if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') {
20700 return attribute.chunks[0].data;
20701 }
20702 return null;
20703 }
20704 has_ancestor(type) {
20705 return this.parent ?
20706 this.parent.type === type || this.parent.has_ancestor(type) :
20707 false;
20708 }
20709 }
20710
20711 class AbstractBlock extends Node$1 {
20712 constructor(component, parent, scope, info) {
20713 super(component, parent, scope, info);
20714 }
20715 warn_if_empty_block() {
20716 if (!this.children || this.children.length > 1)
20717 return;
20718 const child = this.children[0];
20719 if (!child || (child.type === 'Text' && !/[^ \r\n\f\v\t]/.test(child.data))) {
20720 this.component.warn(this, {
20721 code: 'empty-block',
20722 message: 'Empty block'
20723 });
20724 }
20725 }
20726 }
20727
20728 class PendingBlock extends AbstractBlock {
20729 constructor(component, parent, scope, info) {
20730 super(component, parent, scope, info);
20731 this.children = map_children(component, parent, scope, info.children);
20732 if (!info.skip) {
20733 this.warn_if_empty_block();
20734 }
20735 }
20736 }
20737
20738 class ThenBlock extends AbstractBlock {
20739 constructor(component, parent, scope, info) {
20740 super(component, parent, scope, info);
20741 this.scope = scope.child();
20742 this.scope.add(parent.value, parent.expression.dependencies, this);
20743 this.children = map_children(component, parent, this.scope, info.children);
20744 if (!info.skip) {
20745 this.warn_if_empty_block();
20746 }
20747 }
20748 }
20749
20750 class CatchBlock extends AbstractBlock {
20751 constructor(component, parent, scope, info) {
20752 super(component, parent, scope, info);
20753 this.scope = scope.child();
20754 this.scope.add(parent.error, parent.expression.dependencies, this);
20755 this.children = map_children(component, parent, this.scope, info.children);
20756 if (!info.skip) {
20757 this.warn_if_empty_block();
20758 }
20759 }
20760 }
20761
20762 const binary_operators = {
20763 '**': 15,
20764 '*': 14,
20765 '/': 14,
20766 '%': 14,
20767 '+': 13,
20768 '-': 13,
20769 '<<': 12,
20770 '>>': 12,
20771 '>>>': 12,
20772 '<': 11,
20773 '<=': 11,
20774 '>': 11,
20775 '>=': 11,
20776 in: 11,
20777 instanceof: 11,
20778 '==': 10,
20779 '!=': 10,
20780 '===': 10,
20781 '!==': 10,
20782 '&': 9,
20783 '^': 8,
20784 '|': 7
20785 };
20786 const logical_operators = {
20787 '&&': 6,
20788 '||': 5
20789 };
20790 const precedence = {
20791 Literal: () => 21,
20792 Identifier: () => 21,
20793 ParenthesizedExpression: () => 20,
20794 MemberExpression: () => 19,
20795 NewExpression: () => 19,
20796 CallExpression: () => 19,
20797 UpdateExpression: () => 17,
20798 UnaryExpression: () => 16,
20799 BinaryExpression: (node) => binary_operators[node.operator],
20800 LogicalExpression: (node) => logical_operators[node.operator],
20801 ConditionalExpression: () => 4,
20802 AssignmentExpression: () => 3,
20803 YieldExpression: () => 2,
20804 SpreadElement: () => 1,
20805 SequenceExpression: () => 0
20806 };
20807 class Expression {
20808 // todo: owner type
20809 constructor(component, owner, template_scope, info, lazy) {
20810 this.type = 'Expression';
20811 this.dependencies = new Set();
20812 this.contextual_dependencies = new Set();
20813 this.declarations = [];
20814 this.uses_context = false;
20815 // TODO revert to direct property access in prod?
20816 Object.defineProperties(this, {
20817 component: {
20818 value: component
20819 }
20820 });
20821 this.node = info;
20822 this.template_scope = template_scope;
20823 this.owner = owner;
20824 // @ts-ignore
20825 this.is_synthetic = owner.is_synthetic;
20826 const { dependencies, contextual_dependencies } = this;
20827 let { map, scope } = create_scopes(info);
20828 this.scope = scope;
20829 this.scope_map = map;
20830 const expression = this;
20831 let function_expression;
20832 // discover dependencies, but don't change the code yet
20833 walk(info, {
20834 enter(node, parent, key) {
20835 // don't manipulate shorthand props twice
20836 if (key === 'value' && parent.shorthand)
20837 return;
20838 if (map.has(node)) {
20839 scope = map.get(node);
20840 }
20841 if (!function_expression && /FunctionExpression/.test(node.type)) {
20842 function_expression = node;
20843 }
20844 if (isReference(node, parent)) {
20845 const { name, nodes } = flatten_reference(node);
20846 if (scope.has(name))
20847 return;
20848 if (globals.has(name) && !component.var_lookup.has(name))
20849 return;
20850 if (name[0] === '$' && template_scope.names.has(name.slice(1))) {
20851 component.error(node, {
20852 code: `contextual-store`,
20853 message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`
20854 });
20855 }
20856 if (template_scope.is_let(name)) {
20857 if (!function_expression) { // TODO should this be `!lazy` ?
20858 contextual_dependencies.add(name);
20859 dependencies.add(name);
20860 }
20861 }
20862 else if (template_scope.names.has(name)) {
20863 expression.uses_context = true;
20864 contextual_dependencies.add(name);
20865 if (!lazy) {
20866 template_scope.dependencies_for_name.get(name).forEach(name => dependencies.add(name));
20867 }
20868 }
20869 else {
20870 if (!lazy) {
20871 dependencies.add(name);
20872 }
20873 component.add_reference(name);
20874 component.warn_if_undefined(name, nodes[0], template_scope);
20875 }
20876 this.skip();
20877 }
20878 // track any assignments from template expressions as mutable
20879 let names;
20880 let deep = false;
20881 if (function_expression) {
20882 if (node.type === 'AssignmentExpression') {
20883 deep = node.left.type === 'MemberExpression';
20884 names = deep
20885 ? [get_object(node.left).name]
20886 : extract_names(node.left);
20887 }
20888 else if (node.type === 'UpdateExpression') {
20889 const { name } = get_object(node.argument);
20890 names = [name];
20891 }
20892 }
20893 if (names) {
20894 names.forEach(name => {
20895 if (template_scope.names.has(name)) {
20896 template_scope.dependencies_for_name.get(name).forEach(name => {
20897 const variable = component.var_lookup.get(name);
20898 if (variable)
20899 variable[deep ? 'mutated' : 'reassigned'] = true;
20900 });
20901 }
20902 else {
20903 component.add_reference(name);
20904 const variable = component.var_lookup.get(name);
20905 if (variable)
20906 variable[deep ? 'mutated' : 'reassigned'] = true;
20907 }
20908 });
20909 }
20910 },
20911 leave(node) {
20912 if (map.has(node)) {
20913 scope = scope.parent;
20914 }
20915 if (node === function_expression) {
20916 function_expression = null;
20917 }
20918 }
20919 });
20920 }
20921 dynamic_dependencies() {
20922 return Array.from(this.dependencies).filter(name => {
20923 if (this.template_scope.is_let(name))
20924 return true;
20925 if (name === '$$props')
20926 return true;
20927 const variable = this.component.var_lookup.get(name);
20928 return is_dynamic$1(variable);
20929 });
20930 }
20931 get_precedence() {
20932 return this.node.type in precedence ? precedence[this.node.type](this.node) : 0;
20933 }
20934 // TODO move this into a render-dom wrapper?
20935 render(block) {
20936 if (this.rendered)
20937 return this.rendered;
20938 const { component, declarations, scope_map: map, template_scope, owner, is_synthetic } = this;
20939 let scope = this.scope;
20940 const { code } = component;
20941 let function_expression;
20942 let pending_assignments = new Set();
20943 let dependencies;
20944 let contextual_dependencies;
20945 // rewrite code as appropriate
20946 walk(this.node, {
20947 enter(node, parent, key) {
20948 // don't manipulate shorthand props twice
20949 if (key === 'value' && parent.shorthand)
20950 return;
20951 code.addSourcemapLocation(node.start);
20952 code.addSourcemapLocation(node.end);
20953 if (map.has(node)) {
20954 scope = map.get(node);
20955 }
20956 if (isReference(node, parent)) {
20957 const { name, nodes } = flatten_reference(node);
20958 if (scope.has(name))
20959 return;
20960 if (globals.has(name) && !component.var_lookup.has(name))
20961 return;
20962 if (function_expression) {
20963 if (template_scope.names.has(name)) {
20964 contextual_dependencies.add(name);
20965 template_scope.dependencies_for_name.get(name).forEach(dependency => {
20966 dependencies.add(dependency);
20967 });
20968 }
20969 else {
20970 dependencies.add(name);
20971 component.add_reference(name); // TODO is this redundant/misplaced?
20972 }
20973 }
20974 else if (!is_synthetic && is_contextual(component, template_scope, name)) {
20975 code.prependRight(node.start, key === 'key' && parent.shorthand
20976 ? `${name}: ctx.`
20977 : 'ctx.');
20978 }
20979 if (node.type === 'MemberExpression') {
20980 nodes.forEach(node => {
20981 code.addSourcemapLocation(node.start);
20982 code.addSourcemapLocation(node.end);
20983 });
20984 }
20985 this.skip();
20986 }
20987 if (!function_expression) {
20988 if (node.type === 'AssignmentExpression') ;
20989 if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
20990 function_expression = node;
20991 dependencies = new Set();
20992 contextual_dependencies = new Set();
20993 }
20994 }
20995 },
20996 leave(node, parent) {
20997 if (map.has(node))
20998 scope = scope.parent;
20999 if (node === function_expression) {
21000 if (pending_assignments.size > 0) {
21001 if (node.type !== 'ArrowFunctionExpression') {
21002 // this should never happen!
21003 throw new Error(`Well that's odd`);
21004 }
21005 // TOOD optimisation — if this is an event handler,
21006 // the return value doesn't matter
21007 }
21008 const name = component.get_unique_name(sanitize(get_function_name(node, owner)));
21009 const args = contextual_dependencies.size > 0
21010 ? [`{ ${Array.from(contextual_dependencies).join(', ')} }`]
21011 : [];
21012 let original_params;
21013 if (node.params.length > 0) {
21014 original_params = code.slice(node.params[0].start, node.params[node.params.length - 1].end);
21015 args.push(original_params);
21016 }
21017 let body = code.slice(node.body.start, node.body.end).trim();
21018 if (node.body.type !== 'BlockStatement') {
21019 if (pending_assignments.size > 0) {
21020 const dependencies = new Set();
21021 pending_assignments.forEach(name => {
21022 if (template_scope.names.has(name)) {
21023 template_scope.dependencies_for_name.get(name).forEach(dependency => {
21024 dependencies.add(dependency);
21025 });
21026 }
21027 else {
21028 dependencies.add(name);
21029 }
21030 });
21031 const insert = Array.from(dependencies).map(name => component.invalidate(name)).join('; ');
21032 pending_assignments = new Set();
21033 component.has_reactive_assignments = true;
21034 body = deindent `
21035 {
21036 const $$result = ${body};
21037 ${insert};
21038 return $$result;
21039 }
21040 `;
21041 }
21042 else {
21043 body = `{\n\treturn ${body};\n}`;
21044 }
21045 }
21046 const fn = deindent `
21047 function ${name}(${args.join(', ')}) ${body}
21048 `;
21049 if (dependencies.size === 0 && contextual_dependencies.size === 0) {
21050 // we can hoist this out of the component completely
21051 component.fully_hoisted.push(fn);
21052 code.overwrite(node.start, node.end, name);
21053 component.add_var({
21054 name,
21055 internal: true,
21056 hoistable: true,
21057 referenced: true
21058 });
21059 }
21060 else if (contextual_dependencies.size === 0) {
21061 // function can be hoisted inside the component init
21062 component.partly_hoisted.push(fn);
21063 code.overwrite(node.start, node.end, `ctx.${name}`);
21064 component.add_var({
21065 name,
21066 internal: true,
21067 referenced: true
21068 });
21069 }
21070 else {
21071 // we need a combo block/init recipe
21072 component.partly_hoisted.push(fn);
21073 code.overwrite(node.start, node.end, name);
21074 component.add_var({
21075 name,
21076 internal: true,
21077 referenced: true
21078 });
21079 declarations.push(deindent `
21080 function ${name}(${original_params ? '...args' : ''}) {
21081 return ctx.${name}(ctx${original_params ? ', ...args' : ''});
21082 }
21083 `);
21084 }
21085 if (parent && parent.method) {
21086 code.prependRight(node.start, ': ');
21087 }
21088 function_expression = null;
21089 dependencies = null;
21090 contextual_dependencies = null;
21091 }
21092 if (node.type === 'AssignmentExpression') {
21093 const names = node.left.type === 'MemberExpression'
21094 ? [get_object(node.left).name]
21095 : extract_names(node.left);
21096 if (node.operator === '=' && nodes_match(node.left, node.right)) {
21097 const dirty = names.filter(name => {
21098 return !scope.declarations.has(name);
21099 });
21100 if (dirty.length)
21101 component.has_reactive_assignments = true;
21102 code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
21103 }
21104 else {
21105 names.forEach(name => {
21106 if (scope.declarations.has(name))
21107 return;
21108 const variable = component.var_lookup.get(name);
21109 if (variable && variable.hoistable)
21110 return;
21111 pending_assignments.add(name);
21112 });
21113 }
21114 }
21115 else if (node.type === 'UpdateExpression') {
21116 const { name } = get_object(node.argument);
21117 if (scope.declarations.has(name))
21118 return;
21119 const variable = component.var_lookup.get(name);
21120 if (variable && variable.hoistable)
21121 return;
21122 pending_assignments.add(name);
21123 }
21124 if (/Statement/.test(node.type)) {
21125 if (pending_assignments.size > 0) {
21126 const has_semi = code.original[node.end - 1] === ';';
21127 const insert = ((has_semi ? ' ' : '; ') +
21128 Array.from(pending_assignments).map(name => component.invalidate(name)).join('; '));
21129 if (/^(Break|Continue|Return)Statement/.test(node.type)) {
21130 if (node.argument) {
21131 code.overwrite(node.start, node.argument.start, `var $$result = `);
21132 code.appendLeft(node.end, `${insert}; return $$result`);
21133 }
21134 else {
21135 code.prependRight(node.start, `${insert}; `);
21136 }
21137 }
21138 else if (parent && /(If|For(In|Of)?|While)Statement/.test(parent.type) && node.type !== 'BlockStatement') {
21139 code.prependRight(node.start, '{ ');
21140 code.appendLeft(node.end, `${insert}; }`);
21141 }
21142 else {
21143 code.appendLeft(node.end, `${insert};`);
21144 }
21145 component.has_reactive_assignments = true;
21146 pending_assignments = new Set();
21147 }
21148 }
21149 }
21150 });
21151 if (declarations.length > 0) {
21152 block.maintain_context = true;
21153 declarations.forEach(declaration => {
21154 block.builders.init.add_block(declaration);
21155 });
21156 }
21157 return this.rendered = `[✂${this.node.start}-${this.node.end}✂]`;
21158 }
21159 }
21160 function get_function_name(_node, parent) {
21161 if (parent.type === 'EventHandler') {
21162 return `${parent.name}_handler`;
21163 }
21164 if (parent.type === 'Action') {
21165 return `${parent.name}_function`;
21166 }
21167 return 'func';
21168 }
21169 function is_contextual(component, scope, name) {
21170 if (name === '$$props')
21171 return true;
21172 // if it's a name below root scope, it's contextual
21173 if (!scope.is_top_level(name))
21174 return true;
21175 const variable = component.var_lookup.get(name);
21176 // hoistables, module declarations, and imports are non-contextual
21177 if (!variable || variable.hoistable)
21178 return false;
21179 // assume contextual
21180 return true;
21181 }
21182
21183 class AwaitBlock$1 extends Node$1 {
21184 constructor(component, parent, scope, info) {
21185 super(component, parent, scope, info);
21186 this.expression = new Expression(component, this, scope, info.expression);
21187 this.value = info.value;
21188 this.error = info.error;
21189 this.pending = new PendingBlock(component, this, scope, info.pending);
21190 this.then = new ThenBlock(component, this, scope, info.then);
21191 this.catch = new CatchBlock(component, this, scope, info.catch);
21192 }
21193 }
21194
21195 class EventHandler extends Node$1 {
21196 constructor(component, parent, template_scope, info) {
21197 super(component, parent, template_scope, info);
21198 this.uses_context = false;
21199 this.can_make_passive = false;
21200 this.name = info.name;
21201 this.modifiers = new Set(info.modifiers);
21202 if (info.expression) {
21203 this.expression = new Expression(component, this, template_scope, info.expression, true);
21204 this.uses_context = this.expression.uses_context;
21205 if (/FunctionExpression/.test(info.expression.type) && info.expression.params.length === 0) {
21206 // TODO make this detection more accurate — if `event.preventDefault` isn't called, and
21207 // `event` is passed to another function, we can make it passive
21208 this.can_make_passive = true;
21209 }
21210 else if (info.expression.type === 'Identifier') {
21211 let node = component.node_for_declaration.get(info.expression.name);
21212 if (node && node.type === 'VariableDeclaration') {
21213 // for `const handleClick = () => {...}`, we want the [arrow] function expression node
21214 const declarator = node.declarations.find(d => d.id.name === info.expression.name);
21215 node = declarator && declarator.init;
21216 }
21217 if (node && /Function/.test(node.type) && node.params.length === 0) {
21218 this.can_make_passive = true;
21219 }
21220 }
21221 }
21222 else {
21223 const name = component.get_unique_name(`${sanitize(this.name)}_handler`);
21224 component.add_var({
21225 name,
21226 internal: true,
21227 referenced: true
21228 });
21229 component.partly_hoisted.push(deindent `
21230 function ${name}(event) {
21231 @bubble($$self, event);
21232 }
21233 `);
21234 this.handler_name = name;
21235 }
21236 }
21237 // TODO move this? it is specific to render-dom
21238 render(block) {
21239 if (this.expression)
21240 return this.expression.render(block);
21241 // this.component.add_reference(this.handler_name);
21242 return `ctx.${this.handler_name}`;
21243 }
21244 }
21245
21246 class Body extends Node$1 {
21247 constructor(component, parent, scope, info) {
21248 super(component, parent, scope, info);
21249 this.handlers = [];
21250 info.attributes.forEach(node => {
21251 if (node.type === 'EventHandler') {
21252 this.handlers.push(new EventHandler(component, this, scope, node));
21253 }
21254 });
21255 }
21256 }
21257
21258 class Comment$2 extends Node$1 {
21259 constructor(component, parent, scope, info) {
21260 super(component, parent, scope, info);
21261 this.data = info.data;
21262 }
21263 }
21264
21265 class ElseBlock extends AbstractBlock {
21266 constructor(component, parent, scope, info) {
21267 super(component, parent, scope, info);
21268 this.children = map_children(component, this, scope, info.children);
21269 this.warn_if_empty_block();
21270 }
21271 }
21272
21273 function unpack_destructuring(contexts, node, tail) {
21274 if (!node)
21275 return;
21276 if (node.type === 'Identifier' || node.type === 'RestIdentifier') {
21277 contexts.push({
21278 key: node,
21279 tail
21280 });
21281 }
21282 else if (node.type === 'ArrayPattern') {
21283 node.elements.forEach((element, i) => {
21284 if (element && element.type === 'RestIdentifier') {
21285 unpack_destructuring(contexts, element, `${tail}.slice(${i})`);
21286 }
21287 else {
21288 unpack_destructuring(contexts, element, `${tail}[${i}]`);
21289 }
21290 });
21291 }
21292 else if (node.type === 'ObjectPattern') {
21293 const used_properties = [];
21294 node.properties.forEach((property) => {
21295 if (property.kind === 'rest') {
21296 unpack_destructuring(contexts, property.value, `@object_without_properties(${tail}, ${JSON.stringify(used_properties)})`);
21297 }
21298 else {
21299 used_properties.push(property.key.name);
21300 unpack_destructuring(contexts, property.value, `${tail}.${property.key.name}`);
21301 }
21302 });
21303 }
21304 }
21305 class EachBlock$1 extends AbstractBlock {
21306 constructor(component, parent, scope, info) {
21307 super(component, parent, scope, info);
21308 this.has_binding = false;
21309 this.expression = new Expression(component, this, scope, info.expression);
21310 this.context = info.context.name || 'each'; // TODO this is used to facilitate binding; currently fails with destructuring
21311 this.context_node = info.context;
21312 this.index = info.index;
21313 this.scope = scope.child();
21314 this.contexts = [];
21315 unpack_destructuring(this.contexts, info.context, new_tail());
21316 this.contexts.forEach(context => {
21317 this.scope.add(context.key.name, this.expression.dependencies, this);
21318 });
21319 this.key = info.key
21320 ? new Expression(component, this, this.scope, info.key)
21321 : null;
21322 if (this.index) {
21323 // index can only change if this is a keyed each block
21324 const dependencies = this.key ? this.expression.dependencies : new Set([]);
21325 this.scope.add(this.index, dependencies, this);
21326 }
21327 this.has_animation = false;
21328 this.children = map_children(component, this, this.scope, info.children);
21329 if (this.has_animation) {
21330 if (this.children.length !== 1) {
21331 const child = this.children.find(child => !!child.animation);
21332 component.error(child.animation, {
21333 code: `invalid-animation`,
21334 message: `An element that use the animate directive must be the sole child of a keyed each block`
21335 });
21336 }
21337 }
21338 this.warn_if_empty_block();
21339 this.else = info.else
21340 ? new ElseBlock(component, this, this.scope, info.else)
21341 : null;
21342 }
21343 }
21344
21345 class Attribute extends Node$1 {
21346 constructor(component, parent, scope, info) {
21347 super(component, parent, scope, info);
21348 if (info.type === 'Spread') {
21349 this.name = null;
21350 this.is_spread = true;
21351 this.is_true = false;
21352 this.is_synthetic = false;
21353 this.expression = new Expression(component, this, scope, info.expression);
21354 this.dependencies = this.expression.dependencies;
21355 this.chunks = null;
21356 this.is_dynamic = true; // TODO not necessarily
21357 this.is_static = false;
21358 this.should_cache = false; // TODO does this mean anything here?
21359 }
21360 else {
21361 this.name = info.name;
21362 this.is_true = info.value === true;
21363 this.is_static = true;
21364 this.is_synthetic = info.synthetic;
21365 this.dependencies = new Set();
21366 this.chunks = this.is_true
21367 ? []
21368 : info.value.map(node => {
21369 if (node.type === 'Text')
21370 return node;
21371 this.is_static = false;
21372 const expression = new Expression(component, this, scope, node.expression);
21373 add_to_set(this.dependencies, expression.dependencies);
21374 return expression;
21375 });
21376 this.is_dynamic = this.dependencies.size > 0;
21377 this.should_cache = this.is_dynamic
21378 ? this.chunks.length === 1
21379 // @ts-ignore todo: probably error
21380 ? this.chunks[0].node.type !== 'Identifier' || scope.names.has(this.chunks[0].node.name)
21381 : true
21382 : false;
21383 }
21384 }
21385 get_dependencies() {
21386 if (this.is_spread)
21387 return this.expression.dynamic_dependencies();
21388 const dependencies = new Set();
21389 this.chunks.forEach(chunk => {
21390 if (chunk.type === 'Expression') {
21391 add_to_set(dependencies, chunk.dynamic_dependencies());
21392 }
21393 });
21394 return Array.from(dependencies);
21395 }
21396 get_value(block) {
21397 if (this.is_true)
21398 return true;
21399 if (this.chunks.length === 0)
21400 return `""`;
21401 if (this.chunks.length === 1) {
21402 return this.chunks[0].type === 'Text'
21403 ? stringify(this.chunks[0].data)
21404 // @ts-ignore todo: probably error
21405 : this.chunks[0].render(block);
21406 }
21407 return (this.chunks[0].type === 'Text' ? '' : `"" + `) +
21408 this.chunks
21409 .map(chunk => {
21410 if (chunk.type === 'Text') {
21411 return stringify(chunk.data);
21412 }
21413 else {
21414 // @ts-ignore todo: probably error
21415 return chunk.get_precedence() <= 13 ? `(${chunk.render()})` : chunk.render();
21416 }
21417 })
21418 .join(' + ');
21419 }
21420 get_static_value() {
21421 if (this.is_spread || this.is_dynamic)
21422 return null;
21423 return this.is_true
21424 ? true
21425 : this.chunks[0]
21426 // method should be called only when `is_static = true`
21427 ? this.chunks[0].data
21428 : '';
21429 }
21430 }
21431
21432 // TODO this should live in a specific binding
21433 const read_only_media_attributes = new Set([
21434 'duration',
21435 'buffered',
21436 'seekable',
21437 'played'
21438 ]);
21439 class Binding extends Node$1 {
21440 constructor(component, parent, scope, info) {
21441 super(component, parent, scope, info);
21442 if (info.expression.type !== 'Identifier' && info.expression.type !== 'MemberExpression') {
21443 component.error(info, {
21444 code: 'invalid-directive-value',
21445 message: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)'
21446 });
21447 }
21448 this.name = info.name;
21449 this.expression = new Expression(component, this, scope, info.expression);
21450 let obj;
21451 let prop;
21452 const { name } = get_object(this.expression.node);
21453 this.is_contextual = scope.names.has(name);
21454 // make sure we track this as a mutable ref
21455 if (scope.is_let(name)) {
21456 component.error(this, {
21457 code: 'invalid-binding',
21458 message: 'Cannot bind to a variable declared with the let: directive'
21459 });
21460 }
21461 else if (this.is_contextual) {
21462 scope.dependencies_for_name.get(name).forEach(name => {
21463 const variable = component.var_lookup.get(name);
21464 variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true;
21465 });
21466 }
21467 else {
21468 const variable = component.var_lookup.get(name);
21469 if (!variable || variable.global)
21470 component.error(this.expression.node, {
21471 code: 'binding-undeclared',
21472 message: `${name} is not declared`
21473 });
21474 variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true;
21475 }
21476 if (this.expression.node.type === 'MemberExpression') {
21477 prop = `[✂${this.expression.node.property.start}-${this.expression.node.property.end}✂]`;
21478 if (!this.expression.node.computed)
21479 prop = `'${prop}'`;
21480 obj = `[✂${this.expression.node.object.start}-${this.expression.node.object.end}✂]`;
21481 }
21482 else {
21483 obj = 'ctx';
21484 prop = `'${name}'`;
21485 }
21486 this.obj = obj;
21487 this.prop = prop;
21488 const type = parent.get_static_attribute_value('type');
21489 this.is_readonly = (dimensions.test(this.name) ||
21490 (parent.is_media_node && parent.is_media_node() && read_only_media_attributes.has(this.name)) ||
21491 (parent.name === 'input' && type === 'file') // TODO others?
21492 );
21493 }
21494 is_readonly_media_attribute() {
21495 return read_only_media_attributes.has(this.name);
21496 }
21497 }
21498
21499 class Transition extends Node$1 {
21500 constructor(component, parent, scope, info) {
21501 super(component, parent, scope, info);
21502 component.warn_if_undefined(info.name, info, scope);
21503 this.name = info.name;
21504 component.qualify(info.name);
21505 this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
21506 this.is_local = info.modifiers.includes('local');
21507 if ((info.intro && parent.intro) || (info.outro && parent.outro)) {
21508 const parent_transition = (parent.intro || parent.outro);
21509 const message = this.directive === parent_transition.directive
21510 ? `An element can only have one '${this.directive}' directive`
21511 : `An element cannot have both ${describe(parent_transition)} directive and ${describe(this)} directive`;
21512 component.error(info, {
21513 code: `duplicate-transition`,
21514 message
21515 });
21516 }
21517 this.expression = info.expression
21518 ? new Expression(component, this, scope, info.expression, true)
21519 : null;
21520 }
21521 }
21522 function describe(transition) {
21523 return transition.directive === 'transition'
21524 ? `a 'transition'`
21525 : `an '${transition.directive}'`;
21526 }
21527
21528 class Animation extends Node$1 {
21529 constructor(component, parent, scope, info) {
21530 super(component, parent, scope, info);
21531 component.warn_if_undefined(info.name, info, scope);
21532 this.name = info.name;
21533 component.qualify(info.name);
21534 if (parent.animation) {
21535 component.error(this, {
21536 code: `duplicate-animation`,
21537 message: `An element can only have one 'animate' directive`
21538 });
21539 }
21540 const block = parent.parent;
21541 if (!block || block.type !== 'EachBlock' || !block.key) {
21542 // TODO can we relax the 'immediate child' rule?
21543 component.error(this, {
21544 code: `invalid-animation`,
21545 message: `An element that use the animate directive must be the immediate child of a keyed each block`
21546 });
21547 }
21548 block.has_animation = true;
21549 this.expression = info.expression
21550 ? new Expression(component, this, scope, info.expression, true)
21551 : null;
21552 }
21553 }
21554
21555 class Action extends Node$1 {
21556 constructor(component, parent, scope, info) {
21557 super(component, parent, scope, info);
21558 component.warn_if_undefined(info.name, info, scope);
21559 this.name = info.name;
21560 component.qualify(info.name);
21561 this.expression = info.expression
21562 ? new Expression(component, this, scope, info.expression)
21563 : null;
21564 this.uses_context = this.expression && this.expression.uses_context;
21565 }
21566 }
21567
21568 class Class extends Node$1 {
21569 constructor(component, parent, scope, info) {
21570 super(component, parent, scope, info);
21571 this.name = info.name;
21572 this.expression = info.expression
21573 ? new Expression(component, this, scope, info.expression)
21574 : null;
21575 }
21576 }
21577
21578 class Text$1 extends Node$1 {
21579 constructor(component, parent, scope, info) {
21580 super(component, parent, scope, info);
21581 this.data = info.data;
21582 }
21583 }
21584
21585 const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']);
21586 class Let extends Node$1 {
21587 constructor(component, parent, scope, info) {
21588 super(component, parent, scope, info);
21589 this.names = [];
21590 this.name = info.name;
21591 this.value = info.expression && `[✂${info.expression.start}-${info.expression.end}✂]`;
21592 if (info.expression) {
21593 walk(info.expression, {
21594 enter: node => {
21595 if (!applicable.has(node.type)) {
21596 component.error(node, {
21597 code: 'invalid-let',
21598 message: `let directive value must be an identifier or an object/array pattern`
21599 });
21600 }
21601 if (node.type === 'Identifier') {
21602 this.names.push(node.name);
21603 }
21604 }
21605 });
21606 }
21607 else {
21608 this.names.push(this.name);
21609 }
21610 }
21611 }
21612
21613 const svg$1 = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|svg|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/;
21614 const aria_attributes = 'activedescendant atomic autocomplete busy checked colindex controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription rowindex selected setsize sort valuemax valuemin valuenow valuetext'.split(' ');
21615 const aria_attribute_set = new Set(aria_attributes);
21616 const aria_roles = 'alert alertdialog application article banner button cell checkbox columnheader combobox command complementary composite contentinfo definition dialog directory document feed figure form grid gridcell group heading img input landmark link list listbox listitem log main marquee math menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option presentation progressbar radio radiogroup range region roletype row rowgroup rowheader scrollbar search searchbox section sectionhead select separator slider spinbutton status structure switch tab table tablist tabpanel term textbox timer toolbar tooltip tree treegrid treeitem widget window'.split(' ');
21617 const aria_role_set = new Set(aria_roles);
21618 const a11y_required_attributes = {
21619 a: ['href'],
21620 area: ['alt', 'aria-label', 'aria-labelledby'],
21621 // html-has-lang
21622 html: ['lang'],
21623 // iframe-has-title
21624 iframe: ['title'],
21625 img: ['alt'],
21626 object: ['title', 'aria-label', 'aria-labelledby']
21627 };
21628 const a11y_distracting_elements = new Set([
21629 'blink',
21630 'marquee'
21631 ]);
21632 const a11y_required_content = new Set([
21633 // anchor-has-content
21634 'a',
21635 // heading-has-content
21636 'h1',
21637 'h2',
21638 'h3',
21639 'h4',
21640 'h5',
21641 'h6'
21642 ]);
21643 const invisible_elements = new Set(['meta', 'html', 'script', 'style']);
21644 const valid_modifiers = new Set([
21645 'preventDefault',
21646 'stopPropagation',
21647 'capture',
21648 'once',
21649 'passive'
21650 ]);
21651 const passive_events = new Set([
21652 'wheel',
21653 'touchstart',
21654 'touchmove',
21655 'touchend',
21656 'touchcancel'
21657 ]);
21658 function get_namespace(parent, element, explicit_namespace) {
21659 const parent_element = parent.find_nearest(/^Element/);
21660 if (!parent_element) {
21661 return explicit_namespace || (svg$1.test(element.name)
21662 ? namespaces.svg
21663 : null);
21664 }
21665 if (element.name.toLowerCase() === 'svg')
21666 return namespaces.svg;
21667 if (parent_element.name.toLowerCase() === 'foreignobject')
21668 return null;
21669 return parent_element.namespace;
21670 }
21671 class Element$1 extends Node$1 {
21672 constructor(component, parent, scope, info) {
21673 super(component, parent, scope, info);
21674 this.attributes = [];
21675 this.actions = [];
21676 this.bindings = [];
21677 this.classes = [];
21678 this.handlers = [];
21679 this.lets = [];
21680 this.intro = null;
21681 this.outro = null;
21682 this.animation = null;
21683 this.name = info.name;
21684 this.namespace = get_namespace(parent, this, component.namespace);
21685 if (this.name === 'textarea') {
21686 if (info.children.length > 0) {
21687 const value_attribute = info.attributes.find(node => node.name === 'value');
21688 if (value_attribute) {
21689 component.error(value_attribute, {
21690 code: `textarea-duplicate-value`,
21691 message: `A <textarea> can have either a value attribute or (equivalently) child content, but not both`
21692 });
21693 }
21694 // this is an egregious hack, but it's the easiest way to get <textarea>
21695 // children treated the same way as a value attribute
21696 info.attributes.push({
21697 type: 'Attribute',
21698 name: 'value',
21699 value: info.children
21700 });
21701 info.children = [];
21702 }
21703 }
21704 if (this.name === 'option') {
21705 // Special case — treat these the same way:
21706 // <option>{foo}</option>
21707 // <option value={foo}>{foo}</option>
21708 const value_attribute = info.attributes.find(attribute => attribute.name === 'value');
21709 if (!value_attribute) {
21710 info.attributes.push({
21711 type: 'Attribute',
21712 name: 'value',
21713 value: info.children,
21714 synthetic: true
21715 });
21716 }
21717 }
21718 info.attributes.forEach(node => {
21719 switch (node.type) {
21720 case 'Action':
21721 this.actions.push(new Action(component, this, scope, node));
21722 break;
21723 case 'Attribute':
21724 case 'Spread':
21725 // special case
21726 if (node.name === 'xmlns')
21727 this.namespace = node.value[0].data;
21728 this.attributes.push(new Attribute(component, this, scope, node));
21729 break;
21730 case 'Binding':
21731 this.bindings.push(new Binding(component, this, scope, node));
21732 break;
21733 case 'Class':
21734 this.classes.push(new Class(component, this, scope, node));
21735 break;
21736 case 'EventHandler':
21737 this.handlers.push(new EventHandler(component, this, scope, node));
21738 break;
21739 case 'Let':
21740 this.lets.push(new Let(component, this, scope, node));
21741 break;
21742 case 'Transition':
21743 {
21744 const transition = new Transition(component, this, scope, node);
21745 if (node.intro)
21746 this.intro = transition;
21747 if (node.outro)
21748 this.outro = transition;
21749 break;
21750 }
21751 case 'Animation':
21752 this.animation = new Animation(component, this, scope, node);
21753 break;
21754 default:
21755 throw new Error(`Not implemented: ${node.type}`);
21756 }
21757 });
21758 if (this.lets.length > 0) {
21759 this.scope = scope.child();
21760 this.lets.forEach(l => {
21761 const dependencies = new Set([l.name]);
21762 l.names.forEach(name => {
21763 this.scope.add(name, dependencies, this);
21764 });
21765 });
21766 }
21767 else {
21768 this.scope = scope;
21769 }
21770 this.children = map_children(component, this, this.scope, info.children);
21771 this.validate();
21772 component.stylesheet.apply(this);
21773 }
21774 validate() {
21775 if (a11y_distracting_elements.has(this.name)) {
21776 // no-distracting-elements
21777 this.component.warn(this, {
21778 code: `a11y-distracting-elements`,
21779 message: `A11y: Avoid <${this.name}> elements`
21780 });
21781 }
21782 if (this.name === 'figcaption') {
21783 let { parent } = this;
21784 let is_figure_parent = false;
21785 while (parent) {
21786 if (parent.name === 'figure') {
21787 is_figure_parent = true;
21788 break;
21789 }
21790 if (parent.type === 'Element') {
21791 break;
21792 }
21793 parent = parent.parent;
21794 }
21795 if (!is_figure_parent) {
21796 this.component.warn(this, {
21797 code: `a11y-structure`,
21798 message: `A11y: <figcaption> must be an immediate child of <figure>`
21799 });
21800 }
21801 }
21802 if (this.name === 'figure') {
21803 const children = this.children.filter(node => {
21804 if (node.type === 'Comment')
21805 return false;
21806 if (node.type === 'Text')
21807 return /\S/.test(node.data);
21808 return true;
21809 });
21810 const index = children.findIndex(child => child.name === 'figcaption');
21811 if (index !== -1 && (index !== 0 && index !== children.length - 1)) {
21812 this.component.warn(children[index], {
21813 code: `a11y-structure`,
21814 message: `A11y: <figcaption> must be first or last child of <figure>`
21815 });
21816 }
21817 }
21818 this.validate_attributes();
21819 this.validate_bindings();
21820 this.validate_content();
21821 this.validate_event_handlers();
21822 }
21823 validate_attributes() {
21824 const { component } = this;
21825 const attribute_map = new Map();
21826 this.attributes.forEach(attribute => {
21827 if (attribute.is_spread)
21828 return;
21829 const name = attribute.name.toLowerCase();
21830 // aria-props
21831 if (name.startsWith('aria-')) {
21832 if (invisible_elements.has(this.name)) {
21833 // aria-unsupported-elements
21834 component.warn(attribute, {
21835 code: `a11y-aria-attributes`,
21836 message: `A11y: <${this.name}> should not have aria-* attributes`
21837 });
21838 }
21839 const type = name.slice(5);
21840 if (!aria_attribute_set.has(type)) {
21841 const match = fuzzymatch(type, aria_attributes);
21842 let message = `A11y: Unknown aria attribute 'aria-${type}'`;
21843 if (match)
21844 message += ` (did you mean '${match}'?)`;
21845 component.warn(attribute, {
21846 code: `a11y-unknown-aria-attribute`,
21847 message
21848 });
21849 }
21850 if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) {
21851 component.warn(attribute, {
21852 code: `a11y-hidden`,
21853 message: `A11y: <${this.name}> element should not be hidden`
21854 });
21855 }
21856 }
21857 // aria-role
21858 if (name === 'role') {
21859 if (invisible_elements.has(this.name)) {
21860 // aria-unsupported-elements
21861 component.warn(attribute, {
21862 code: `a11y-misplaced-role`,
21863 message: `A11y: <${this.name}> should not have role attribute`
21864 });
21865 }
21866 const value = attribute.get_static_value();
21867 // @ts-ignore
21868 if (value && !aria_role_set.has(value)) {
21869 // @ts-ignore
21870 const match = fuzzymatch(value, aria_roles);
21871 let message = `A11y: Unknown role '${value}'`;
21872 if (match)
21873 message += ` (did you mean '${match}'?)`;
21874 component.warn(attribute, {
21875 code: `a11y-unknown-role`,
21876 message
21877 });
21878 }
21879 }
21880 // no-access-key
21881 if (name === 'accesskey') {
21882 component.warn(attribute, {
21883 code: `a11y-accesskey`,
21884 message: `A11y: Avoid using accesskey`
21885 });
21886 }
21887 // no-autofocus
21888 if (name === 'autofocus') {
21889 component.warn(attribute, {
21890 code: `a11y-autofocus`,
21891 message: `A11y: Avoid using autofocus`
21892 });
21893 }
21894 // scope
21895 if (name === 'scope' && this.name !== 'th') {
21896 component.warn(attribute, {
21897 code: `a11y-misplaced-scope`,
21898 message: `A11y: The scope attribute should only be used with <th> elements`
21899 });
21900 }
21901 // tabindex-no-positive
21902 if (name === 'tabindex') {
21903 const value = attribute.get_static_value();
21904 // @ts-ignore todo is tabindex=true correct case?
21905 if (!isNaN(value) && +value > 0) {
21906 component.warn(attribute, {
21907 code: `a11y-positive-tabindex`,
21908 message: `A11y: avoid tabindex values above zero`
21909 });
21910 }
21911 }
21912 if (name === 'slot') {
21913 if (!attribute.is_static) {
21914 component.error(attribute, {
21915 code: `invalid-slot-attribute`,
21916 message: `slot attribute cannot have a dynamic value`
21917 });
21918 }
21919 if (component.slot_outlets.has(name)) {
21920 component.error(attribute, {
21921 code: `duplicate-slot-attribute`,
21922 message: `Duplicate '${name}' slot`
21923 });
21924 component.slot_outlets.add(name);
21925 }
21926 let ancestor = this.parent;
21927 do {
21928 if (ancestor.type === 'InlineComponent')
21929 break;
21930 if (ancestor.type === 'Element' && /-/.test(ancestor.name))
21931 break;
21932 if (ancestor.type === 'IfBlock' || ancestor.type === 'EachBlock') {
21933 const type = ancestor.type === 'IfBlock' ? 'if' : 'each';
21934 const message = `Cannot place slotted elements inside an ${type}-block`;
21935 component.error(attribute, {
21936 code: `invalid-slotted-content`,
21937 message
21938 });
21939 }
21940 } while (ancestor = ancestor.parent);
21941 if (!ancestor) {
21942 component.error(attribute, {
21943 code: `invalid-slotted-content`,
21944 message: `Element with a slot='...' attribute must be a descendant of a component or custom element`
21945 });
21946 }
21947 }
21948 attribute_map.set(attribute.name, attribute);
21949 });
21950 // handle special cases
21951 if (this.name === 'a') {
21952 const attribute = attribute_map.get('href') || attribute_map.get('xlink:href');
21953 if (attribute) {
21954 const value = attribute.get_static_value();
21955 if (value === '' || value === '#') {
21956 component.warn(attribute, {
21957 code: `a11y-invalid-attribute`,
21958 message: `A11y: '${value}' is not a valid ${attribute.name} attribute`
21959 });
21960 }
21961 }
21962 else {
21963 component.warn(this, {
21964 code: `a11y-missing-attribute`,
21965 message: `A11y: <a> element should have an href attribute`
21966 });
21967 }
21968 }
21969 else {
21970 const required_attributes = a11y_required_attributes[this.name];
21971 if (required_attributes) {
21972 const has_attribute = required_attributes.some(name => attribute_map.has(name));
21973 if (!has_attribute) {
21974 should_have_attribute(this, required_attributes);
21975 }
21976 }
21977 if (this.name === 'input') {
21978 const type = attribute_map.get('type');
21979 if (type && type.get_static_value() === 'image') {
21980 should_have_attribute(this, ['alt', 'aria-label', 'aria-labelledby'], 'input type="image"');
21981 }
21982 }
21983 }
21984 }
21985 validate_bindings() {
21986 const { component } = this;
21987 const check_type_attribute = () => {
21988 const attribute = this.attributes.find((attribute) => attribute.name === 'type');
21989 if (!attribute)
21990 return null;
21991 if (!attribute.is_static) {
21992 component.error(attribute, {
21993 code: `invalid-type`,
21994 message: `'type' attribute cannot be dynamic if input uses two-way binding`
21995 });
21996 }
21997 const value = attribute.get_static_value();
21998 if (value === true) {
21999 component.error(attribute, {
22000 code: `missing-type`,
22001 message: `'type' attribute must be specified`
22002 });
22003 }
22004 return value;
22005 };
22006 this.bindings.forEach(binding => {
22007 const { name } = binding;
22008 if (name === 'value') {
22009 if (this.name !== 'input' &&
22010 this.name !== 'textarea' &&
22011 this.name !== 'select') {
22012 component.error(binding, {
22013 code: `invalid-binding`,
22014 message: `'value' is not a valid binding on <${this.name}> elements`
22015 });
22016 }
22017 if (this.name === 'select') {
22018 const attribute = this.attributes.find((attribute) => attribute.name === 'multiple');
22019 if (attribute && !attribute.is_static) {
22020 component.error(attribute, {
22021 code: `dynamic-multiple-attribute`,
22022 message: `'multiple' attribute cannot be dynamic if select uses two-way binding`
22023 });
22024 }
22025 }
22026 else {
22027 check_type_attribute();
22028 }
22029 }
22030 else if (name === 'checked' || name === 'indeterminate') {
22031 if (this.name !== 'input') {
22032 component.error(binding, {
22033 code: `invalid-binding`,
22034 message: `'${name}' is not a valid binding on <${this.name}> elements`
22035 });
22036 }
22037 const type = check_type_attribute();
22038 if (type !== 'checkbox') {
22039 let message = `'${name}' binding can only be used with <input type="checkbox">`;
22040 if (type === 'radio')
22041 message += ` — for <input type="radio">, use 'group' binding`;
22042 component.error(binding, { code: `invalid-binding`, message });
22043 }
22044 }
22045 else if (name === 'group') {
22046 if (this.name !== 'input') {
22047 component.error(binding, {
22048 code: `invalid-binding`,
22049 message: `'group' is not a valid binding on <${this.name}> elements`
22050 });
22051 }
22052 const type = check_type_attribute();
22053 if (type !== 'checkbox' && type !== 'radio') {
22054 component.error(binding, {
22055 code: `invalid-binding`,
22056 message: `'group' binding can only be used with <input type="checkbox"> or <input type="radio">`
22057 });
22058 }
22059 }
22060 else if (name === 'files') {
22061 if (this.name !== 'input') {
22062 component.error(binding, {
22063 code: `invalid-binding`,
22064 message: `'files' is not a valid binding on <${this.name}> elements`
22065 });
22066 }
22067 const type = check_type_attribute();
22068 if (type !== 'file') {
22069 component.error(binding, {
22070 code: `invalid-binding`,
22071 message: `'files' binding can only be used with <input type="file">`
22072 });
22073 }
22074 }
22075 else if (name === 'open') {
22076 if (this.name !== 'details') {
22077 component.error(binding, {
22078 code: `invalid-binding`,
22079 message: `'${name}' binding can only be used with <details>`
22080 });
22081 }
22082 }
22083 else if (name === 'currentTime' ||
22084 name === 'duration' ||
22085 name === 'paused' ||
22086 name === 'buffered' ||
22087 name === 'seekable' ||
22088 name === 'played' ||
22089 name === 'volume' ||
22090 name === 'playbackRate') {
22091 if (this.name !== 'audio' && this.name !== 'video') {
22092 component.error(binding, {
22093 code: `invalid-binding`,
22094 message: `'${name}' binding can only be used with <audio> or <video>`
22095 });
22096 }
22097 }
22098 else if (dimensions.test(name)) {
22099 if (this.name === 'svg' && (name === 'offsetWidth' || name === 'offsetHeight')) {
22100 component.error(binding, {
22101 code: 'invalid-binding',
22102 message: `'${binding.name}' is not a valid binding on <svg>. Use '${name.replace('offset', 'client')}' instead`
22103 });
22104 }
22105 else if (svg$1.test(this.name)) {
22106 component.error(binding, {
22107 code: 'invalid-binding',
22108 message: `'${binding.name}' is not a valid binding on SVG elements`
22109 });
22110 }
22111 else if (is_void(this.name)) {
22112 component.error(binding, {
22113 code: 'invalid-binding',
22114 message: `'${binding.name}' is not a valid binding on void elements like <${this.name}>. Use a wrapper element instead`
22115 });
22116 }
22117 }
22118 else if (name === 'textContent' ||
22119 name === 'innerHTML') {
22120 const contenteditable = this.attributes.find((attribute) => attribute.name === 'contenteditable');
22121 if (!contenteditable) {
22122 component.error(binding, {
22123 code: `missing-contenteditable-attribute`,
22124 message: `'contenteditable' attribute is required for textContent and innerHTML two-way bindings`
22125 });
22126 }
22127 else if (contenteditable && !contenteditable.is_static) {
22128 component.error(contenteditable, {
22129 code: `dynamic-contenteditable-attribute`,
22130 message: `'contenteditable' attribute cannot be dynamic if element uses two-way binding`
22131 });
22132 }
22133 }
22134 else if (name !== 'this') {
22135 component.error(binding, {
22136 code: `invalid-binding`,
22137 message: `'${binding.name}' is not a valid binding`
22138 });
22139 }
22140 });
22141 }
22142 validate_content() {
22143 if (!a11y_required_content.has(this.name))
22144 return;
22145 if (this.children.length === 0) {
22146 this.component.warn(this, {
22147 code: `a11y-missing-content`,
22148 message: `A11y: <${this.name}> element should have child content`
22149 });
22150 }
22151 }
22152 validate_event_handlers() {
22153 const { component } = this;
22154 this.handlers.forEach(handler => {
22155 if (handler.modifiers.has('passive') && handler.modifiers.has('preventDefault')) {
22156 component.error(handler, {
22157 code: 'invalid-event-modifier',
22158 message: `The 'passive' and 'preventDefault' modifiers cannot be used together`
22159 });
22160 }
22161 handler.modifiers.forEach(modifier => {
22162 if (!valid_modifiers.has(modifier)) {
22163 component.error(handler, {
22164 code: 'invalid-event-modifier',
22165 message: `Valid event modifiers are ${list$1(Array.from(valid_modifiers))}`
22166 });
22167 }
22168 if (modifier === 'passive') {
22169 if (passive_events.has(handler.name)) {
22170 if (handler.can_make_passive) {
22171 component.warn(handler, {
22172 code: 'redundant-event-modifier',
22173 message: `Touch event handlers that don't use the 'event' object are passive by default`
22174 });
22175 }
22176 }
22177 else {
22178 component.warn(handler, {
22179 code: 'redundant-event-modifier',
22180 message: `The passive modifier only works with wheel and touch events`
22181 });
22182 }
22183 }
22184 if (component.compile_options.legacy && (modifier === 'once' || modifier === 'passive')) {
22185 // TODO this could be supported, but it would need a few changes to
22186 // how event listeners work
22187 component.error(handler, {
22188 code: 'invalid-event-modifier',
22189 message: `The '${modifier}' modifier cannot be used in legacy mode`
22190 });
22191 }
22192 });
22193 if (passive_events.has(handler.name) && handler.can_make_passive && !handler.modifiers.has('preventDefault')) {
22194 // touch/wheel events should be passive by default
22195 handler.modifiers.add('passive');
22196 }
22197 });
22198 }
22199 is_media_node() {
22200 return this.name === 'audio' || this.name === 'video';
22201 }
22202 add_css_class(class_name = this.component.stylesheet.id) {
22203 const class_attribute = this.attributes.find(a => a.name === 'class');
22204 if (class_attribute && !class_attribute.is_true) {
22205 if (class_attribute.chunks.length === 1 && class_attribute.chunks[0].type === 'Text') {
22206 class_attribute.chunks[0].data += ` ${class_name}`;
22207 }
22208 else {
22209 class_attribute.chunks.push(new Text$1(this.component, this, this.scope, {
22210 type: 'Text',
22211 data: ` ${class_name}`
22212 }));
22213 }
22214 }
22215 else {
22216 this.attributes.push(new Attribute(this.component, this, this.scope, {
22217 type: 'Attribute',
22218 name: 'class',
22219 value: [{ type: 'Text', data: class_name }]
22220 }));
22221 }
22222 }
22223 }
22224 function should_have_attribute(node, attributes, name = node.name) {
22225 const article = /^[aeiou]/.test(attributes[0]) ? 'an' : 'a';
22226 const sequence = attributes.length > 1 ?
22227 attributes.slice(0, -1).join(', ') + ` or ${attributes[attributes.length - 1]}` :
22228 attributes[0];
22229 node.component.warn(node, {
22230 code: `a11y-missing-attribute`,
22231 message: `A11y: <${name}> element should have ${article} ${sequence} attribute`
22232 });
22233 }
22234
22235 class Head$1 extends Node$1 {
22236 constructor(component, parent, scope, info) {
22237 super(component, parent, scope, info);
22238 if (info.attributes.length) {
22239 component.error(info.attributes[0], {
22240 code: `invalid-attribute`,
22241 message: `<svelte:head> should not have any attributes or directives`
22242 });
22243 }
22244 this.children = map_children(component, parent, scope, info.children.filter(child => {
22245 return (child.type !== 'Text' || /\S/.test(child.data));
22246 }));
22247 }
22248 }
22249
22250 class IfBlock$1 extends AbstractBlock {
22251 constructor(component, parent, scope, info) {
22252 super(component, parent, scope, info);
22253 this.expression = new Expression(component, this, scope, info.expression);
22254 this.children = map_children(component, this, scope, info.children);
22255 this.else = info.else
22256 ? new ElseBlock(component, this, scope, info.else)
22257 : null;
22258 this.warn_if_empty_block();
22259 }
22260 }
22261
22262 class InlineComponent$1 extends Node$1 {
22263 constructor(component, parent, scope, info) {
22264 super(component, parent, scope, info);
22265 this.attributes = [];
22266 this.bindings = [];
22267 this.handlers = [];
22268 this.lets = [];
22269 if (info.name !== 'svelte:component' && info.name !== 'svelte:self') {
22270 const name = info.name.split('.')[0]; // accommodate namespaces
22271 component.warn_if_undefined(name, info, scope);
22272 component.add_reference(name);
22273 }
22274 this.name = info.name;
22275 this.expression = this.name === 'svelte:component'
22276 ? new Expression(component, this, scope, info.expression)
22277 : null;
22278 info.attributes.forEach(node => {
22279 /* eslint-disable no-fallthrough */
22280 switch (node.type) {
22281 case 'Action':
22282 component.error(node, {
22283 code: `invalid-action`,
22284 message: `Actions can only be applied to DOM elements, not components`
22285 });
22286 case 'Attribute':
22287 if (node.name === 'slot') {
22288 component.error(node, {
22289 code: `invalid-prop`,
22290 message: `'slot' is reserved for future use in named slots`
22291 });
22292 }
22293 // fallthrough
22294 case 'Spread':
22295 this.attributes.push(new Attribute(component, this, scope, node));
22296 break;
22297 case 'Binding':
22298 this.bindings.push(new Binding(component, this, scope, node));
22299 break;
22300 case 'Class':
22301 component.error(node, {
22302 code: `invalid-class`,
22303 message: `Classes can only be applied to DOM elements, not components`
22304 });
22305 case 'EventHandler':
22306 this.handlers.push(new EventHandler(component, this, scope, node));
22307 break;
22308 case 'Let':
22309 this.lets.push(new Let(component, this, scope, node));
22310 break;
22311 case 'Transition':
22312 component.error(node, {
22313 code: `invalid-transition`,
22314 message: `Transitions can only be applied to DOM elements, not components`
22315 });
22316 default:
22317 throw new Error(`Not implemented: ${node.type}`);
22318 }
22319 /* eslint-enable no-fallthrough */
22320 });
22321 if (this.lets.length > 0) {
22322 this.scope = scope.child();
22323 this.lets.forEach(l => {
22324 const dependencies = new Set([l.name]);
22325 l.names.forEach(name => {
22326 this.scope.add(name, dependencies, this);
22327 });
22328 });
22329 }
22330 else {
22331 this.scope = scope;
22332 }
22333 this.handlers.forEach(handler => {
22334 handler.modifiers.forEach(modifier => {
22335 if (modifier !== 'once') {
22336 component.error(handler, {
22337 code: 'invalid-event-modifier',
22338 message: `Event modifiers other than 'once' can only be used on DOM elements`
22339 });
22340 }
22341 });
22342 });
22343 this.children = map_children(component, this, this.scope, info.children);
22344 }
22345 }
22346
22347 class Tag$2 extends Node$1 {
22348 constructor(component, parent, scope, info) {
22349 super(component, parent, scope, info);
22350 this.expression = new Expression(component, this, scope, info.expression);
22351 this.should_cache = (info.expression.type !== 'Identifier' ||
22352 (this.expression.dependencies.size && scope.names.has(info.expression.name)));
22353 }
22354 }
22355
22356 class MustacheTag extends Tag$2 {
22357 }
22358
22359 class Options extends Node$1 {
22360 }
22361
22362 class RawMustacheTag extends Tag$2 {
22363 }
22364
22365 class DebugTag$1 extends Node$1 {
22366 constructor(component, parent, scope, info) {
22367 super(component, parent, scope, info);
22368 this.expressions = info.identifiers.map(node => {
22369 return new Expression(component, parent, scope, node);
22370 });
22371 }
22372 }
22373
22374 class Slot$1 extends Element$1 {
22375 constructor(component, parent, scope, info) {
22376 super(component, parent, scope, info);
22377 this.values = new Map();
22378 info.attributes.forEach(attr => {
22379 if (attr.type !== 'Attribute') {
22380 component.error(attr, {
22381 code: `invalid-slot-directive`,
22382 message: `<slot> cannot have directives`
22383 });
22384 }
22385 if (attr.name === 'name') {
22386 if (attr.value.length !== 1 || attr.value[0].type !== 'Text') {
22387 component.error(attr, {
22388 code: `dynamic-slot-name`,
22389 message: `<slot> name cannot be dynamic`
22390 });
22391 }
22392 this.slot_name = attr.value[0].data;
22393 if (this.slot_name === 'default') {
22394 component.error(attr, {
22395 code: `invalid-slot-name`,
22396 message: `default is a reserved word — it cannot be used as a slot name`
22397 });
22398 }
22399 }
22400 this.values.set(attr.name, new Attribute(component, this, scope, attr));
22401 });
22402 if (!this.slot_name)
22403 this.slot_name = 'default';
22404 if (this.slot_name === 'default') {
22405 // if this is the default slot, add our dependencies to any
22406 // other slots (which inherit our slot values) that were
22407 // previously encountered
22408 component.slots.forEach((slot) => {
22409 this.values.forEach((attribute, name) => {
22410 if (!slot.values.has(name)) {
22411 slot.values.set(name, attribute);
22412 }
22413 });
22414 });
22415 }
22416 else if (component.slots.has('default')) {
22417 // otherwise, go the other way — inherit values from
22418 // a previously encountered default slot
22419 const default_slot = component.slots.get('default');
22420 default_slot.values.forEach((attribute, name) => {
22421 if (!this.values.has(name)) {
22422 this.values.set(name, attribute);
22423 }
22424 });
22425 }
22426 component.slots.set(this.slot_name, this);
22427 }
22428 }
22429
22430 class Title$1 extends Node$1 {
22431 constructor(component, parent, scope, info) {
22432 super(component, parent, scope, info);
22433 this.children = map_children(component, parent, scope, info.children);
22434 if (info.attributes.length > 0) {
22435 component.error(info.attributes[0], {
22436 code: `illegal-attribute`,
22437 message: `<title> cannot have attributes`
22438 });
22439 }
22440 info.children.forEach(child => {
22441 if (child.type !== 'Text' && child.type !== 'MustacheTag') {
22442 component.error(child, {
22443 code: 'illegal-structure',
22444 message: `<title> can only contain text and {tags}`
22445 });
22446 }
22447 });
22448 this.should_cache = info.children.length === 1
22449 ? (info.children[0].type !== 'Identifier' ||
22450 scope.names.has(info.children[0].name))
22451 : true;
22452 }
22453 }
22454
22455 const valid_bindings = [
22456 'innerWidth',
22457 'innerHeight',
22458 'outerWidth',
22459 'outerHeight',
22460 'scrollX',
22461 'scrollY',
22462 'online'
22463 ];
22464 class Window extends Node$1 {
22465 constructor(component, parent, scope, info) {
22466 super(component, parent, scope, info);
22467 this.handlers = [];
22468 this.bindings = [];
22469 this.actions = [];
22470 info.attributes.forEach(node => {
22471 if (node.type === 'EventHandler') {
22472 this.handlers.push(new EventHandler(component, this, scope, node));
22473 }
22474 else if (node.type === 'Binding') {
22475 if (node.expression.type !== 'Identifier') {
22476 const { parts } = flatten_reference(node.expression);
22477 // TODO is this constraint necessary?
22478 component.error(node.expression, {
22479 code: `invalid-binding`,
22480 message: `Bindings on <svelte:window> must be to top-level properties, e.g. '${parts[parts.length - 1]}' rather than '${parts.join('.')}'`
22481 });
22482 }
22483 if (!~valid_bindings.indexOf(node.name)) {
22484 const match = (node.name === 'width' ? 'innerWidth' :
22485 node.name === 'height' ? 'innerHeight' :
22486 fuzzymatch(node.name, valid_bindings));
22487 const message = `'${node.name}' is not a valid binding on <svelte:window>`;
22488 if (match) {
22489 component.error(node, {
22490 code: `invalid-binding`,
22491 message: `${message} (did you mean '${match}'?)`
22492 });
22493 }
22494 else {
22495 component.error(node, {
22496 code: `invalid-binding`,
22497 message: `${message} — valid bindings are ${list$1(valid_bindings)}`
22498 });
22499 }
22500 }
22501 this.bindings.push(new Binding(component, this, scope, node));
22502 }
22503 else if (node.type === 'Action') {
22504 this.actions.push(new Action(component, this, scope, node));
22505 }
22506 });
22507 }
22508 }
22509
22510 function get_constructor(type) {
22511 switch (type) {
22512 case 'AwaitBlock': return AwaitBlock$1;
22513 case 'Body': return Body;
22514 case 'Comment': return Comment$2;
22515 case 'EachBlock': return EachBlock$1;
22516 case 'Element': return Element$1;
22517 case 'Head': return Head$1;
22518 case 'IfBlock': return IfBlock$1;
22519 case 'InlineComponent': return InlineComponent$1;
22520 case 'MustacheTag': return MustacheTag;
22521 case 'Options': return Options;
22522 case 'RawMustacheTag': return RawMustacheTag;
22523 case 'DebugTag': return DebugTag$1;
22524 case 'Slot': return Slot$1;
22525 case 'Text': return Text$1;
22526 case 'Title': return Title$1;
22527 case 'Window': return Window;
22528 default: throw new Error(`Not implemented: ${type}`);
22529 }
22530 }
22531 function map_children(component, parent, scope, children) {
22532 let last = null;
22533 return children.map(child => {
22534 const constructor = get_constructor(child.type);
22535 const node = new constructor(component, parent, scope, child);
22536 if (last)
22537 last.next = node;
22538 node.prev = last;
22539 last = node;
22540 return node;
22541 });
22542 }
22543
22544 class TemplateScope {
22545 constructor(parent) {
22546 this.owners = new Map();
22547 this.parent = parent;
22548 this.names = new Set(parent ? parent.names : []);
22549 this.dependencies_for_name = new Map(parent ? parent.dependencies_for_name : []);
22550 }
22551 add(name, dependencies, owner) {
22552 this.names.add(name);
22553 this.dependencies_for_name.set(name, dependencies);
22554 this.owners.set(name, owner);
22555 return this;
22556 }
22557 child() {
22558 const child = new TemplateScope(this);
22559 return child;
22560 }
22561 is_top_level(name) {
22562 return !this.parent || !this.names.has(name) && this.parent.is_top_level(name);
22563 }
22564 get_owner(name) {
22565 return this.owners.get(name) || (this.parent && this.parent.get_owner(name));
22566 }
22567 is_let(name) {
22568 const owner = this.get_owner(name);
22569 return owner && (owner.type === 'Element' || owner.type === 'InlineComponent');
22570 }
22571 }
22572
22573 class Fragment extends Node$1 {
22574 constructor(component, info) {
22575 const scope = new TemplateScope();
22576 super(component, null, scope, info);
22577 this.scope = scope;
22578 this.children = map_children(component, this, scope, info.children);
22579 }
22580 }
22581
22582 // This file is automatically generated
22583 var internal_exports = new Set(["SvelteComponent", "SvelteComponentDev", "SvelteElement", "add_attribute", "add_classes", "add_flush_callback", "add_location", "add_render_callback", "add_resize_listener", "add_transform", "afterUpdate", "append", "assign", "attr", "beforeUpdate", "bind", "binding_callbacks", "blank_object", "bubble", "check_outros", "children", "claim_element", "claim_text", "clear_loops", "createEventDispatcher", "create_animation", "create_bidirectional_transition", "create_in_transition", "create_out_transition", "create_slot", "create_ssr_component", "current_component", "custom_event", "debug", "destroy_block", "destroy_component", "destroy_each", "detach", "detach_after", "detach_before", "detach_between", "dirty_components", "each", "element", "empty", "escape", "escaped", "exclude_internal_props", "fix_and_destroy_block", "fix_and_outro_and_destroy_block", "fix_position", "flush", "getContext", "get_binding_group_value", "get_slot_changes", "get_slot_context", "get_spread_update", "get_store_value", "globals", "group_outros", "handle_promise", "identity", "init", "insert", "intros", "invalid_attribute_name_character", "is_client", "is_function", "is_promise", "listen", "loop", "measure", "missing_component", "mount_component", "noop", "not_equal", "now", "object_without_properties", "onDestroy", "onMount", "once", "outro_and_destroy_block", "prevent_default", "raf", "run", "run_all", "safe_not_equal", "schedule_update", "select_multiple_value", "select_option", "select_options", "select_value", "setContext", "set_attributes", "set_current_component", "set_custom_element_data", "set_data", "set_input_type", "set_now", "set_raf", "set_style", "space", "spread", "stop_propagation", "subscribe", "svg_element", "text", "tick", "time_ranges_to_array", "to_number", "toggle_class", "transition_in", "transition_out", "update_keyed_each", "validate_component", "validate_store", "xlink_attr"]);
22584
22585 function remove_indentation(code, node) {
22586 const indent = code.getIndentString();
22587 const pattern = new RegExp(`^${indent}`, 'gm');
22588 const excluded = [];
22589 walk(node, {
22590 enter(node) {
22591 if (node.type === 'TemplateElement') {
22592 excluded.push(node);
22593 }
22594 }
22595 });
22596 const str = code.original.slice(node.start, node.end);
22597 let match;
22598 while (match = pattern.exec(str)) {
22599 const index = node.start + match.index;
22600 while (excluded[0] && excluded[0].end < index)
22601 excluded.shift();
22602 if (excluded[0] && excluded[0].start < index)
22603 continue;
22604 code.remove(index, index + indent.length);
22605 }
22606 }
22607 function add_indentation(code, node, levels = 1) {
22608 const base_indent = code.getIndentString();
22609 const indent = repeat(base_indent, levels);
22610 const pattern = /\n/gm;
22611 const excluded = [];
22612 walk(node, {
22613 enter(node) {
22614 if (node.type === 'TemplateElement') {
22615 excluded.push(node);
22616 }
22617 }
22618 });
22619 const str = code.original.slice(node.start, node.end);
22620 let match;
22621 while (match = pattern.exec(str)) {
22622 const index = node.start + match.index;
22623 while (excluded[0] && excluded[0].end < index)
22624 excluded.shift();
22625 if (excluded[0] && excluded[0].start < index)
22626 continue;
22627 code.appendLeft(index + 1, indent);
22628 }
22629 }
22630
22631 // We need to tell estree-walker that it should always
22632 // look for an `else` block, otherwise it might get
22633 // the wrong idea about the shape of each/if blocks
22634 childKeys.EachBlock = childKeys.IfBlock = ['children', 'else'];
22635 childKeys.Attribute = ['value'];
22636 childKeys.ExportNamedDeclaration = ['declaration', 'specifiers'];
22637 function remove_node(code, start, end, body, node) {
22638 const i = body.indexOf(node);
22639 if (i === -1)
22640 throw new Error('node not in list');
22641 let a;
22642 let b;
22643 if (body.length === 1) {
22644 // remove everything, leave {}
22645 a = start;
22646 b = end;
22647 }
22648 else if (i === 0) {
22649 // remove everything before second node, including comments
22650 a = start;
22651 while (/\s/.test(code.original[a]))
22652 a += 1;
22653 b = body[i].end;
22654 while (/[\s,]/.test(code.original[b]))
22655 b += 1;
22656 }
22657 else {
22658 // remove the end of the previous node to the end of this one
22659 a = body[i - 1].end;
22660 b = node.end;
22661 }
22662 code.remove(a, b);
22663 return;
22664 }
22665 class Component {
22666 constructor(ast, source, name, compile_options, stats, warnings) {
22667 this.vars = [];
22668 this.var_lookup = new Map();
22669 this.imports = [];
22670 this.hoistable_nodes = new Set();
22671 this.node_for_declaration = new Map();
22672 this.partly_hoisted = [];
22673 this.fully_hoisted = [];
22674 this.reactive_declarations = [];
22675 this.reactive_declaration_nodes = new Set();
22676 this.has_reactive_assignments = false;
22677 this.injected_reactive_declaration_vars = new Set();
22678 this.helpers = new Map();
22679 this.globals = new Map();
22680 this.indirect_dependencies = new Map();
22681 this.aliases = new Map();
22682 this.used_names = new Set();
22683 this.globally_used_names = new Set();
22684 this.slots = new Map();
22685 this.slot_outlets = new Set();
22686 this.name = name;
22687 this.stats = stats;
22688 this.warnings = warnings;
22689 this.ast = ast;
22690 this.source = source;
22691 this.compile_options = compile_options;
22692 this.file = compile_options.filename && (
22693 // eslint-disable-next-line no-useless-escape
22694 typeof process !== 'undefined' ? compile_options.filename.replace(process.cwd(), '').replace(/^[\/\\]/, '') : compile_options.filename);
22695 this.locate = getLocator(this.source);
22696 this.code = new MagicString(source);
22697 // styles
22698 this.stylesheet = new Stylesheet(source, ast, compile_options.filename, compile_options.dev);
22699 this.stylesheet.validate(this);
22700 this.component_options = process_component_options(this, this.ast.html.children);
22701 this.namespace = namespaces[this.component_options.namespace] || this.component_options.namespace;
22702 if (compile_options.customElement) {
22703 if (this.component_options.tag === undefined && compile_options.tag === undefined) {
22704 const svelteOptions = ast.html.children.find(child => child.name === 'svelte:options') || { start: 0, end: 0 };
22705 this.warn(svelteOptions, {
22706 code: 'custom-element-no-tag',
22707 message: `No custom element 'tag' option was specified. To automatically register a custom element, specify a name with a hyphen in it, e.g. <svelte:options tag="my-thing"/>. To hide this warning, use <svelte:options tag={null}/>`
22708 });
22709 }
22710 this.tag = this.component_options.tag || compile_options.tag;
22711 }
22712 else {
22713 this.tag = this.name;
22714 }
22715 this.walk_module_js();
22716 this.walk_instance_js_pre_template();
22717 this.fragment = new Fragment(this, ast.html);
22718 this.name = this.get_unique_name(name);
22719 this.walk_instance_js_post_template();
22720 if (!compile_options.customElement)
22721 this.stylesheet.reify();
22722 this.stylesheet.warn_on_unused_selectors(this);
22723 }
22724 add_var(variable) {
22725 this.vars.push(variable);
22726 this.var_lookup.set(variable.name, variable);
22727 }
22728 add_reference(name) {
22729 const variable = this.var_lookup.get(name);
22730 if (variable) {
22731 variable.referenced = true;
22732 }
22733 else if (name === '$$props') {
22734 this.add_var({
22735 name,
22736 injected: true,
22737 referenced: true
22738 });
22739 }
22740 else if (name[0] === '$') {
22741 this.add_var({
22742 name,
22743 injected: true,
22744 referenced: true,
22745 mutated: true,
22746 writable: true
22747 });
22748 const subscribable_name = name.slice(1);
22749 this.add_reference(subscribable_name);
22750 const variable = this.var_lookup.get(subscribable_name);
22751 if (variable)
22752 variable.subscribable = true;
22753 }
22754 else {
22755 this.used_names.add(name);
22756 }
22757 }
22758 add_sourcemap_locations(node) {
22759 walk(node, {
22760 enter: (node) => {
22761 this.code.addSourcemapLocation(node.start);
22762 this.code.addSourcemapLocation(node.end);
22763 },
22764 });
22765 }
22766 alias(name) {
22767 if (!this.aliases.has(name)) {
22768 this.aliases.set(name, this.get_unique_name(name));
22769 }
22770 return this.aliases.get(name);
22771 }
22772 helper(name) {
22773 const alias = this.alias(name);
22774 this.helpers.set(name, alias);
22775 return alias;
22776 }
22777 global(name) {
22778 const alias = this.alias(name);
22779 this.globals.set(name, alias);
22780 return alias;
22781 }
22782 generate(result) {
22783 let js = null;
22784 let css = null;
22785 if (result) {
22786 const { compile_options, name } = this;
22787 const { format = 'esm' } = compile_options;
22788 const banner = `/* ${this.file ? `${this.file} ` : ``}generated by Svelte v${"3.6.6"} */`;
22789 result = result
22790 .replace(/__svelte:self__/g, this.name)
22791 .replace(compile_options.generate === 'ssr' ? /(@+|#+)(\w*(?:-\w*)?)/g : /(@+)(\w*(?:-\w*)?)/g, (_match, sigil, name) => {
22792 if (sigil === '@') {
22793 if (name[0] === '_') {
22794 return this.global(name.slice(1));
22795 }
22796 if (!internal_exports.has(name)) {
22797 throw new Error(`compiler error: this shouldn't happen! generated code is trying to use inexistent internal '${name}'`);
22798 }
22799 if (compile_options.dev && internal_exports.has(`${name}Dev`)) {
22800 name = `${name}Dev`;
22801 }
22802 return this.helper(name);
22803 }
22804 return sigil.slice(1) + name;
22805 });
22806 const referenced_globals = Array.from(this.globals, ([name, alias]) => name !== alias && ({ name, alias })).filter(Boolean);
22807 if (referenced_globals.length) {
22808 this.helper('globals');
22809 }
22810 const imported_helpers = Array.from(this.helpers, ([name, alias]) => ({ name, alias }));
22811 const module = create_module(result, format, name, banner, compile_options.sveltePath, imported_helpers, referenced_globals, this.imports, this.vars.filter(variable => variable.module && variable.export_name).map(variable => ({
22812 name: variable.name,
22813 as: variable.export_name
22814 })), this.source);
22815 const parts = module.split('✂]');
22816 const final_chunk = parts.pop();
22817 const compiled = new Bundle({ separator: '' });
22818 function add_string(str) {
22819 compiled.addSource({
22820 content: new MagicString(str),
22821 });
22822 }
22823 const { filename } = compile_options;
22824 // special case — the source file doesn't actually get used anywhere. we need
22825 // to add an empty file to populate map.sources and map.sourcesContent
22826 if (!parts.length) {
22827 compiled.addSource({
22828 filename,
22829 content: new MagicString(this.source).remove(0, this.source.length),
22830 });
22831 }
22832 const pattern = /\[✂(\d+)-(\d+)$/;
22833 parts.forEach((str) => {
22834 const chunk = str.replace(pattern, '');
22835 if (chunk)
22836 add_string(chunk);
22837 const match = pattern.exec(str);
22838 const snippet = this.code.snip(+match[1], +match[2]);
22839 compiled.addSource({
22840 filename,
22841 content: snippet,
22842 });
22843 });
22844 add_string(final_chunk);
22845 css = compile_options.customElement ?
22846 { code: null, map: null } :
22847 this.stylesheet.render(compile_options.cssOutputFilename, true);
22848 js = {
22849 code: compiled.toString(),
22850 map: compiled.generateMap({
22851 includeContent: true,
22852 file: compile_options.outputFilename,
22853 })
22854 };
22855 }
22856 return {
22857 js,
22858 css,
22859 ast: this.ast,
22860 warnings: this.warnings,
22861 vars: this.vars.filter(v => !v.global && !v.internal).map(v => ({
22862 name: v.name,
22863 export_name: v.export_name || null,
22864 injected: v.injected || false,
22865 module: v.module || false,
22866 mutated: v.mutated || false,
22867 reassigned: v.reassigned || false,
22868 referenced: v.referenced || false,
22869 writable: v.writable || false
22870 })),
22871 stats: this.stats.render()
22872 };
22873 }
22874 get_unique_name(name) {
22875 if (test)
22876 name = `${name}$`;
22877 let alias = name;
22878 for (let i = 1; reserved.has(alias) ||
22879 this.var_lookup.has(alias) ||
22880 this.used_names.has(alias) ||
22881 this.globally_used_names.has(alias); alias = `${name}_${i++}`)
22882 ;
22883 this.used_names.add(alias);
22884 return alias;
22885 }
22886 get_unique_name_maker() {
22887 const local_used_names = new Set();
22888 function add(name) {
22889 local_used_names.add(name);
22890 }
22891 reserved.forEach(add);
22892 internal_exports.forEach(add);
22893 this.var_lookup.forEach((_value, key) => add(key));
22894 return (name) => {
22895 if (test)
22896 name = `${name}$`;
22897 let alias = name;
22898 for (let i = 1; this.used_names.has(alias) ||
22899 local_used_names.has(alias); alias = `${name}_${i++}`)
22900 ;
22901 local_used_names.add(alias);
22902 this.globally_used_names.add(alias);
22903 return alias;
22904 };
22905 }
22906 error(pos, e) {
22907 error$1(e.message, {
22908 name: 'ValidationError',
22909 code: e.code,
22910 source: this.source,
22911 start: pos.start,
22912 end: pos.end,
22913 filename: this.compile_options.filename
22914 });
22915 }
22916 warn(pos, warning) {
22917 if (!this.locator) {
22918 this.locator = getLocator(this.source, { offsetLine: 1 });
22919 }
22920 const start = this.locator(pos.start);
22921 const end = this.locator(pos.end);
22922 const frame = get_code_frame(this.source, start.line - 1, start.column);
22923 this.warnings.push({
22924 code: warning.code,
22925 message: warning.message,
22926 frame,
22927 start,
22928 end,
22929 pos: pos.start,
22930 filename: this.compile_options.filename,
22931 toString: () => `${warning.message} (${start.line + 1}:${start.column})\n${frame}`,
22932 });
22933 }
22934 extract_imports(content) {
22935 const { code } = this;
22936 content.body.forEach(node => {
22937 if (node.type === 'ImportDeclaration') {
22938 // imports need to be hoisted out of the IIFE
22939 remove_node(code, content.start, content.end, content.body, node);
22940 this.imports.push(node);
22941 }
22942 });
22943 }
22944 extract_exports(content) {
22945 const { code } = this;
22946 content.body.forEach(node => {
22947 if (node.type === 'ExportDefaultDeclaration') {
22948 this.error(node, {
22949 code: `default-export`,
22950 message: `A component cannot have a default export`
22951 });
22952 }
22953 if (node.type === 'ExportNamedDeclaration') {
22954 if (node.source) {
22955 this.error(node, {
22956 code: `not-implemented`,
22957 message: `A component currently cannot have an export ... from`
22958 });
22959 }
22960 if (node.declaration) {
22961 if (node.declaration.type === 'VariableDeclaration') {
22962 node.declaration.declarations.forEach(declarator => {
22963 extract_names(declarator.id).forEach(name => {
22964 const variable = this.var_lookup.get(name);
22965 variable.export_name = name;
22966 });
22967 });
22968 }
22969 else {
22970 const { name } = node.declaration.id;
22971 const variable = this.var_lookup.get(name);
22972 variable.export_name = name;
22973 }
22974 code.remove(node.start, node.declaration.start);
22975 }
22976 else {
22977 remove_node(code, content.start, content.end, content.body, node);
22978 node.specifiers.forEach(specifier => {
22979 const variable = this.var_lookup.get(specifier.local.name);
22980 if (variable) {
22981 variable.export_name = specifier.exported.name;
22982 }
22983 });
22984 }
22985 }
22986 });
22987 }
22988 extract_javascript(script) {
22989 const nodes_to_include = script.content.body.filter(node => {
22990 if (this.hoistable_nodes.has(node))
22991 return false;
22992 if (this.reactive_declaration_nodes.has(node))
22993 return false;
22994 if (node.type === 'ImportDeclaration')
22995 return false;
22996 if (node.type === 'ExportDeclaration' && node.specifiers.length > 0)
22997 return false;
22998 return true;
22999 });
23000 if (nodes_to_include.length === 0)
23001 return null;
23002 let a = script.content.start;
23003 while (/\s/.test(this.source[a]))
23004 a += 1;
23005 let b = a;
23006 let result = '';
23007 script.content.body.forEach((node) => {
23008 if (this.hoistable_nodes.has(node) || this.reactive_declaration_nodes.has(node)) {
23009 if (a !== b)
23010 result += `[✂${a}-${b}✂]`;
23011 a = node.end;
23012 }
23013 b = node.end;
23014 });
23015 // while (/\s/.test(this.source[a - 1])) a -= 1;
23016 b = script.content.end;
23017 while (/\s/.test(this.source[b - 1]))
23018 b -= 1;
23019 if (a < b)
23020 result += `[✂${a}-${b}✂]`;
23021 return result || null;
23022 }
23023 walk_module_js() {
23024 const component = this;
23025 const script = this.ast.module;
23026 if (!script)
23027 return;
23028 walk(script.content, {
23029 enter(node) {
23030 if (node.type === 'LabeledStatement' && node.label.name === '$') {
23031 component.warn(node, {
23032 code: 'module-script-reactive-declaration',
23033 message: '$: has no effect in a module script'
23034 });
23035 }
23036 }
23037 });
23038 this.add_sourcemap_locations(script.content);
23039 const { scope, globals } = create_scopes(script.content);
23040 this.module_scope = scope;
23041 scope.declarations.forEach((node, name) => {
23042 if (name[0] === '$') {
23043 this.error(node, {
23044 code: 'illegal-declaration',
23045 message: `The $ prefix is reserved, and cannot be used for variable and import names`
23046 });
23047 }
23048 this.add_var({
23049 name,
23050 module: true,
23051 hoistable: true,
23052 writable: node.kind === 'var' || node.kind === 'let'
23053 });
23054 });
23055 globals.forEach((node, name) => {
23056 if (name[0] === '$') {
23057 this.error(node, {
23058 code: 'illegal-subscription',
23059 message: `Cannot reference store value inside <script context="module">`
23060 });
23061 }
23062 else {
23063 this.add_var({
23064 name,
23065 global: true
23066 });
23067 }
23068 });
23069 this.extract_imports(script.content);
23070 this.extract_exports(script.content);
23071 remove_indentation(this.code, script.content);
23072 this.module_javascript = this.extract_javascript(script);
23073 }
23074 walk_instance_js_pre_template() {
23075 const script = this.ast.instance;
23076 if (!script)
23077 return;
23078 this.add_sourcemap_locations(script.content);
23079 // inject vars for reactive declarations
23080 script.content.body.forEach(node => {
23081 if (node.type !== 'LabeledStatement')
23082 return;
23083 if (node.body.type !== 'ExpressionStatement')
23084 return;
23085 const expression = unwrap_parens(node.body.expression);
23086 if (expression.type !== 'AssignmentExpression')
23087 return;
23088 extract_names(expression.left).forEach(name => {
23089 if (!this.var_lookup.has(name) && name[0] !== '$') {
23090 this.injected_reactive_declaration_vars.add(name);
23091 }
23092 });
23093 });
23094 const { scope: instance_scope, map, globals } = create_scopes(script.content);
23095 this.instance_scope = instance_scope;
23096 this.instance_scope_map = map;
23097 instance_scope.declarations.forEach((node, name) => {
23098 if (name[0] === '$') {
23099 this.error(node, {
23100 code: 'illegal-declaration',
23101 message: `The $ prefix is reserved, and cannot be used for variable and import names`
23102 });
23103 }
23104 this.add_var({
23105 name,
23106 initialised: instance_scope.initialised_declarations.has(name),
23107 hoistable: /^Import/.test(node.type),
23108 writable: node.kind === 'var' || node.kind === 'let'
23109 });
23110 this.node_for_declaration.set(name, node);
23111 });
23112 globals.forEach((_node, name) => {
23113 if (this.var_lookup.has(name))
23114 return;
23115 if (this.injected_reactive_declaration_vars.has(name)) {
23116 this.add_var({
23117 name,
23118 injected: true,
23119 writable: true,
23120 reassigned: true,
23121 initialised: true
23122 });
23123 }
23124 else if (name === '$$props') {
23125 this.add_var({
23126 name,
23127 injected: true
23128 });
23129 }
23130 else if (name[0] === '$') {
23131 this.add_var({
23132 name,
23133 injected: true,
23134 mutated: true,
23135 writable: true
23136 });
23137 this.add_reference(name.slice(1));
23138 const variable = this.var_lookup.get(name.slice(1));
23139 if (variable)
23140 variable.subscribable = true;
23141 }
23142 else {
23143 this.add_var({
23144 name,
23145 global: true
23146 });
23147 }
23148 });
23149 this.extract_imports(script.content);
23150 this.extract_exports(script.content);
23151 this.track_mutations();
23152 }
23153 walk_instance_js_post_template() {
23154 const script = this.ast.instance;
23155 if (!script)
23156 return;
23157 this.hoist_instance_declarations();
23158 this.extract_reactive_declarations();
23159 this.extract_reactive_store_references();
23160 this.javascript = this.extract_javascript(script);
23161 }
23162 // TODO merge this with other walks that are independent
23163 track_mutations() {
23164 const component = this;
23165 const { instance_scope, instance_scope_map: map } = this;
23166 let scope = instance_scope;
23167 walk(this.ast.instance.content, {
23168 enter(node) {
23169 if (map.has(node)) {
23170 scope = map.get(node);
23171 }
23172 let names;
23173 let deep = false;
23174 if (node.type === 'AssignmentExpression') {
23175 deep = node.left.type === 'MemberExpression';
23176 names = deep
23177 ? [get_object(node.left).name]
23178 : extract_names(node.left);
23179 }
23180 else if (node.type === 'UpdateExpression') {
23181 names = [get_object(node.argument).name];
23182 }
23183 if (names) {
23184 names.forEach(name => {
23185 if (scope.find_owner(name) === instance_scope) {
23186 const variable = component.var_lookup.get(name);
23187 variable[deep ? 'mutated' : 'reassigned'] = true;
23188 }
23189 });
23190 }
23191 },
23192 leave(node) {
23193 if (map.has(node)) {
23194 scope = scope.parent;
23195 }
23196 }
23197 });
23198 }
23199 extract_reactive_store_references() {
23200 // TODO this pattern happens a lot... can we abstract it
23201 // (or better still, do fewer AST walks)?
23202 const component = this;
23203 let { instance_scope: scope, instance_scope_map: map } = this;
23204 walk(this.ast.instance.content, {
23205 enter(node, parent) {
23206 if (map.has(node)) {
23207 scope = map.get(node);
23208 }
23209 if (node.type === 'LabeledStatement' && node.label.name === '$' && parent.type !== 'Program') {
23210 component.warn(node, {
23211 code: 'non-top-level-reactive-declaration',
23212 message: '$: has no effect outside of the top-level'
23213 });
23214 }
23215 if (isReference(node, parent)) {
23216 const object = get_object(node);
23217 const { name } = object;
23218 if (name[0] === '$' && !scope.has(name)) {
23219 component.warn_if_undefined(name, object, null);
23220 }
23221 }
23222 },
23223 leave(node) {
23224 if (map.has(node)) {
23225 scope = scope.parent;
23226 }
23227 }
23228 });
23229 }
23230 invalidate(name, value) {
23231 const variable = this.var_lookup.get(name);
23232 if (variable && (variable.subscribable && variable.reassigned)) {
23233 return `$$subscribe_${name}(), $$invalidate('${name}', ${value || name})`;
23234 }
23235 if (name[0] === '$' && name[1] !== '$') {
23236 return `${name.slice(1)}.set(${name})`;
23237 }
23238 if (variable && !variable.referenced && !variable.is_reactive_dependency && !variable.export_name && !name.startsWith('$$')) {
23239 return value || name;
23240 }
23241 if (value) {
23242 return `$$invalidate('${name}', ${value})`;
23243 }
23244 // if this is a reactive declaration, invalidate dependencies recursively
23245 const deps = new Set([name]);
23246 deps.forEach(name => {
23247 const reactive_declarations = this.reactive_declarations.filter(x => x.assignees.has(name));
23248 reactive_declarations.forEach(declaration => {
23249 declaration.dependencies.forEach(name => {
23250 deps.add(name);
23251 });
23252 });
23253 });
23254 return Array.from(deps).map(n => `$$invalidate('${n}', ${n})`).join(', ');
23255 }
23256 rewrite_props(get_insert) {
23257 const component = this;
23258 const { code, instance_scope, instance_scope_map: map } = this;
23259 let scope = instance_scope;
23260 const coalesced_declarations = [];
23261 let current_group;
23262 walk(this.ast.instance.content, {
23263 enter(node, parent) {
23264 if (/Function/.test(node.type)) {
23265 current_group = null;
23266 return this.skip();
23267 }
23268 if (map.has(node)) {
23269 scope = map.get(node);
23270 }
23271 if (node.type === 'VariableDeclaration') {
23272 if (node.kind === 'var' || scope === instance_scope) {
23273 node.declarations.forEach((declarator, i) => {
23274 const next = node.declarations[i + 1];
23275 if (declarator.id.type !== 'Identifier') {
23276 const inserts = [];
23277 extract_names(declarator.id).forEach(name => {
23278 const variable = component.var_lookup.get(name);
23279 if (variable.export_name) {
23280 component.error(declarator, {
23281 code: 'destructured-prop',
23282 message: `Cannot declare props in destructured declaration`
23283 });
23284 }
23285 if (variable.subscribable) {
23286 inserts.push(get_insert(variable));
23287 }
23288 });
23289 if (inserts.length > 0) {
23290 if (next) {
23291 code.overwrite(declarator.end, next.start, `; ${inserts.join('; ')}; ${node.kind} `);
23292 }
23293 else {
23294 code.appendLeft(declarator.end, `; ${inserts.join('; ')}`);
23295 }
23296 }
23297 return;
23298 }
23299 const { name } = declarator.id;
23300 const variable = component.var_lookup.get(name);
23301 if (variable.export_name) {
23302 if (current_group && current_group.kind !== node.kind) {
23303 current_group = null;
23304 }
23305 const insert = variable.subscribable
23306 ? get_insert(variable)
23307 : null;
23308 if (!current_group || (current_group.insert && insert)) {
23309 current_group = { kind: node.kind, declarators: [declarator], insert };
23310 coalesced_declarations.push(current_group);
23311 }
23312 else if (insert) {
23313 current_group.insert = insert;
23314 current_group.declarators.push(declarator);
23315 }
23316 else {
23317 current_group.declarators.push(declarator);
23318 }
23319 if (variable.writable && variable.name !== variable.export_name) {
23320 code.prependRight(declarator.id.start, `${variable.export_name}: `);
23321 }
23322 if (next) {
23323 const next_variable = component.var_lookup.get(next.id.name);
23324 const new_declaration = !next_variable.export_name
23325 || (current_group.insert && next_variable.subscribable);
23326 if (new_declaration) {
23327 code.overwrite(declarator.end, next.start, ` ${node.kind} `);
23328 }
23329 }
23330 }
23331 else {
23332 current_group = null;
23333 if (variable.subscribable) {
23334 const insert = get_insert(variable);
23335 if (next) {
23336 code.overwrite(declarator.end, next.start, `; ${insert}; ${node.kind} `);
23337 }
23338 else {
23339 code.appendLeft(declarator.end, `; ${insert}`);
23340 }
23341 }
23342 }
23343 });
23344 }
23345 }
23346 else {
23347 if (node.type !== 'ExportNamedDeclaration') {
23348 if (!parent || parent.type === 'Program')
23349 current_group = null;
23350 }
23351 }
23352 },
23353 leave(node) {
23354 if (map.has(node)) {
23355 scope = scope.parent;
23356 }
23357 }
23358 });
23359 coalesced_declarations.forEach(group => {
23360 const writable = group.kind === 'var' || group.kind === 'let';
23361 let c = 0;
23362 let combining = false;
23363 group.declarators.forEach(declarator => {
23364 const { id } = declarator;
23365 if (combining) {
23366 code.overwrite(c, id.start, ', ');
23367 }
23368 else {
23369 if (writable)
23370 code.appendLeft(id.start, '{ ');
23371 combining = true;
23372 }
23373 c = declarator.end;
23374 });
23375 if (combining) {
23376 const insert = group.insert
23377 ? `; ${group.insert}`
23378 : '';
23379 const suffix = `${writable ? ` } = $$props` : ``}${insert}` + (code.original[c] === ';' ? `` : `;`);
23380 code.appendLeft(c, suffix);
23381 }
23382 });
23383 }
23384 hoist_instance_declarations() {
23385 // we can safely hoist variable declarations that are
23386 // initialised to literals, and functions that don't
23387 // reference instance variables other than other
23388 // hoistable functions. TODO others?
23389 const { hoistable_nodes, var_lookup, injected_reactive_declaration_vars } = this;
23390 const top_level_function_declarations = new Map();
23391 this.ast.instance.content.body.forEach(node => {
23392 if (node.type === 'VariableDeclaration') {
23393 const all_hoistable = node.declarations.every(d => {
23394 if (!d.init)
23395 return false;
23396 if (d.init.type !== 'Literal')
23397 return false;
23398 const v = this.var_lookup.get(d.id.name);
23399 if (v.reassigned)
23400 return false;
23401 if (v.export_name)
23402 return false;
23403 if (this.var_lookup.get(d.id.name).reassigned)
23404 return false;
23405 if (this.vars.find(variable => variable.name === d.id.name && variable.module))
23406 return false;
23407 return true;
23408 });
23409 if (all_hoistable) {
23410 node.declarations.forEach(d => {
23411 const variable = this.var_lookup.get(d.id.name);
23412 variable.hoistable = true;
23413 });
23414 hoistable_nodes.add(node);
23415 this.fully_hoisted.push(`[✂${node.start}-${node.end}✂]`);
23416 }
23417 }
23418 if (node.type === 'ExportNamedDeclaration' && node.declaration && node.declaration.type === 'FunctionDeclaration') {
23419 top_level_function_declarations.set(node.declaration.id.name, node);
23420 }
23421 if (node.type === 'FunctionDeclaration') {
23422 top_level_function_declarations.set(node.id.name, node);
23423 }
23424 });
23425 const checked = new Set();
23426 const walking = new Set();
23427 const is_hoistable = fn_declaration => {
23428 if (fn_declaration.type === 'ExportNamedDeclaration') {
23429 fn_declaration = fn_declaration.declaration;
23430 }
23431 const instance_scope = this.instance_scope;
23432 let scope = this.instance_scope;
23433 const map = this.instance_scope_map;
23434 let hoistable = true;
23435 // handle cycles
23436 walking.add(fn_declaration);
23437 walk(fn_declaration, {
23438 enter(node, parent) {
23439 if (!hoistable)
23440 return this.skip();
23441 if (map.has(node)) {
23442 scope = map.get(node);
23443 }
23444 if (isReference(node, parent)) {
23445 const { name } = flatten_reference(node);
23446 const owner = scope.find_owner(name);
23447 if (injected_reactive_declaration_vars.has(name)) {
23448 hoistable = false;
23449 }
23450 else if (name[0] === '$' && !owner) {
23451 hoistable = false;
23452 }
23453 else if (owner === instance_scope) {
23454 if (name === fn_declaration.id.name)
23455 return;
23456 const variable = var_lookup.get(name);
23457 if (variable.hoistable)
23458 return;
23459 if (top_level_function_declarations.has(name)) {
23460 const other_declaration = top_level_function_declarations.get(name);
23461 if (walking.has(other_declaration)) {
23462 hoistable = false;
23463 }
23464 else if (other_declaration.type === 'ExportNamedDeclaration' && walking.has(other_declaration.declaration)) {
23465 hoistable = false;
23466 }
23467 else if (!is_hoistable(other_declaration)) {
23468 hoistable = false;
23469 }
23470 }
23471 else {
23472 hoistable = false;
23473 }
23474 }
23475 this.skip();
23476 }
23477 },
23478 leave(node) {
23479 if (map.has(node)) {
23480 scope = scope.parent;
23481 }
23482 }
23483 });
23484 checked.add(fn_declaration);
23485 walking.delete(fn_declaration);
23486 return hoistable;
23487 };
23488 for (const [name, node] of top_level_function_declarations) {
23489 if (is_hoistable(node)) {
23490 const variable = this.var_lookup.get(name);
23491 variable.hoistable = true;
23492 hoistable_nodes.add(node);
23493 remove_indentation(this.code, node);
23494 this.fully_hoisted.push(`[✂${node.start}-${node.end}✂]`);
23495 }
23496 }
23497 }
23498 extract_reactive_declarations() {
23499 const component = this;
23500 const unsorted_reactive_declarations = [];
23501 this.ast.instance.content.body.forEach(node => {
23502 if (node.type === 'LabeledStatement' && node.label.name === '$') {
23503 this.reactive_declaration_nodes.add(node);
23504 const assignees = new Set();
23505 const assignee_nodes = new Set();
23506 const dependencies = new Set();
23507 let scope = this.instance_scope;
23508 const map = this.instance_scope_map;
23509 walk(node.body, {
23510 enter(node, parent) {
23511 if (map.has(node)) {
23512 scope = map.get(node);
23513 }
23514 if (node.type === 'AssignmentExpression') {
23515 extract_identifiers(get_object(node.left)).forEach(node => {
23516 assignee_nodes.add(node);
23517 assignees.add(node.name);
23518 });
23519 }
23520 else if (node.type === 'UpdateExpression') {
23521 const identifier = get_object(node.argument);
23522 assignees.add(identifier.name);
23523 }
23524 else if (isReference(node, parent)) {
23525 const identifier = get_object(node);
23526 if (!assignee_nodes.has(identifier)) {
23527 const { name } = identifier;
23528 const owner = scope.find_owner(name);
23529 const variable = component.var_lookup.get(name);
23530 if (variable)
23531 variable.is_reactive_dependency = true;
23532 const is_writable_or_mutated = variable && (variable.writable || variable.mutated);
23533 if ((!owner || owner === component.instance_scope) &&
23534 (name[0] === '$' || is_writable_or_mutated)) {
23535 dependencies.add(name);
23536 }
23537 }
23538 this.skip();
23539 }
23540 },
23541 leave(node) {
23542 if (map.has(node)) {
23543 scope = scope.parent;
23544 }
23545 }
23546 });
23547 add_indentation(this.code, node.body, 2);
23548 const expression = node.body.expression && unwrap_parens(node.body.expression);
23549 const declaration = expression && expression.left;
23550 unsorted_reactive_declarations.push({ assignees, dependencies, node, declaration });
23551 }
23552 });
23553 const lookup = new Map();
23554 let seen;
23555 unsorted_reactive_declarations.forEach(declaration => {
23556 declaration.assignees.forEach(name => {
23557 if (!lookup.has(name)) {
23558 lookup.set(name, []);
23559 }
23560 // TODO warn or error if a name is assigned to in
23561 // multiple reactive declarations?
23562 lookup.get(name).push(declaration);
23563 });
23564 });
23565 const add_declaration = declaration => {
23566 if (seen.has(declaration)) {
23567 this.error(declaration.node, {
23568 code: 'cyclical-reactive-declaration',
23569 message: 'Cyclical dependency detected'
23570 });
23571 }
23572 if (this.reactive_declarations.indexOf(declaration) !== -1) {
23573 return;
23574 }
23575 seen.add(declaration);
23576 declaration.dependencies.forEach(name => {
23577 if (declaration.assignees.has(name))
23578 return;
23579 const earlier_declarations = lookup.get(name);
23580 if (earlier_declarations)
23581 earlier_declarations.forEach(declaration => {
23582 add_declaration(declaration);
23583 });
23584 });
23585 this.reactive_declarations.push(declaration);
23586 };
23587 unsorted_reactive_declarations.forEach(declaration => {
23588 seen = new Set();
23589 add_declaration(declaration);
23590 });
23591 }
23592 qualify(name) {
23593 if (name === `$$props`)
23594 return `ctx.$$props`;
23595 const variable = this.var_lookup.get(name);
23596 if (!variable)
23597 return name;
23598 this.add_reference(name); // TODO we can probably remove most other occurrences of this
23599 if (variable.hoistable)
23600 return name;
23601 return `ctx.${name}`;
23602 }
23603 warn_if_undefined(name, node, template_scope) {
23604 if (name[0] === '$') {
23605 name = name.slice(1);
23606 this.has_reactive_assignments = true; // TODO does this belong here?
23607 if (name[0] === '$')
23608 return; // $$props
23609 }
23610 if (this.var_lookup.has(name) && !this.var_lookup.get(name).global)
23611 return;
23612 if (template_scope && template_scope.names.has(name))
23613 return;
23614 if (globals.has(name))
23615 return;
23616 let message = `'${name}' is not defined`;
23617 if (!this.ast.instance)
23618 message += `. Consider adding a <script> block with 'export let ${name}' to declare a prop`;
23619 this.warn(node, {
23620 code: 'missing-declaration',
23621 message
23622 });
23623 }
23624 }
23625 function process_component_options(component, nodes) {
23626 const component_options = {
23627 immutable: component.compile_options.immutable || false,
23628 accessors: 'accessors' in component.compile_options
23629 ? component.compile_options.accessors
23630 : !!component.compile_options.customElement,
23631 preserveWhitespace: !!component.compile_options.preserveWhitespace
23632 };
23633 const node = nodes.find(node => node.name === 'svelte:options');
23634 function get_value(attribute, code, message) {
23635 const { value } = attribute;
23636 const chunk = value[0];
23637 if (!chunk)
23638 return true;
23639 if (value.length > 1) {
23640 component.error(attribute, { code, message });
23641 }
23642 if (chunk.type === 'Text')
23643 return chunk.data;
23644 if (chunk.expression.type !== 'Literal') {
23645 component.error(attribute, { code, message });
23646 }
23647 return chunk.expression.value;
23648 }
23649 if (node) {
23650 node.attributes.forEach(attribute => {
23651 if (attribute.type === 'Attribute') {
23652 const { name } = attribute;
23653 switch (name) {
23654 case 'tag': {
23655 const code = 'invalid-tag-attribute';
23656 const message = `'tag' must be a string literal`;
23657 const tag = get_value(attribute, code, message);
23658 if (typeof tag !== 'string' && tag !== null)
23659 component.error(attribute, { code, message });
23660 if (tag && !/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
23661 component.error(attribute, {
23662 code: `invalid-tag-property`,
23663 message: `tag name must be two or more words joined by the '-' character`
23664 });
23665 }
23666 component_options.tag = tag;
23667 break;
23668 }
23669 case 'namespace': {
23670 const code = 'invalid-namespace-attribute';
23671 const message = `The 'namespace' attribute must be a string literal representing a valid namespace`;
23672 const ns = get_value(attribute, code, message);
23673 if (typeof ns !== 'string')
23674 component.error(attribute, { code, message });
23675 if (valid_namespaces.indexOf(ns) === -1) {
23676 const match = fuzzymatch(ns, valid_namespaces);
23677 if (match) {
23678 component.error(attribute, {
23679 code: `invalid-namespace-property`,
23680 message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
23681 });
23682 }
23683 else {
23684 component.error(attribute, {
23685 code: `invalid-namespace-property`,
23686 message: `Invalid namespace '${ns}'`
23687 });
23688 }
23689 }
23690 component_options.namespace = ns;
23691 break;
23692 }
23693 case 'accessors':
23694 case 'immutable':
23695 case 'preserveWhitespace':
23696 {
23697 const code = `invalid-${name}-value`;
23698 const message = `${name} attribute must be true or false`;
23699 const value = get_value(attribute, code, message);
23700 if (typeof value !== 'boolean')
23701 component.error(attribute, { code, message });
23702 component_options[name] = value;
23703 break;
23704 }
23705 default:
23706 component.error(attribute, {
23707 code: `invalid-options-attribute`,
23708 message: `<svelte:options> unknown attribute`
23709 });
23710 }
23711 }
23712 else {
23713 component.error(attribute, {
23714 code: `invalid-options-attribute`,
23715 message: `<svelte:options> can only have static 'tag', 'namespace', 'accessors', 'immutable' and 'preserveWhitespace' attributes`
23716 });
23717 }
23718 });
23719 }
23720 return component_options;
23721 }
23722
23723 function get_name_from_filename(filename) {
23724 if (!filename)
23725 return null;
23726 // eslint-disable-next-line no-useless-escape
23727 const parts = filename.split(/[\/\\]/);
23728 if (parts.length > 1) {
23729 const index_match = parts[parts.length - 1].match(/^index(\.\w+)/);
23730 if (index_match) {
23731 parts.pop();
23732 parts[parts.length - 1] += index_match[1];
23733 }
23734 }
23735 const base = parts.pop()
23736 .replace(/\.[^.]+$/, "")
23737 .replace(/[^a-zA-Z_$0-9]+/g, '_')
23738 .replace(/^_/, '')
23739 .replace(/_$/, '')
23740 .replace(/^(\d)/, '_$1');
23741 if (!base) {
23742 throw new Error(`Could not derive component name from file ${filename}`);
23743 }
23744 return base[0].toUpperCase() + base.slice(1);
23745 }
23746
23747 const valid_options = [
23748 'format',
23749 'name',
23750 'filename',
23751 'generate',
23752 'outputFilename',
23753 'cssOutputFilename',
23754 'sveltePath',
23755 'dev',
23756 'accessors',
23757 'immutable',
23758 'hydratable',
23759 'legacy',
23760 'customElement',
23761 'tag',
23762 'css',
23763 'preserveComments',
23764 'preserveWhitespace'
23765 ];
23766 function validate_options(options, warnings) {
23767 const { name, filename } = options;
23768 Object.keys(options).forEach(key => {
23769 if (valid_options.indexOf(key) === -1) {
23770 const match = fuzzymatch(key, valid_options);
23771 let message = `Unrecognized option '${key}'`;
23772 if (match)
23773 message += ` (did you mean '${match}'?)`;
23774 throw new Error(message);
23775 }
23776 });
23777 if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
23778 throw new Error(`options.name must be a valid identifier (got '${name}')`);
23779 }
23780 if (name && /^[a-z]/.test(name)) {
23781 const message = `options.name should be capitalised`;
23782 warnings.push({
23783 code: `options-lowercase-name`,
23784 message,
23785 filename,
23786 toString: () => message,
23787 });
23788 }
23789 }
23790 function compile(source, options = {}) {
23791 options = assign({ generate: 'dom', dev: false }, options);
23792 const stats = new Stats();
23793 const warnings = [];
23794 validate_options(options, warnings);
23795 stats.start('parse');
23796 const ast = parse$2(source, options);
23797 stats.stop('parse');
23798 stats.start('create component');
23799 const component = new Component(ast, source, options.name || get_name_from_filename(options.filename) || 'Component', options, stats, warnings);
23800 stats.stop('create component');
23801 const js = options.generate === false
23802 ? null
23803 : options.generate === 'ssr'
23804 ? ssr(component, options)
23805 : dom(component, options);
23806 return component.generate(js);
23807 }
23808
23809 function parse_attributes(str) {
23810 const attrs = {};
23811 str.split(/\s+/).filter(Boolean).forEach(attr => {
23812 const p = attr.indexOf('=');
23813 if (p === -1) {
23814 attrs[attr] = true;
23815 }
23816 else {
23817 attrs[attr.slice(0, p)] = `'"`.includes(attr[p + 1]) ?
23818 attr.slice(p + 2, -1) :
23819 attr.slice(p + 1);
23820 }
23821 });
23822 return attrs;
23823 }
23824 async function replace_async(str, re, func) {
23825 const replacements = [];
23826 str.replace(re, (...args) => {
23827 replacements.push(func(...args).then(res => // eslint-disable-next-line @typescript-eslint/no-object-literal-type-assertion
23828 ({
23829 offset: args[args.length - 2],
23830 length: args[0].length,
23831 replacement: res,
23832 })));
23833 return '';
23834 });
23835 let out = '';
23836 let last_end = 0;
23837 for (const { offset, length, replacement } of await Promise.all(replacements)) {
23838 out += str.slice(last_end, offset) + replacement;
23839 last_end = offset + length;
23840 }
23841 out += str.slice(last_end);
23842 return out;
23843 }
23844 async function preprocess(source, preprocessor, options) {
23845 // @ts-ignore todo: doublecheck
23846 const filename = (options && options.filename) || preprocessor.filename; // legacy
23847 const dependencies = [];
23848 const preprocessors = Array.isArray(preprocessor) ? preprocessor : [preprocessor];
23849 const markup = preprocessors.map(p => p.markup).filter(Boolean);
23850 const script = preprocessors.map(p => p.script).filter(Boolean);
23851 const style = preprocessors.map(p => p.style).filter(Boolean);
23852 for (const fn of markup) {
23853 const processed = await fn({
23854 content: source,
23855 filename
23856 });
23857 if (processed && processed.dependencies)
23858 dependencies.push(...processed.dependencies);
23859 source = processed ? processed.code : source;
23860 }
23861 for (const fn of script) {
23862 source = await replace_async(source, /<script(\s[^]*?)?>([^]*?)<\/script>/gi, async (match, attributes = '', content) => {
23863 const processed = await fn({
23864 content,
23865 attributes: parse_attributes(attributes),
23866 filename
23867 });
23868 if (processed && processed.dependencies)
23869 dependencies.push(...processed.dependencies);
23870 return processed ? `<script${attributes}>${processed.code}</script>` : match;
23871 });
23872 }
23873 for (const fn of style) {
23874 source = await replace_async(source, /<style(\s[^]*?)?>([^]*?)<\/style>/gi, async (match, attributes = '', content) => {
23875 const processed = await fn({
23876 content,
23877 attributes: parse_attributes(attributes),
23878 filename
23879 });
23880 if (processed && processed.dependencies)
23881 dependencies.push(...processed.dependencies);
23882 return processed ? `<style${attributes}>${processed.code}</style>` : match;
23883 });
23884 }
23885 return {
23886 // TODO return separated output, in future version where svelte.compile supports it:
23887 // style: { code: styleCode, map: styleMap },
23888 // script { code: scriptCode, map: scriptMap },
23889 // markup { code: markupCode, map: markupMap },
23890 code: source,
23891 dependencies: [...new Set(dependencies)],
23892 toString() {
23893 return source;
23894 }
23895 };
23896 }
23897
23898 const VERSION = '3.6.6';
23899
23900 exports.VERSION = VERSION;
23901 exports.compile = compile;
23902 exports.parse = parse$2;
23903 exports.preprocess = preprocess;
23904 exports.walk = walk;
23905
23906 Object.defineProperty(exports, '__esModule', { value: true });
23907
23908}));
23909//# sourceMappingURL=compiler.js.map