Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/resources/formats/html/ojs/quarto-ojs-runtime.js
12923 views
1
// quarto-ojs-runtime v0.0.18 Copyright 2024 undefined
2
var EOL = {},
3
EOF = {},
4
QUOTE = 34,
5
NEWLINE = 10,
6
RETURN = 13;
7
8
function objectConverter(columns) {
9
return new Function("d", "return {" + columns.map(function(name, i) {
10
return JSON.stringify(name) + ": d[" + i + "] || \"\"";
11
}).join(",") + "}");
12
}
13
14
function customConverter(columns, f) {
15
var object = objectConverter(columns);
16
return function(row, i) {
17
return f(object(row), i, columns);
18
};
19
}
20
21
// Compute unique columns in order of discovery.
22
function inferColumns(rows) {
23
var columnSet = Object.create(null),
24
columns = [];
25
26
rows.forEach(function(row) {
27
for (var column in row) {
28
if (!(column in columnSet)) {
29
columns.push(columnSet[column] = column);
30
}
31
}
32
});
33
34
return columns;
35
}
36
37
function pad$1(value, width) {
38
var s = value + "", length = s.length;
39
return length < width ? new Array(width - length + 1).join(0) + s : s;
40
}
41
42
function formatYear$1(year) {
43
return year < 0 ? "-" + pad$1(-year, 6)
44
: year > 9999 ? "+" + pad$1(year, 6)
45
: pad$1(year, 4);
46
}
47
48
function formatDate$2(date) {
49
var hours = date.getUTCHours(),
50
minutes = date.getUTCMinutes(),
51
seconds = date.getUTCSeconds(),
52
milliseconds = date.getUTCMilliseconds();
53
return isNaN(date) ? "Invalid Date"
54
: formatYear$1(date.getUTCFullYear()) + "-" + pad$1(date.getUTCMonth() + 1, 2) + "-" + pad$1(date.getUTCDate(), 2)
55
+ (milliseconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "." + pad$1(milliseconds, 3) + "Z"
56
: seconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "Z"
57
: minutes || hours ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + "Z"
58
: "");
59
}
60
61
function dsv$1(delimiter) {
62
var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
63
DELIMITER = delimiter.charCodeAt(0);
64
65
function parse(text, f) {
66
var convert, columns, rows = parseRows(text, function(row, i) {
67
if (convert) return convert(row, i - 1);
68
columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
69
});
70
rows.columns = columns || [];
71
return rows;
72
}
73
74
function parseRows(text, f) {
75
var rows = [], // output rows
76
N = text.length,
77
I = 0, // current character index
78
n = 0, // current line number
79
t, // current token
80
eof = N <= 0, // current token followed by EOF?
81
eol = false; // current token followed by EOL?
82
83
// Strip the trailing newline.
84
if (text.charCodeAt(N - 1) === NEWLINE) --N;
85
if (text.charCodeAt(N - 1) === RETURN) --N;
86
87
function token() {
88
if (eof) return EOF;
89
if (eol) return eol = false, EOL;
90
91
// Unescape quotes.
92
var i, j = I, c;
93
if (text.charCodeAt(j) === QUOTE) {
94
while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
95
if ((i = I) >= N) eof = true;
96
else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
97
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
98
return text.slice(j + 1, i - 1).replace(/""/g, "\"");
99
}
100
101
// Find next delimiter or newline.
102
while (I < N) {
103
if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
104
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
105
else if (c !== DELIMITER) continue;
106
return text.slice(j, i);
107
}
108
109
// Return last token before EOF.
110
return eof = true, text.slice(j, N);
111
}
112
113
while ((t = token()) !== EOF) {
114
var row = [];
115
while (t !== EOL && t !== EOF) row.push(t), t = token();
116
if (f && (row = f(row, n++)) == null) continue;
117
rows.push(row);
118
}
119
120
return rows;
121
}
122
123
function preformatBody(rows, columns) {
124
return rows.map(function(row) {
125
return columns.map(function(column) {
126
return formatValue(row[column]);
127
}).join(delimiter);
128
});
129
}
130
131
function format(rows, columns) {
132
if (columns == null) columns = inferColumns(rows);
133
return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join("\n");
134
}
135
136
function formatBody(rows, columns) {
137
if (columns == null) columns = inferColumns(rows);
138
return preformatBody(rows, columns).join("\n");
139
}
140
141
function formatRows(rows) {
142
return rows.map(formatRow).join("\n");
143
}
144
145
function formatRow(row) {
146
return row.map(formatValue).join(delimiter);
147
}
148
149
function formatValue(value) {
150
return value == null ? ""
151
: value instanceof Date ? formatDate$2(value)
152
: reFormat.test(value += "") ? "\"" + value.replace(/"/g, "\"\"") + "\""
153
: value;
154
}
155
156
return {
157
parse: parse,
158
parseRows: parseRows,
159
format: format,
160
formatBody: formatBody,
161
formatRows: formatRows,
162
formatRow: formatRow,
163
formatValue: formatValue
164
};
165
}
166
167
var csv = dsv$1(",");
168
169
var csvParse = csv.parse;
170
var csvParseRows = csv.parseRows;
171
172
var tsv = dsv$1("\t");
173
174
var tsvParse = tsv.parse;
175
var tsvParseRows = tsv.parseRows;
176
177
function autoType(object) {
178
for (var key in object) {
179
var value = object[key].trim(), number, m;
180
if (!value) value = null;
181
else if (value === "true") value = true;
182
else if (value === "false") value = false;
183
else if (value === "NaN") value = NaN;
184
else if (!isNaN(number = +value)) value = number;
185
else if (m = value.match(/^([-+]\d{2})?\d{4}(-\d{2}(-\d{2})?)?(T\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/)) {
186
if (fixtz && !!m[4] && !m[7]) value = value.replace(/-/g, "/").replace(/T/, " ");
187
value = new Date(value);
188
}
189
else continue;
190
object[key] = value;
191
}
192
return object;
193
}
194
195
// https://github.com/d3/d3-dsv/issues/45
196
const fixtz = new Date("2019-01-01T00:00").getHours() || new Date("2019-07-01T00:00").getHours();
197
198
function dependency(name, version, main) {
199
return {
200
resolve(path = main) {
201
return `${name}@${version}/${path}`;
202
}
203
};
204
}
205
206
const d3 = dependency("d3", "7.8.5", "dist/d3.min.js");
207
const inputs = dependency("@observablehq/inputs", "0.10.6", "dist/inputs.min.js");
208
const plot = dependency("@observablehq/plot", "0.6.11", "dist/plot.umd.min.js");
209
const graphviz = dependency("@observablehq/graphviz", "0.2.1", "dist/graphviz.min.js");
210
const highlight = dependency("@observablehq/highlight.js", "2.0.0", "highlight.min.js");
211
const katex = dependency("@observablehq/katex", "0.11.1", "dist/katex.min.js");
212
const lodash = dependency("lodash", "4.17.21", "lodash.min.js");
213
const htl = dependency("htl", "0.3.1", "dist/htl.min.js");
214
const jszip = dependency("jszip", "3.10.1", "dist/jszip.min.js");
215
const marked = dependency("marked", "0.3.12", "marked.min.js");
216
const sql = dependency("sql.js", "1.8.0", "dist/sql-wasm.js");
217
const vega = dependency("vega", "5.22.1", "build/vega.min.js");
218
const vegalite = dependency("vega-lite", "5.6.0", "build/vega-lite.min.js");
219
const vegaliteApi = dependency("vega-lite-api", "5.0.0", "build/vega-lite-api.min.js");
220
const arrow4 = dependency("apache-arrow", "4.0.1", "Arrow.es2015.min.js");
221
const arrow9 = dependency("apache-arrow", "9.0.0", "+esm");
222
const arrow11 = dependency("apache-arrow", "11.0.0", "+esm");
223
const arquero = dependency("arquero", "4.8.8", "dist/arquero.min.js");
224
const topojson = dependency("topojson-client", "3.1.0", "dist/topojson-client.min.js");
225
const exceljs = dependency("exceljs", "4.3.0", "dist/exceljs.min.js");
226
const mermaid$1 = dependency("mermaid", "9.2.2", "dist/mermaid.min.js");
227
const leaflet$1 = dependency("leaflet", "1.9.3", "dist/leaflet.js");
228
const duckdb = dependency("@duckdb/duckdb-wasm", "1.24.0", "+esm");
229
230
const metas = new Map;
231
const queue$1 = [];
232
const map$2 = queue$1.map;
233
const some = queue$1.some;
234
const hasOwnProperty$2 = queue$1.hasOwnProperty;
235
const identifierRe = /^((?:@[^/@]+\/)?[^/@]+)(?:@([^/]+))?(?:\/(.*))?$/;
236
const versionRe = /^\d+\.\d+\.\d+(-[\w-.+]+)?$/;
237
const extensionRe = /(?:\.[^/]*|\/)$/;
238
239
class RequireError extends Error {
240
constructor(message) {
241
super(message);
242
}
243
}
244
245
RequireError.prototype.name = RequireError.name;
246
247
function parseIdentifier(identifier) {
248
const match = identifierRe.exec(identifier);
249
return match && {
250
name: match[1],
251
version: match[2],
252
path: match[3]
253
};
254
}
255
256
function resolveFrom(origin = "https://cdn.jsdelivr.net/npm/", mains = ["unpkg", "jsdelivr", "browser", "main"]) {
257
if (!/\/$/.test(origin)) throw new Error("origin lacks trailing slash");
258
259
function main(meta) {
260
for (const key of mains) {
261
let value = meta[key];
262
if (typeof value === "string") {
263
if (value.startsWith("./")) value = value.slice(2);
264
return extensionRe.test(value) ? value : `${value}.js`;
265
}
266
}
267
}
268
269
function resolveMeta(target) {
270
const url = `${origin}${target.name}${target.version ? `@${target.version}` : ""}/package.json`;
271
let meta = metas.get(url);
272
if (!meta) metas.set(url, meta = fetch(url).then(response => {
273
if (!response.ok) throw new RequireError("unable to load package.json");
274
if (response.redirected && !metas.has(response.url)) metas.set(response.url, meta);
275
return response.json();
276
}));
277
return meta;
278
}
279
280
return async function resolve(name, base) {
281
if (name.startsWith(origin)) name = name.substring(origin.length);
282
if (/^(\w+:)|\/\//i.test(name)) return name;
283
if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href;
284
if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new RequireError("illegal name");
285
const target = parseIdentifier(name);
286
if (!target) return `${origin}${name}`;
287
if (!target.version && base != null && base.startsWith(origin)) {
288
const meta = await resolveMeta(parseIdentifier(base.substring(origin.length)));
289
target.version = meta.dependencies && meta.dependencies[target.name] || meta.peerDependencies && meta.peerDependencies[target.name];
290
}
291
if (target.path && !extensionRe.test(target.path)) target.path += ".js";
292
if (target.path && target.version && versionRe.test(target.version)) return `${origin}${target.name}@${target.version}/${target.path}`;
293
const meta = await resolveMeta(target);
294
return `${origin}${meta.name}@${meta.version}/${target.path || main(meta) || "index.js"}`;
295
};
296
}
297
298
var require = requireFrom(resolveFrom());
299
let requestsInFlight = 0;
300
let prevDefine = undefined;
301
302
function requireFrom(resolver) {
303
const cache = new Map;
304
const requireBase = requireRelative(null);
305
306
function requireAbsolute(url) {
307
if (typeof url !== "string") return url;
308
let module = cache.get(url);
309
if (!module) cache.set(url, module = new Promise((resolve, reject) => {
310
const script = document.createElement("script");
311
script.onload = () => {
312
try { resolve(queue$1.pop()(requireRelative(url))); }
313
catch (error) { reject(new RequireError("invalid module")); }
314
script.remove();
315
requestsInFlight--;
316
if (requestsInFlight === 0) {
317
window.define = prevDefine;
318
}
319
};
320
script.onerror = () => {
321
reject(new RequireError("unable to load module"));
322
script.remove();
323
requestsInFlight--;
324
if (requestsInFlight === 0) {
325
window.define = prevDefine;
326
}
327
};
328
script.async = true;
329
script.src = url;
330
if (requestsInFlight === 0) {
331
prevDefine = window.define;
332
window.define = define;
333
}
334
requestsInFlight++;
335
336
document.head.appendChild(script);
337
}));
338
return module;
339
}
340
341
function requireRelative(base) {
342
return name => Promise.resolve(resolver(name, base)).then(requireAbsolute);
343
}
344
345
function requireAlias(aliases) {
346
return requireFrom((name, base) => {
347
if (name in aliases) {
348
name = aliases[name], base = null;
349
if (typeof name !== "string") return name;
350
}
351
return resolver(name, base);
352
});
353
}
354
355
function require(name) {
356
return arguments.length > 1
357
? Promise.all(map$2.call(arguments, requireBase)).then(merge$1)
358
: requireBase(name);
359
}
360
361
require.alias = requireAlias;
362
require.resolve = resolver;
363
364
return require;
365
}
366
367
function merge$1(modules) {
368
const o = {};
369
for (const m of modules) {
370
for (const k in m) {
371
if (hasOwnProperty$2.call(m, k)) {
372
if (m[k] == null) Object.defineProperty(o, k, {get: getter(m, k)});
373
else o[k] = m[k];
374
}
375
}
376
}
377
return o;
378
}
379
380
function getter(object, name) {
381
return () => object[name];
382
}
383
384
function isbuiltin(name) {
385
name = name + "";
386
return name === "exports" || name === "module";
387
}
388
389
function define(name, dependencies, factory) {
390
const n = arguments.length;
391
if (n < 2) factory = name, dependencies = [];
392
else if (n < 3) factory = dependencies, dependencies = typeof name === "string" ? [] : name;
393
queue$1.push(some.call(dependencies, isbuiltin) ? require => {
394
const exports = {};
395
const module = {exports};
396
return Promise.all(map$2.call(dependencies, name => {
397
name = name + "";
398
return name === "exports" ? exports : name === "module" ? module : require(name);
399
})).then(dependencies => {
400
factory.apply(null, dependencies);
401
return module.exports;
402
});
403
} : require => {
404
return Promise.all(map$2.call(dependencies, require)).then(dependencies => {
405
return typeof factory === "function" ? factory.apply(null, dependencies) : factory;
406
});
407
});
408
}
409
410
define.amd = {};
411
412
// TODO Allow this to be overridden using the Library’s resolver.
413
const cdn = "https://cdn.observableusercontent.com/npm/";
414
415
let requireDefault = require;
416
417
function setDefaultRequire(require) {
418
requireDefault = require;
419
}
420
421
function requirer(resolver) {
422
return resolver == null ? requireDefault : requireFrom(resolver);
423
}
424
425
function fromEntries(obj) {
426
const result = {};
427
for (const [key, value] of obj) {
428
result[key] = value;
429
}
430
return result;
431
}
432
433
async function SQLite(require) {
434
const [init, dist] = await Promise.all([require(sql.resolve()), require.resolve(sql.resolve("dist/"))]);
435
return init({locateFile: file => `${dist}${file}`});
436
}
437
438
class SQLiteDatabaseClient {
439
constructor(db) {
440
Object.defineProperties(this, {
441
_db: {value: db}
442
});
443
}
444
static async open(source) {
445
const [SQL, buffer] = await Promise.all([SQLite(requireDefault), Promise.resolve(source).then(load$1)]);
446
return new SQLiteDatabaseClient(new SQL.Database(buffer));
447
}
448
async query(query, params) {
449
return await exec(this._db, query, params);
450
}
451
async queryRow(query, params) {
452
return (await this.query(query, params))[0] || null;
453
}
454
async explain(query, params) {
455
const rows = await this.query(`EXPLAIN QUERY PLAN ${query}`, params);
456
return element$1("pre", {className: "observablehq--inspect"}, [
457
text$2(rows.map(row => row.detail).join("\n"))
458
]);
459
}
460
async describeTables({schema} = {}) {
461
return this.query(`SELECT NULLIF(schema, 'main') AS schema, name FROM pragma_table_list() WHERE type = 'table'${schema == null ? "" : ` AND schema = ?`} AND name NOT LIKE 'sqlite_%' ORDER BY schema, name`, schema == null ? [] : [schema]);
462
}
463
async describeColumns({schema, table} = {}) {
464
if (table == null) throw new Error(`missing table`);
465
const rows = await this.query(`SELECT name, type, "notnull" FROM pragma_table_info(?${schema == null ? "" : `, ?`}) ORDER BY cid`, schema == null ? [table] : [table, schema]);
466
if (!rows.length) throw new Error(`table not found: ${table}`);
467
return rows.map(({name, type, notnull}) => ({name, type: sqliteType(type), databaseType: type, nullable: !notnull}));
468
}
469
async describe(object) {
470
const rows = await (object === undefined
471
? this.query(`SELECT name FROM sqlite_master WHERE type = 'table'`)
472
: this.query(`SELECT * FROM pragma_table_info(?)`, [object]));
473
if (!rows.length) throw new Error("Not found");
474
const {columns} = rows;
475
return element$1("table", {value: rows}, [
476
element$1("thead", [element$1("tr", columns.map(c => element$1("th", [text$2(c)])))]),
477
element$1("tbody", rows.map(r => element$1("tr", columns.map(c => element$1("td", [text$2(r[c])])))))
478
]);
479
}
480
async sql() {
481
return this.query(...this.queryTag.apply(this, arguments));
482
}
483
queryTag(strings, ...params) {
484
return [strings.join("?"), params];
485
}
486
}
487
488
Object.defineProperty(SQLiteDatabaseClient.prototype, "dialect", {
489
value: "sqlite"
490
});
491
492
// https://www.sqlite.org/datatype3.html
493
function sqliteType(type) {
494
switch (type) {
495
case "NULL":
496
return "null";
497
case "INT":
498
case "INTEGER":
499
case "TINYINT":
500
case "SMALLINT":
501
case "MEDIUMINT":
502
case "BIGINT":
503
case "UNSIGNED BIG INT":
504
case "INT2":
505
case "INT8":
506
return "integer";
507
case "TEXT":
508
case "CLOB":
509
return "string";
510
case "REAL":
511
case "DOUBLE":
512
case "DOUBLE PRECISION":
513
case "FLOAT":
514
case "NUMERIC":
515
return "number";
516
case "BLOB":
517
return "buffer";
518
case "DATE":
519
case "DATETIME":
520
return "string"; // TODO convert strings to Date instances in sql.js
521
default:
522
return /^(?:(?:(?:VARYING|NATIVE) )?CHARACTER|(?:N|VAR|NVAR)CHAR)\(/.test(type) ? "string"
523
: /^(?:DECIMAL|NUMERIC)\(/.test(type) ? "number"
524
: "other";
525
}
526
}
527
528
function load$1(source) {
529
return typeof source === "string" ? fetch(source).then(load$1)
530
: source instanceof Response || source instanceof Blob ? source.arrayBuffer().then(load$1)
531
: source instanceof ArrayBuffer ? new Uint8Array(source)
532
: source;
533
}
534
535
async function exec(db, query, params) {
536
const [result] = await db.exec(query, params);
537
if (!result) return [];
538
const {columns, values} = result;
539
const rows = values.map(row => fromEntries(row.map((value, i) => [columns[i], value])));
540
rows.columns = columns;
541
return rows;
542
}
543
544
function element$1(name, props, children) {
545
if (arguments.length === 2) children = props, props = undefined;
546
const element = document.createElement(name);
547
if (props !== undefined) for (const p in props) element[p] = props[p];
548
if (children !== undefined) for (const c of children) element.appendChild(c);
549
return element;
550
}
551
552
function text$2(value) {
553
return document.createTextNode(value);
554
}
555
556
function ascending(a, b) {
557
return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
558
}
559
560
function descending(a, b) {
561
return a == null || b == null ? NaN
562
: b < a ? -1
563
: b > a ? 1
564
: b >= a ? 0
565
: NaN;
566
}
567
568
function bisector(f) {
569
let compare1, compare2, delta;
570
571
// If an accessor is specified, promote it to a comparator. In this case we
572
// can test whether the search value is (self-) comparable. We can’t do this
573
// for a comparator (except for specific, known comparators) because we can’t
574
// tell if the comparator is symmetric, and an asymmetric comparator can’t be
575
// used to test whether a single value is comparable.
576
if (f.length !== 2) {
577
compare1 = ascending;
578
compare2 = (d, x) => ascending(f(d), x);
579
delta = (d, x) => f(d) - x;
580
} else {
581
compare1 = f === ascending || f === descending ? f : zero;
582
compare2 = f;
583
delta = f;
584
}
585
586
function left(a, x, lo = 0, hi = a.length) {
587
if (lo < hi) {
588
if (compare1(x, x) !== 0) return hi;
589
do {
590
const mid = (lo + hi) >>> 1;
591
if (compare2(a[mid], x) < 0) lo = mid + 1;
592
else hi = mid;
593
} while (lo < hi);
594
}
595
return lo;
596
}
597
598
function right(a, x, lo = 0, hi = a.length) {
599
if (lo < hi) {
600
if (compare1(x, x) !== 0) return hi;
601
do {
602
const mid = (lo + hi) >>> 1;
603
if (compare2(a[mid], x) <= 0) lo = mid + 1;
604
else hi = mid;
605
} while (lo < hi);
606
}
607
return lo;
608
}
609
610
function center(a, x, lo = 0, hi = a.length) {
611
const i = left(a, x, lo, hi - 1);
612
return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;
613
}
614
615
return {left, center, right};
616
}
617
618
function zero() {
619
return 0;
620
}
621
622
function number(x) {
623
return x === null ? NaN : +x;
624
}
625
626
bisector(ascending);
627
bisector(number).center;
628
629
function greatest(values, compare = ascending) {
630
let max;
631
let defined = false;
632
if (compare.length === 1) {
633
let maxValue;
634
for (const element of values) {
635
const value = compare(element);
636
if (defined
637
? ascending(value, maxValue) > 0
638
: ascending(value, value) === 0) {
639
max = element;
640
maxValue = value;
641
defined = true;
642
}
643
}
644
} else {
645
for (const value of values) {
646
if (defined
647
? compare(value, max) > 0
648
: compare(value, value) === 0) {
649
max = value;
650
defined = true;
651
}
652
}
653
}
654
return max;
655
}
656
657
function reverse(values) {
658
if (typeof values[Symbol.iterator] !== "function") throw new TypeError("values is not iterable");
659
return Array.from(values).reverse();
660
}
661
662
function isArqueroTable(value) {
663
// Arquero tables have a `toArrowBuffer` function
664
return value && typeof value.toArrowBuffer === "function";
665
}
666
667
// Returns true if the vaue is an Apache Arrow table. This uses a “duck” test
668
// (instead of strict instanceof) because we want it to work with a range of
669
// Apache Arrow versions at least 7.0.0 or above.
670
// https://arrow.apache.org/docs/7.0/js/classes/Arrow_dom.Table.html
671
function isArrowTable(value) {
672
return (
673
value &&
674
typeof value.getChild === "function" &&
675
typeof value.toArray === "function" &&
676
value.schema &&
677
Array.isArray(value.schema.fields)
678
);
679
}
680
681
function getArrowTableSchema(table) {
682
return table.schema.fields.map(getArrowFieldSchema);
683
}
684
685
function getArrowFieldSchema(field) {
686
return {
687
name: field.name,
688
type: getArrowType(field.type),
689
nullable: field.nullable,
690
databaseType: String(field.type)
691
};
692
}
693
694
// https://github.com/apache/arrow/blob/89f9a0948961f6e94f1ef5e4f310b707d22a3c11/js/src/enum.ts#L140-L141
695
function getArrowType(type) {
696
switch (type.typeId) {
697
case 2: // Int
698
return "integer";
699
case 3: // Float
700
case 7: // Decimal
701
return "number";
702
case 4: // Binary
703
case 15: // FixedSizeBinary
704
return "buffer";
705
case 5: // Utf8
706
return "string";
707
case 6: // Bool
708
return "boolean";
709
case 8: // Date
710
case 9: // Time
711
case 10: // Timestamp
712
return "date";
713
case 12: // List
714
case 16: // FixedSizeList
715
return "array";
716
case 13: // Struct
717
case 14: // Union
718
return "object";
719
case 11: // Interval
720
case 17: // Map
721
default:
722
return "other";
723
}
724
}
725
726
async function loadArrow() {
727
return await import(`${cdn}${arrow11.resolve()}`);
728
}
729
730
// Adapted from https://observablehq.com/@cmudig/duckdb-client
731
// Copyright 2021 CMU Data Interaction Group
732
//
733
// Redistribution and use in source and binary forms, with or without
734
// modification, are permitted provided that the following conditions are met:
735
//
736
// 1. Redistributions of source code must retain the above copyright notice,
737
// this list of conditions and the following disclaimer.
738
//
739
// 2. Redistributions in binary form must reproduce the above copyright notice,
740
// this list of conditions and the following disclaimer in the documentation
741
// and/or other materials provided with the distribution.
742
//
743
// 3. Neither the name of the copyright holder nor the names of its contributors
744
// may be used to endorse or promote products derived from this software
745
// without specific prior written permission.
746
//
747
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
748
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
749
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
750
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
751
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
752
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
753
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
754
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
755
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
756
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
757
// POSSIBILITY OF SUCH DAMAGE.
758
759
let promise;
760
761
class DuckDBClient {
762
constructor(db) {
763
Object.defineProperties(this, {
764
_db: {value: db}
765
});
766
}
767
768
async queryStream(query, params) {
769
const connection = await this._db.connect();
770
let reader, batch;
771
try {
772
if (params?.length > 0) {
773
const statement = await connection.prepare(query);
774
reader = await statement.send(...params);
775
} else {
776
reader = await connection.send(query);
777
}
778
batch = await reader.next();
779
if (batch.done) throw new Error("missing first batch");
780
} catch (error) {
781
await connection.close();
782
throw error;
783
}
784
return {
785
schema: getArrowTableSchema(batch.value),
786
async *readRows() {
787
try {
788
while (!batch.done) {
789
yield batch.value.toArray();
790
batch = await reader.next();
791
}
792
} finally {
793
await connection.close();
794
}
795
}
796
};
797
}
798
799
async query(query, params) {
800
const result = await this.queryStream(query, params);
801
const results = [];
802
for await (const rows of result.readRows()) {
803
for (const row of rows) {
804
results.push(row);
805
}
806
}
807
results.schema = result.schema;
808
return results;
809
}
810
811
async queryRow(query, params) {
812
const result = await this.queryStream(query, params);
813
const reader = result.readRows();
814
try {
815
const {done, value} = await reader.next();
816
return done || !value.length ? null : value[0];
817
} finally {
818
await reader.return();
819
}
820
}
821
822
async sql(strings, ...args) {
823
return await this.query(strings.join("?"), args);
824
}
825
826
queryTag(strings, ...params) {
827
return [strings.join("?"), params];
828
}
829
830
escape(name) {
831
return `"${name}"`;
832
}
833
834
async describeTables() {
835
const tables = await this.query(`SHOW TABLES`);
836
return tables.map(({name}) => ({name}));
837
}
838
839
async describeColumns({table} = {}) {
840
const columns = await this.query(`DESCRIBE ${this.escape(table)}`);
841
return columns.map(({column_name, column_type, null: nullable}) => ({
842
name: column_name,
843
type: getDuckDBType(column_type),
844
nullable: nullable !== "NO",
845
databaseType: column_type
846
}));
847
}
848
849
static async of(sources = {}, config = {}) {
850
const db = await createDuckDB();
851
if (config.query?.castTimestampToDate === undefined) {
852
config = {...config, query: {...config.query, castTimestampToDate: true}};
853
}
854
if (config.query?.castBigIntToDouble === undefined) {
855
config = {...config, query: {...config.query, castBigIntToDouble: true}};
856
}
857
await db.open(config);
858
await Promise.all(
859
Object.entries(sources).map(async ([name, source]) => {
860
if (source instanceof FileAttachment) { // bare file
861
await insertFile(db, name, source);
862
} else if (isArrowTable(source)) { // bare arrow table
863
await insertArrowTable(db, name, source);
864
} else if (Array.isArray(source)) { // bare array of objects
865
await insertArray(db, name, source);
866
} else if (isArqueroTable(source)) {
867
await insertArqueroTable(db, name, source);
868
} else if ("data" in source) { // data + options
869
const {data, ...options} = source;
870
if (isArrowTable(data)) {
871
await insertArrowTable(db, name, data, options);
872
} else {
873
await insertArray(db, name, data, options);
874
}
875
} else if ("file" in source) { // file + options
876
const {file, ...options} = source;
877
await insertFile(db, name, file, options);
878
} else {
879
throw new Error(`invalid source: ${source}`);
880
}
881
})
882
);
883
return new DuckDBClient(db);
884
}
885
}
886
887
Object.defineProperty(DuckDBClient.prototype, "dialect", {
888
value: "duckdb"
889
});
890
891
async function insertFile(database, name, file, options) {
892
const url = await file.url();
893
if (url.startsWith("blob:")) {
894
const buffer = await file.arrayBuffer();
895
await database.registerFileBuffer(file.name, new Uint8Array(buffer));
896
} else {
897
await database.registerFileURL(file.name, url, 4); // duckdb.DuckDBDataProtocol.HTTP
898
}
899
const connection = await database.connect();
900
try {
901
switch (file.mimeType) {
902
case "text/csv":
903
case "text/tab-separated-values": {
904
return await connection.insertCSVFromPath(file.name, {
905
name,
906
schema: "main",
907
...options
908
}).catch(async (error) => {
909
// If initial attempt to insert CSV resulted in a conversion
910
// error, try again, this time treating all columns as strings.
911
if (error.toString().includes("Could not convert")) {
912
return await insertUntypedCSV(connection, file, name);
913
}
914
throw error;
915
});
916
}
917
case "application/json":
918
return await connection.insertJSONFromPath(file.name, {
919
name,
920
schema: "main",
921
...options
922
});
923
default:
924
if (/\.arrow$/i.test(file.name)) {
925
const buffer = new Uint8Array(await file.arrayBuffer());
926
return await connection.insertArrowFromIPCStream(buffer, {
927
name,
928
schema: "main",
929
...options
930
});
931
}
932
if (/\.parquet$/i.test(file.name)) {
933
return await connection.query(
934
`CREATE VIEW '${name}' AS SELECT * FROM parquet_scan('${file.name}')`
935
);
936
}
937
throw new Error(`unknown file type: ${file.mimeType}`);
938
}
939
} finally {
940
await connection.close();
941
}
942
}
943
944
async function insertUntypedCSV(connection, file, name) {
945
const statement = await connection.prepare(
946
`CREATE TABLE '${name}' AS SELECT * FROM read_csv_auto(?, ALL_VARCHAR=TRUE)`
947
);
948
return await statement.send(file.name);
949
}
950
951
async function insertArrowTable(database, name, table, options) {
952
const connection = await database.connect();
953
try {
954
await connection.insertArrowTable(table, {
955
name,
956
schema: "main",
957
...options
958
});
959
} finally {
960
await connection.close();
961
}
962
}
963
964
async function insertArqueroTable(database, name, source) {
965
// TODO When we have stdlib versioning and can upgrade Arquero to version 5,
966
// we can then call source.toArrow() directly, with insertArrowTable()
967
const arrow = await loadArrow();
968
const table = arrow.tableFromIPC(source.toArrowBuffer());
969
return await insertArrowTable(database, name, table);
970
}
971
972
async function insertArray(database, name, array, options) {
973
const arrow = await loadArrow();
974
const table = arrow.tableFromJSON(array);
975
return await insertArrowTable(database, name, table, options);
976
}
977
978
async function loadDuckDB() {
979
const module = await import(`${cdn}${duckdb.resolve()}`);
980
const bundle = await module.selectBundle({
981
mvp: {
982
mainModule: `${cdn}${duckdb.resolve("dist/duckdb-mvp.wasm")}`,
983
mainWorker: `${cdn}${duckdb.resolve("dist/duckdb-browser-mvp.worker.js")}`
984
},
985
eh: {
986
mainModule: `${cdn}${duckdb.resolve("dist/duckdb-eh.wasm")}`,
987
mainWorker: `${cdn}${duckdb.resolve("dist/duckdb-browser-eh.worker.js")}`
988
}
989
});
990
const logger = new module.ConsoleLogger();
991
return {module, bundle, logger};
992
}
993
994
async function createDuckDB() {
995
if (promise === undefined) promise = loadDuckDB();
996
const {module, bundle, logger} = await promise;
997
const worker = await module.createWorker(bundle.mainWorker);
998
const db = new module.AsyncDuckDB(logger, worker);
999
await db.instantiate(bundle.mainModule);
1000
return db;
1001
}
1002
1003
// https://duckdb.org/docs/sql/data_types/overview
1004
function getDuckDBType(type) {
1005
switch (type) {
1006
case "BIGINT":
1007
case "HUGEINT":
1008
case "UBIGINT":
1009
return "bigint";
1010
case "DOUBLE":
1011
case "REAL":
1012
case "FLOAT":
1013
return "number";
1014
case "INTEGER":
1015
case "SMALLINT":
1016
case "TINYINT":
1017
case "USMALLINT":
1018
case "UINTEGER":
1019
case "UTINYINT":
1020
return "integer";
1021
case "BOOLEAN":
1022
return "boolean";
1023
case "DATE":
1024
case "TIMESTAMP":
1025
case "TIMESTAMP WITH TIME ZONE":
1026
return "date";
1027
case "VARCHAR":
1028
case "UUID":
1029
return "string";
1030
// case "BLOB":
1031
// case "INTERVAL":
1032
// case "TIME":
1033
default:
1034
if (/^DECIMAL\(/.test(type)) return "integer";
1035
return "other";
1036
}
1037
}
1038
1039
const nChecks = 20; // number of values to check in each array
1040
1041
// We support two levels of DatabaseClient. The simplest DatabaseClient
1042
// implements only the client.sql tagged template literal. More advanced
1043
// DatabaseClients implement client.query and client.queryStream, which support
1044
// streaming and abort, and the client.queryTag tagged template literal is used
1045
// to translate the contents of a SQL cell or Table cell into the appropriate
1046
// arguments for calling client.query or client.queryStream. For table cells, we
1047
// additionally require client.describeColumns. The client.describeTables method
1048
// is optional.
1049
function isDatabaseClient(value, mode) {
1050
return (
1051
value &&
1052
(typeof value.sql === "function" ||
1053
(typeof value.queryTag === "function" &&
1054
(typeof value.query === "function" ||
1055
typeof value.queryStream === "function"))) &&
1056
(mode !== "table" || typeof value.describeColumns === "function") &&
1057
value !== __query // don’t match our internal helper
1058
);
1059
}
1060
1061
// Returns true if the value is a typed array (for a single-column table), or if
1062
// it’s an array. In the latter case, the elements of the array must be
1063
// consistently typed: either plain objects or primitives or dates.
1064
function isDataArray(value) {
1065
return (
1066
(Array.isArray(value) &&
1067
(isQueryResultSetSchema(value.schema) ||
1068
isQueryResultSetColumns(value.columns) ||
1069
arrayContainsObjects(value) ||
1070
arrayContainsPrimitives(value) ||
1071
arrayContainsDates(value))) ||
1072
isTypedArray(value)
1073
);
1074
}
1075
1076
// Given an array, checks that the given value is an array that does not contain
1077
// any primitive values (at least for the first few values that we check), and
1078
// that the first object contains enumerable keys (see computeSchema for how we
1079
// infer the columns). We assume that the contents of the table are homogenous,
1080
// but we don’t currently enforce this.
1081
// https://observablehq.com/@observablehq/database-client-specification#§1
1082
function arrayContainsObjects(value) {
1083
const n = Math.min(nChecks, value.length);
1084
for (let i = 0; i < n; ++i) {
1085
const v = value[i];
1086
if (v === null || typeof v !== "object") return false;
1087
}
1088
return n > 0 && objectHasEnumerableKeys(value[0]);
1089
}
1090
1091
// Using a for-in loop here means that we can abort after finding at least one
1092
// enumerable key (whereas Object.keys would require materializing the array of
1093
// all keys, which would be considerably slower if the value has many keys!).
1094
// This function assumes that value is an object; see arrayContainsObjects.
1095
function objectHasEnumerableKeys(value) {
1096
for (const _ in value) return true;
1097
return false;
1098
}
1099
1100
function isQueryResultSetSchema(schemas) {
1101
return (
1102
Array.isArray(schemas) &&
1103
schemas.every(isColumnSchema)
1104
);
1105
}
1106
1107
function isQueryResultSetColumns(columns) {
1108
return (Array.isArray(columns) && columns.every((name) => typeof name === "string"));
1109
}
1110
1111
function isColumnSchema(schema) {
1112
return schema && typeof schema.name === "string" && typeof schema.type === "string";
1113
}
1114
1115
// Returns true if the value represents an array of primitives (i.e., a
1116
// single-column table). This should only be passed values for which
1117
// isDataArray returns true.
1118
function arrayIsPrimitive(value) {
1119
return (
1120
isTypedArray(value) ||
1121
arrayContainsPrimitives(value) ||
1122
arrayContainsDates(value)
1123
);
1124
}
1125
1126
// Given an array, checks that the first n elements are primitives (number,
1127
// string, boolean, bigint) of a consistent type.
1128
function arrayContainsPrimitives(value) {
1129
const n = Math.min(nChecks, value.length);
1130
if (!(n > 0)) return false;
1131
let type;
1132
let hasPrimitive = false; // ensure we encounter 1+ primitives
1133
for (let i = 0; i < n; ++i) {
1134
const v = value[i];
1135
if (v == null) continue; // ignore null and undefined
1136
const t = typeof v;
1137
if (type === undefined) {
1138
switch (t) {
1139
case "number":
1140
case "boolean":
1141
case "string":
1142
case "bigint":
1143
type = t;
1144
break;
1145
default:
1146
return false;
1147
}
1148
} else if (t !== type) {
1149
return false;
1150
}
1151
hasPrimitive = true;
1152
}
1153
return hasPrimitive;
1154
}
1155
1156
// Given an array, checks that the first n elements are dates.
1157
function arrayContainsDates(value) {
1158
const n = Math.min(nChecks, value.length);
1159
if (!(n > 0)) return false;
1160
let hasDate = false; // ensure we encounter 1+ dates
1161
for (let i = 0; i < n; ++i) {
1162
const v = value[i];
1163
if (v == null) continue; // ignore null and undefined
1164
if (!(v instanceof Date)) return false;
1165
hasDate = true;
1166
}
1167
return hasDate;
1168
}
1169
1170
function isTypedArray(value) {
1171
return (
1172
value instanceof Int8Array ||
1173
value instanceof Int16Array ||
1174
value instanceof Int32Array ||
1175
value instanceof Uint8Array ||
1176
value instanceof Uint8ClampedArray ||
1177
value instanceof Uint16Array ||
1178
value instanceof Uint32Array ||
1179
value instanceof Float32Array ||
1180
value instanceof Float64Array
1181
);
1182
}
1183
1184
// __query is used by table cells; __query.sql is used by SQL cells.
1185
const __query = Object.assign(
1186
async (source, operations, invalidation, name) => {
1187
source = await loadTableDataSource(await source, name);
1188
if (isDatabaseClient(source)) return evaluateQuery(source, makeQueryTemplate(operations, source), invalidation);
1189
if (isDataArray(source)) return __table(source, operations);
1190
if (!source) throw new Error("missing data source");
1191
throw new Error("invalid data source");
1192
},
1193
{
1194
sql(source, invalidation, name) {
1195
return async function () {
1196
return evaluateQuery(await loadSqlDataSource(await source, name), arguments, invalidation);
1197
};
1198
}
1199
}
1200
);
1201
1202
// We use a weak map to cache loaded data sources by key so that we don’t have
1203
// to e.g. create separate SQLiteDatabaseClients every time we’re querying the
1204
// same SQLite file attachment. Since this is a weak map, unused references will
1205
// be garbage collected when they are no longer desired. Note: the name should
1206
// be consistent, as it is not part of the cache key!
1207
function sourceCache(loadSource) {
1208
const cache = new WeakMap();
1209
return (source, name) => {
1210
if (!source || typeof source !== "object") throw new Error("invalid data source");
1211
let promise = cache.get(source);
1212
if (!promise || (isDataArray(source) && source.length !== promise._numRows)) {
1213
// Warning: do not await here! We need to populate the cache synchronously.
1214
promise = loadSource(source, name);
1215
promise._numRows = source.length; // This will be undefined for DatabaseClients
1216
cache.set(source, promise);
1217
}
1218
return promise;
1219
};
1220
}
1221
1222
const loadTableDataSource = sourceCache(async (source, name) => {
1223
if (source instanceof FileAttachment) {
1224
switch (source.mimeType) {
1225
case "text/csv": return source.csv();
1226
case "text/tab-separated-values": return source.tsv();
1227
case "application/json": return source.json();
1228
case "application/x-sqlite3": return source.sqlite();
1229
}
1230
if (/\.(arrow|parquet)$/i.test(source.name)) return loadDuckDBClient(source, name);
1231
throw new Error(`unsupported file type: ${source.mimeType}`);
1232
}
1233
if (isArrowTable(source) || isArqueroTable(source)) return loadDuckDBClient(source, name);
1234
if (isDataArray(source) && arrayIsPrimitive(source))
1235
return Array.from(source, (value) => ({value}));
1236
return source;
1237
});
1238
1239
const loadSqlDataSource = sourceCache(async (source, name) => {
1240
if (source instanceof FileAttachment) {
1241
switch (source.mimeType) {
1242
case "text/csv":
1243
case "text/tab-separated-values":
1244
case "application/json": return loadDuckDBClient(source, name);
1245
case "application/x-sqlite3": return source.sqlite();
1246
}
1247
if (/\.(arrow|parquet)$/i.test(source.name)) return loadDuckDBClient(source, name);
1248
throw new Error(`unsupported file type: ${source.mimeType}`);
1249
}
1250
if (isDataArray(source)) return loadDuckDBClient(await asArrowTable(source, name), name);
1251
if (isArrowTable(source) || isArqueroTable(source)) return loadDuckDBClient(source, name);
1252
return source;
1253
});
1254
1255
async function asArrowTable(array, name) {
1256
const arrow = await loadArrow();
1257
return arrayIsPrimitive(array)
1258
? arrow.tableFromArrays({[name]: array})
1259
: arrow.tableFromJSON(array);
1260
}
1261
1262
function loadDuckDBClient(
1263
source,
1264
name = source instanceof FileAttachment
1265
? getFileSourceName(source)
1266
: "__table"
1267
) {
1268
return DuckDBClient.of({[name]: source});
1269
}
1270
1271
function getFileSourceName(file) {
1272
return file.name
1273
.replace(/@\d+(?=\.|$)/, "") // strip Observable file version number
1274
.replace(/\.\w+$/, ""); // strip file extension
1275
}
1276
1277
async function evaluateQuery(source, args, invalidation) {
1278
if (!source) throw new Error("missing data source");
1279
1280
// If this DatabaseClient supports abort and streaming, use that.
1281
if (typeof source.queryTag === "function") {
1282
const abortController = new AbortController();
1283
const options = {signal: abortController.signal};
1284
invalidation.then(() => abortController.abort("invalidated"));
1285
if (typeof source.queryStream === "function") {
1286
return accumulateQuery(
1287
source.queryStream(...source.queryTag.apply(source, args), options)
1288
);
1289
}
1290
if (typeof source.query === "function") {
1291
return source.query(...source.queryTag.apply(source, args), options);
1292
}
1293
}
1294
1295
// Otherwise, fallback to the basic sql tagged template literal.
1296
if (typeof source.sql === "function") {
1297
return source.sql.apply(source, args);
1298
}
1299
1300
// TODO: test if source is a file attachment, and support CSV etc.
1301
throw new Error("source does not implement query, queryStream, or sql");
1302
}
1303
1304
// Generator function that yields accumulated query results client.queryStream
1305
async function* accumulateQuery(queryRequest) {
1306
let then = performance.now();
1307
const queryResponse = await queryRequest;
1308
const values = [];
1309
values.done = false;
1310
values.error = null;
1311
values.schema = queryResponse.schema;
1312
try {
1313
for await (const rows of queryResponse.readRows()) {
1314
if (performance.now() - then > 150 && values.length > 0) {
1315
yield values;
1316
then = performance.now();
1317
}
1318
for (const value of rows) {
1319
values.push(value);
1320
}
1321
}
1322
values.done = true;
1323
yield values;
1324
} catch (error) {
1325
values.error = error;
1326
yield values;
1327
}
1328
}
1329
1330
/**
1331
* Returns a SQL query in the form [[parts], ...params] where parts is an array
1332
* of sub-strings and params are the parameter values to be inserted between each
1333
* sub-string.
1334
*/
1335
function makeQueryTemplate(operations, source) {
1336
const escaper =
1337
typeof source.escape === "function" ? source.escape : (i) => i;
1338
const {select, from, filter, sort, slice} = operations;
1339
if (!from.table)
1340
throw new Error("missing from table");
1341
if (select.columns && select.columns.length === 0)
1342
throw new Error("at least one column must be selected");
1343
const names = new Map(operations.names?.map(({column, name}) => [column, name]));
1344
const columns = select.columns ? select.columns.map((column) => {
1345
const override = names.get(column);
1346
return override ? `${escaper(column)} AS ${escaper(override)}` : escaper(column);
1347
}).join(", ") : "*";
1348
const args = [
1349
[`SELECT ${columns} FROM ${formatTable(from.table, escaper)}`]
1350
];
1351
for (let i = 0; i < filter.length; ++i) {
1352
appendSql(i ? `\nAND ` : `\nWHERE `, args);
1353
appendWhereEntry(filter[i], args, escaper);
1354
}
1355
for (let i = 0; i < sort.length; ++i) {
1356
appendSql(i ? `, ` : `\nORDER BY `, args);
1357
appendOrderBy(sort[i], args, escaper);
1358
}
1359
if (source.dialect === "mssql" || source.dialect === "oracle") {
1360
if (slice.to !== null || slice.from !== null) {
1361
if (!sort.length) {
1362
if (!select.columns)
1363
throw new Error(
1364
"at least one column must be explicitly specified. Received '*'."
1365
);
1366
appendSql(`\nORDER BY `, args);
1367
appendOrderBy(
1368
{column: select.columns[0], direction: "ASC"},
1369
args,
1370
escaper
1371
);
1372
}
1373
appendSql(`\nOFFSET ${slice.from || 0} ROWS`, args);
1374
appendSql(
1375
`\nFETCH NEXT ${
1376
slice.to !== null ? slice.to - (slice.from || 0) : 1e9
1377
} ROWS ONLY`,
1378
args
1379
);
1380
}
1381
} else {
1382
if (slice.to !== null || slice.from !== null) {
1383
appendSql(
1384
`\nLIMIT ${slice.to !== null ? slice.to - (slice.from || 0) : 1e9}`,
1385
args
1386
);
1387
}
1388
if (slice.from !== null) {
1389
appendSql(` OFFSET ${slice.from}`, args);
1390
}
1391
}
1392
return args;
1393
}
1394
1395
function formatTable(table, escaper) {
1396
if (typeof table === "object") { // i.e., not a bare string specifier
1397
let from = "";
1398
if (table.database != null) from += escaper(table.database) + ".";
1399
if (table.schema != null) from += escaper(table.schema) + ".";
1400
from += escaper(table.table);
1401
return from;
1402
} else {
1403
return escaper(table);
1404
}
1405
}
1406
1407
function appendSql(sql, args) {
1408
const strings = args[0];
1409
strings[strings.length - 1] += sql;
1410
}
1411
1412
function appendOrderBy({column, direction}, args, escaper) {
1413
appendSql(`${escaper(column)} ${direction.toUpperCase()}`, args);
1414
}
1415
1416
function appendWhereEntry({type, operands}, args, escaper) {
1417
if (operands.length < 1) throw new Error("Invalid operand length");
1418
1419
// Unary operations
1420
// We treat `v` and `nv` as `NULL` and `NOT NULL` unary operations in SQL,
1421
// since the database already validates column types.
1422
if (operands.length === 1 || type === "v" || type === "nv") {
1423
appendOperand(operands[0], args, escaper);
1424
switch (type) {
1425
case "n":
1426
case "nv":
1427
appendSql(` IS NULL`, args);
1428
return;
1429
case "nn":
1430
case "v":
1431
appendSql(` IS NOT NULL`, args);
1432
return;
1433
default:
1434
throw new Error("Invalid filter operation");
1435
}
1436
}
1437
1438
// Binary operations
1439
if (operands.length === 2) {
1440
if (["in", "nin"].includes(type)) ; else if (["c", "nc"].includes(type)) {
1441
// TODO: Case (in)sensitive?
1442
appendOperand(operands[0], args, escaper);
1443
switch (type) {
1444
case "c":
1445
appendSql(` LIKE `, args);
1446
break;
1447
case "nc":
1448
appendSql(` NOT LIKE `, args);
1449
break;
1450
}
1451
appendOperand(likeOperand(operands[1]), args, escaper);
1452
return;
1453
} else {
1454
appendOperand(operands[0], args, escaper);
1455
switch (type) {
1456
case "eq":
1457
appendSql(` = `, args);
1458
break;
1459
case "ne":
1460
appendSql(` <> `, args);
1461
break;
1462
case "gt":
1463
appendSql(` > `, args);
1464
break;
1465
case "lt":
1466
appendSql(` < `, args);
1467
break;
1468
case "gte":
1469
appendSql(` >= `, args);
1470
break;
1471
case "lte":
1472
appendSql(` <= `, args);
1473
break;
1474
default:
1475
throw new Error("Invalid filter operation");
1476
}
1477
appendOperand(operands[1], args, escaper);
1478
return;
1479
}
1480
}
1481
1482
// List operations
1483
appendOperand(operands[0], args, escaper);
1484
switch (type) {
1485
case "in":
1486
appendSql(` IN (`, args);
1487
break;
1488
case "nin":
1489
appendSql(` NOT IN (`, args);
1490
break;
1491
default:
1492
throw new Error("Invalid filter operation");
1493
}
1494
appendListOperands(operands.slice(1), args);
1495
appendSql(")", args);
1496
}
1497
1498
function appendOperand(o, args, escaper) {
1499
if (o.type === "column") {
1500
appendSql(escaper(o.value), args);
1501
} else {
1502
args.push(o.value);
1503
args[0].push("");
1504
}
1505
}
1506
1507
// TODO: Support column operands here?
1508
function appendListOperands(ops, args) {
1509
let first = true;
1510
for (const op of ops) {
1511
if (first) first = false;
1512
else appendSql(",", args);
1513
args.push(op.value);
1514
args[0].push("");
1515
}
1516
}
1517
1518
function likeOperand(operand) {
1519
return {...operand, value: `%${operand.value}%`};
1520
}
1521
1522
// Comparator function that moves null values (undefined, null, NaN) to the
1523
// end of the array.
1524
function defined(a, b) {
1525
return (a == null || !(a >= a)) - (b == null || !(b >= b));
1526
}
1527
1528
// Comparator function that sorts values in ascending order, with null values at
1529
// the end.
1530
function ascendingDefined(a, b) {
1531
return defined(a, b) || (a < b ? -1 : a > b ? 1 : 0);
1532
}
1533
1534
// Comparator function that sorts values in descending order, with null values
1535
// at the end.
1536
function descendingDefined(a, b) {
1537
return defined(a, b) || (a > b ? -1 : a < b ? 1 : 0);
1538
}
1539
1540
// Functions for checking type validity
1541
const isValidNumber = (value) => typeof value === "number" && !Number.isNaN(value);
1542
const isValidInteger = (value) => Number.isInteger(value) && !Number.isNaN(value);
1543
const isValidString = (value) => typeof value === "string";
1544
const isValidBoolean = (value) => typeof value === "boolean";
1545
const isValidBigint = (value) => typeof value === "bigint";
1546
const isValidDate = (value) => value instanceof Date && !isNaN(value);
1547
const isValidBuffer = (value) => value instanceof ArrayBuffer;
1548
const isValidArray = (value) => Array.isArray(value);
1549
const isValidObject = (value) => typeof value === "object" && value !== null;
1550
const isValidOther = (value) => value != null;
1551
1552
// Function to get the correct validity checking function based on type
1553
function getTypeValidator(colType) {
1554
switch (colType) {
1555
case "string":
1556
return isValidString;
1557
case "bigint":
1558
return isValidBigint;
1559
case "boolean":
1560
return isValidBoolean;
1561
case "number":
1562
return isValidNumber;
1563
case "integer":
1564
return isValidInteger;
1565
case "date":
1566
return isValidDate;
1567
case "buffer":
1568
return isValidBuffer;
1569
case "array":
1570
return isValidArray;
1571
case "object":
1572
return isValidObject;
1573
case "other":
1574
default:
1575
return isValidOther;
1576
}
1577
}
1578
1579
// Accepts dates in the form of ISOString and LocaleDateString, with or without time
1580
const DATE_TEST = /^(([-+]\d{2})?\d{4}(-\d{2}(-\d{2}))|(\d{1,2})\/(\d{1,2})\/(\d{2,4}))([T ]\d{2}:\d{2}(:\d{2}(\.\d{3})?)?(Z|[-+]\d{2}:\d{2})?)?$/;
1581
1582
function coerceToType(value, type) {
1583
switch (type) {
1584
case "string":
1585
return typeof value === "string" || value == null ? value : String(value);
1586
case "boolean":
1587
if (typeof value === "string") {
1588
const trimValue = value.trim().toLowerCase();
1589
return trimValue === "true"
1590
? true
1591
: trimValue === "false"
1592
? false
1593
: null;
1594
}
1595
return typeof value === "boolean" || value == null
1596
? value
1597
: Boolean(value);
1598
case "bigint":
1599
return typeof value === "bigint" || value == null
1600
? value
1601
: Number.isInteger(typeof value === "string" && !value.trim() ? NaN : +value)
1602
? BigInt(value) // eslint-disable-line no-undef
1603
: undefined;
1604
case "integer": // not a target type for coercion, but can be inferred
1605
case "number": {
1606
return typeof value === "number"
1607
? value
1608
: value == null || (typeof value === "string" && !value.trim())
1609
? NaN
1610
: Number(value);
1611
}
1612
case "date": {
1613
if (value instanceof Date || value == null) return value;
1614
if (typeof value === "number") return new Date(value);
1615
const trimValue = String(value).trim();
1616
if (typeof value === "string" && !trimValue) return null;
1617
return new Date(DATE_TEST.test(trimValue) ? trimValue : NaN);
1618
}
1619
case "array":
1620
case "object":
1621
case "buffer":
1622
case "other":
1623
return value;
1624
default:
1625
throw new Error(`Unable to coerce to type: ${type}`);
1626
}
1627
}
1628
1629
function getSchema(source) {
1630
const {columns} = source;
1631
let {schema} = source;
1632
if (!isQueryResultSetSchema(schema)) {
1633
schema = inferSchema(source, isQueryResultSetColumns(columns) ? columns : undefined);
1634
return {schema, inferred: true};
1635
}
1636
return {schema, inferred: false};
1637
}
1638
1639
// This function infers a schema from the source data, if one doesn't already
1640
// exist, and merges type assertions into that schema. If the schema was
1641
// inferred or if there are type assertions, it then coerces the rows in the
1642
// source data to the types specified in the schema.
1643
function applyTypes(source, operations) {
1644
const input = source;
1645
let {schema, inferred} = getSchema(source);
1646
const types = new Map(schema.map(({name, type}) => [name, type]));
1647
if (operations.types) {
1648
for (const {name, type} of operations.types) {
1649
types.set(name, type);
1650
// update schema with user-selected type
1651
if (schema === input.schema) schema = schema.slice(); // copy on write
1652
const colIndex = schema.findIndex((col) => col.name === name);
1653
if (colIndex > -1) schema[colIndex] = {...schema[colIndex], type};
1654
}
1655
source = source.map(d => coerceRow(d, types, schema));
1656
} else if (inferred) {
1657
// Coerce data according to new schema, unless that happened due to
1658
// operations.types, above.
1659
source = source.map(d => coerceRow(d, types, schema));
1660
}
1661
return {source, schema};
1662
}
1663
1664
function applyNames(source, operations) {
1665
if (!operations.names) return source;
1666
const overridesByName = new Map(operations.names.map((n) => [n.column, n]));
1667
return source.map((d) =>
1668
Object.fromEntries(Object.keys(d).map((k) => {
1669
const override = overridesByName.get(k);
1670
return [override?.name ?? k, d[k]];
1671
}))
1672
);
1673
}
1674
1675
// This function applies table cell operations to an in-memory table (array of
1676
// objects); it should be equivalent to the corresponding SQL query. TODO Use
1677
// DuckDBClient for data arrays, too, and then we wouldn’t need our own __table
1678
// function to do table operations on in-memory data?
1679
function __table(source, operations) {
1680
const errors = new Map();
1681
const input = source;
1682
const typed = applyTypes(source, operations);
1683
source = typed.source;
1684
let schema = typed.schema;
1685
if (operations.derive) {
1686
// Derived columns may depend on coerced values from the original data source,
1687
// so we must evaluate derivations after the initial inference and coercion
1688
// step.
1689
const derivedSource = [];
1690
operations.derive.map(({name, value}) => {
1691
let columnErrors = [];
1692
// Derived column formulas may reference renamed columns, so we must
1693
// compute derivations on the renamed source. However, we don't modify the
1694
// source itself with renamed names until after the other operations are
1695
// applied, because operations like filter and sort reference original
1696
// column names.
1697
// TODO Allow derived columns to reference other derived columns.
1698
applyNames(source, operations).map((row, index) => {
1699
let resolved;
1700
try {
1701
// TODO Support referencing `index` and `rows` in the derive function.
1702
resolved = value(row);
1703
} catch (error) {
1704
columnErrors.push({index, error});
1705
resolved = undefined;
1706
}
1707
if (derivedSource[index]) {
1708
derivedSource[index] = {...derivedSource[index], [name]: resolved};
1709
} else {
1710
derivedSource.push({[name]: resolved});
1711
}
1712
});
1713
if (columnErrors.length) errors.set(name, columnErrors);
1714
});
1715
// Since derived columns are untyped by default, we do a pass of type
1716
// inference and coercion after computing the derived values.
1717
const typedDerived = applyTypes(derivedSource, operations);
1718
// Merge derived source and schema with the source dataset.
1719
source = source.map((row, i) => ({...row, ...typedDerived.source[i]}));
1720
schema = [...schema, ...typedDerived.schema];
1721
}
1722
for (const {type, operands} of operations.filter) {
1723
const [{value: column}] = operands;
1724
const values = operands.slice(1).map(({value}) => value);
1725
switch (type) {
1726
// valid (matches the column type)
1727
case "v": {
1728
const [colType] = values;
1729
const isValid = getTypeValidator(colType);
1730
source = source.filter(d => isValid(d[column]));
1731
break;
1732
}
1733
// not valid (doesn't match the column type)
1734
case "nv": {
1735
const [colType] = values;
1736
const isValid = getTypeValidator(colType);
1737
source = source.filter(d => !isValid(d[column]));
1738
break;
1739
}
1740
case "eq": {
1741
const [value] = values;
1742
if (value instanceof Date) {
1743
const time = +value; // compare as primitive
1744
source = source.filter((d) => +d[column] === time);
1745
} else {
1746
source = source.filter((d) => d[column] === value);
1747
}
1748
break;
1749
}
1750
case "ne": {
1751
const [value] = values;
1752
source = source.filter((d) => d[column] !== value);
1753
break;
1754
}
1755
case "c": {
1756
const [value] = values;
1757
source = source.filter(
1758
(d) => typeof d[column] === "string" && d[column].includes(value)
1759
);
1760
break;
1761
}
1762
case "nc": {
1763
const [value] = values;
1764
source = source.filter(
1765
(d) => typeof d[column] === "string" && !d[column].includes(value)
1766
);
1767
break;
1768
}
1769
case "in": {
1770
const set = new Set(values); // TODO support dates?
1771
source = source.filter((d) => set.has(d[column]));
1772
break;
1773
}
1774
case "nin": {
1775
const set = new Set(values); // TODO support dates?
1776
source = source.filter((d) => !set.has(d[column]));
1777
break;
1778
}
1779
case "n": {
1780
source = source.filter((d) => d[column] == null);
1781
break;
1782
}
1783
case "nn": {
1784
source = source.filter((d) => d[column] != null);
1785
break;
1786
}
1787
case "lt": {
1788
const [value] = values;
1789
source = source.filter((d) => d[column] < value);
1790
break;
1791
}
1792
case "lte": {
1793
const [value] = values;
1794
source = source.filter((d) => d[column] <= value);
1795
break;
1796
}
1797
case "gt": {
1798
const [value] = values;
1799
source = source.filter((d) => d[column] > value);
1800
break;
1801
}
1802
case "gte": {
1803
const [value] = values;
1804
source = source.filter((d) => d[column] >= value);
1805
break;
1806
}
1807
default:
1808
throw new Error(`unknown filter type: ${type}`);
1809
}
1810
}
1811
for (const {column, direction} of reverse(operations.sort)) {
1812
const compare = direction === "desc" ? descendingDefined : ascendingDefined;
1813
if (source === input) source = source.slice(); // defensive copy
1814
source.sort((a, b) => compare(a[column], b[column]));
1815
}
1816
let {from, to} = operations.slice;
1817
from = from == null ? 0 : Math.max(0, from);
1818
to = to == null ? Infinity : Math.max(0, to);
1819
if (from > 0 || to < Infinity) {
1820
source = source.slice(Math.max(0, from), Math.max(0, to));
1821
}
1822
// Preserve the schema for all columns.
1823
let fullSchema = schema.slice();
1824
if (operations.select.columns) {
1825
if (schema) {
1826
const schemaByName = new Map(schema.map((s) => [s.name, s]));
1827
schema = operations.select.columns.map((c) => schemaByName.get(c));
1828
}
1829
source = source.map((d) =>
1830
Object.fromEntries(operations.select.columns.map((c) => [c, d[c]]))
1831
);
1832
}
1833
if (operations.names) {
1834
const overridesByName = new Map(operations.names.map((n) => [n.column, n]));
1835
if (schema) {
1836
schema = schema.map((s) => {
1837
const override = overridesByName.get(s.name);
1838
return ({...s, ...(override ? {name: override.name} : null)});
1839
});
1840
}
1841
if (fullSchema) {
1842
fullSchema = fullSchema.map((s) => {
1843
const override = overridesByName.get(s.name);
1844
return ({...s, ...(override ? {name: override.name} : null)});
1845
});
1846
}
1847
source = applyNames(source, operations);
1848
}
1849
if (source !== input) {
1850
if (schema) source.schema = schema;
1851
}
1852
source.fullSchema = fullSchema;
1853
source.errors = errors;
1854
return source;
1855
}
1856
1857
function coerceRow(object, types, schema) {
1858
const coerced = {};
1859
for (const col of schema) {
1860
const type = types.get(col.name);
1861
const value = object[col.name];
1862
coerced[col.name] = type === "raw" ? value : coerceToType(value, type);
1863
}
1864
return coerced;
1865
}
1866
1867
function createTypeCount() {
1868
return {
1869
boolean: 0,
1870
integer: 0,
1871
number: 0,
1872
date: 0,
1873
string: 0,
1874
array: 0,
1875
object: 0,
1876
bigint: 0,
1877
buffer: 0,
1878
defined: 0
1879
};
1880
}
1881
1882
// Caution: the order below matters! 🌶️ The first one that passes the ≥90% test
1883
// should be the one that we chose, and therefore these types should be listed
1884
// from most specific to least specific.
1885
const types$2 = [
1886
"boolean",
1887
"integer",
1888
"number",
1889
"date",
1890
"bigint",
1891
"array",
1892
"object",
1893
"buffer"
1894
// Note: "other" and "string" are intentionally omitted; see below!
1895
];
1896
1897
// We need to show *all* keys present in the array of Objects
1898
function getAllKeys(rows) {
1899
const keys = new Set();
1900
for (const row of rows) {
1901
// avoid crash if row is null or undefined
1902
if (row) {
1903
// only enumerable properties
1904
for (const key in row) {
1905
// only own properties
1906
if (Object.prototype.hasOwnProperty.call(row, key)) {
1907
// unique properties, in the order they appear
1908
keys.add(key);
1909
}
1910
}
1911
}
1912
}
1913
return Array.from(keys);
1914
}
1915
1916
function inferSchema(source, columns = getAllKeys(source)) {
1917
const schema = [];
1918
const sampleSize = 100;
1919
const sample = source.slice(0, sampleSize);
1920
for (const col of columns) {
1921
const colCount = createTypeCount();
1922
for (const d of sample) {
1923
let value = d[col];
1924
if (value == null) continue;
1925
const type = typeof value;
1926
if (type !== "string") {
1927
++colCount.defined;
1928
if (Array.isArray(value)) ++colCount.array;
1929
else if (value instanceof Date) ++colCount.date;
1930
else if (value instanceof ArrayBuffer) ++colCount.buffer;
1931
else if (type === "number") {
1932
++colCount.number;
1933
if (Number.isInteger(value)) ++colCount.integer;
1934
}
1935
// bigint, boolean, or object
1936
else if (type in colCount) ++colCount[type];
1937
} else {
1938
value = value.trim();
1939
if (!value) continue;
1940
++colCount.defined;
1941
++colCount.string;
1942
if (/^(true|false)$/i.test(value)) {
1943
++colCount.boolean;
1944
} else if (value && !isNaN(value)) {
1945
++colCount.number;
1946
if (Number.isInteger(+value)) ++colCount.integer;
1947
} else if (DATE_TEST.test(value)) ++colCount.date;
1948
}
1949
}
1950
// Chose the non-string, non-other type with the greatest count that is also
1951
// ≥90%; or if no such type meets that criterion, fallback to string if
1952
// ≥90%; and lastly fallback to other.
1953
const minCount = Math.max(1, colCount.defined * 0.9);
1954
const type =
1955
greatest(types$2, (type) =>
1956
colCount[type] >= minCount ? colCount[type] : NaN
1957
) ?? (colCount.string >= minCount ? "string" : "other");
1958
schema.push({
1959
name: col,
1960
type: type,
1961
inferred: type
1962
});
1963
}
1964
return schema;
1965
}
1966
1967
class Workbook {
1968
constructor(workbook) {
1969
Object.defineProperties(this, {
1970
_: {value: workbook},
1971
sheetNames: {
1972
value: workbook.worksheets.map((s) => s.name),
1973
enumerable: true
1974
}
1975
});
1976
}
1977
sheet(name, options) {
1978
const sname =
1979
typeof name === "number"
1980
? this.sheetNames[name]
1981
: this.sheetNames.includes((name += ""))
1982
? name
1983
: null;
1984
if (sname == null) throw new Error(`Sheet not found: ${name}`);
1985
const sheet = this._.getWorksheet(sname);
1986
return extract(sheet, options);
1987
}
1988
}
1989
1990
function extract(sheet, {range, headers} = {}) {
1991
let [[c0, r0], [c1, r1]] = parseRange(range, sheet);
1992
const headerRow = headers ? sheet._rows[r0++] : null;
1993
let names = new Set(["#"]);
1994
for (let n = c0; n <= c1; n++) {
1995
const value = headerRow ? valueOf(headerRow.findCell(n + 1)) : null;
1996
let name = (value && value + "") || toColumn(n);
1997
while (names.has(name)) name += "_";
1998
names.add(name);
1999
}
2000
names = new Array(c0).concat(Array.from(names));
2001
2002
const output = new Array(r1 - r0 + 1);
2003
for (let r = r0; r <= r1; r++) {
2004
const row = (output[r - r0] = Object.create(null, {"#": {value: r + 1}}));
2005
const _row = sheet.getRow(r + 1);
2006
if (_row.hasValues)
2007
for (let c = c0; c <= c1; c++) {
2008
const value = valueOf(_row.findCell(c + 1));
2009
if (value != null) row[names[c + 1]] = value;
2010
}
2011
}
2012
2013
output.columns = names.filter(() => true); // Filter sparse columns
2014
return output;
2015
}
2016
2017
function valueOf(cell) {
2018
if (!cell) return;
2019
const {value} = cell;
2020
if (value && typeof value === "object" && !(value instanceof Date)) {
2021
if (value.formula || value.sharedFormula) {
2022
return value.result && value.result.error ? NaN : value.result;
2023
}
2024
if (value.richText) {
2025
return richText(value);
2026
}
2027
if (value.text) {
2028
let {text} = value;
2029
if (text.richText) text = richText(text);
2030
return value.hyperlink && value.hyperlink !== text
2031
? `${value.hyperlink} ${text}`
2032
: text;
2033
}
2034
return value;
2035
}
2036
return value;
2037
}
2038
2039
function richText(value) {
2040
return value.richText.map((d) => d.text).join("");
2041
}
2042
2043
function parseRange(specifier = ":", {columnCount, rowCount}) {
2044
specifier += "";
2045
if (!specifier.match(/^[A-Z]*\d*:[A-Z]*\d*$/))
2046
throw new Error("Malformed range specifier");
2047
const [[c0 = 0, r0 = 0], [c1 = columnCount - 1, r1 = rowCount - 1]] =
2048
specifier.split(":").map(fromCellReference);
2049
return [
2050
[c0, r0],
2051
[c1, r1]
2052
];
2053
}
2054
2055
// Returns the default column name for a zero-based column index.
2056
// For example: 0 -> "A", 1 -> "B", 25 -> "Z", 26 -> "AA", 27 -> "AB".
2057
function toColumn(c) {
2058
let sc = "";
2059
c++;
2060
do {
2061
sc = String.fromCharCode(64 + (c % 26 || 26)) + sc;
2062
} while ((c = Math.floor((c - 1) / 26)));
2063
return sc;
2064
}
2065
2066
// Returns the zero-based indexes from a cell reference.
2067
// For example: "A1" -> [0, 0], "B2" -> [1, 1], "AA10" -> [26, 9].
2068
function fromCellReference(s) {
2069
const [, sc, sr] = s.match(/^([A-Z]*)(\d*)$/);
2070
let c = 0;
2071
if (sc)
2072
for (let i = 0; i < sc.length; i++)
2073
c += Math.pow(26, sc.length - i - 1) * (sc.charCodeAt(i) - 64);
2074
return [c ? c - 1 : undefined, sr ? +sr - 1 : undefined];
2075
}
2076
2077
async function remote_fetch(file) {
2078
const response = await fetch(await file.url());
2079
if (!response.ok) throw new Error(`Unable to load file: ${file.name}`);
2080
return response;
2081
}
2082
2083
function enforceSchema(source, schema) {
2084
const types = new Map(schema.map(({name, type}) => [name, type]));
2085
return Object.assign(source.map(d => coerceRow(d, types, schema)), {schema});
2086
}
2087
2088
async function dsv(file, delimiter, {array = false, typed = false} = {}) {
2089
const text = await file.text();
2090
const parse = (delimiter === "\t"
2091
? (array ? tsvParseRows : tsvParse)
2092
: (array ? csvParseRows : csvParse));
2093
if (typed === "auto" && !array) {
2094
const source = parse(text);
2095
return enforceSchema(source, inferSchema(source, source.columns));
2096
}
2097
return parse(text, typed && autoType);
2098
}
2099
2100
class AbstractFile {
2101
constructor(name, mimeType) {
2102
Object.defineProperty(this, "name", {value: name, enumerable: true});
2103
if (mimeType !== undefined) Object.defineProperty(this, "mimeType", {value: mimeType + "", enumerable: true});
2104
}
2105
async blob() {
2106
return (await remote_fetch(this)).blob();
2107
}
2108
async arrayBuffer() {
2109
return (await remote_fetch(this)).arrayBuffer();
2110
}
2111
async text() {
2112
return (await remote_fetch(this)).text();
2113
}
2114
async json() {
2115
return (await remote_fetch(this)).json();
2116
}
2117
async stream() {
2118
return (await remote_fetch(this)).body;
2119
}
2120
async csv(options) {
2121
return dsv(this, ",", options);
2122
}
2123
async tsv(options) {
2124
return dsv(this, "\t", options);
2125
}
2126
async image(props) {
2127
const url = await this.url();
2128
return new Promise((resolve, reject) => {
2129
const i = new Image();
2130
if (new URL(url, document.baseURI).origin !== new URL(location).origin) {
2131
i.crossOrigin = "anonymous";
2132
}
2133
Object.assign(i, props);
2134
i.onload = () => resolve(i);
2135
i.onerror = () => reject(new Error(`Unable to load file: ${this.name}`));
2136
i.src = url;
2137
});
2138
}
2139
async arrow({version = 4} = {}) {
2140
switch (version) {
2141
case 4: {
2142
const [Arrow, response] = await Promise.all([requireDefault(arrow4.resolve()), remote_fetch(this)]);
2143
return Arrow.Table.from(response);
2144
}
2145
case 9: {
2146
const [Arrow, response] = await Promise.all([import(`${cdn}${arrow9.resolve()}`), remote_fetch(this)]);
2147
return Arrow.tableFromIPC(response);
2148
}
2149
case 11: {
2150
const [Arrow, response] = await Promise.all([import(`${cdn}${arrow11.resolve()}`), remote_fetch(this)]);
2151
return Arrow.tableFromIPC(response);
2152
}
2153
default: throw new Error(`unsupported arrow version: ${version}`);
2154
}
2155
}
2156
async sqlite() {
2157
return SQLiteDatabaseClient.open(remote_fetch(this));
2158
}
2159
async zip() {
2160
const [JSZip, buffer] = await Promise.all([requireDefault(jszip.resolve()), this.arrayBuffer()]);
2161
return new ZipArchive(await JSZip.loadAsync(buffer));
2162
}
2163
async xml(mimeType = "application/xml") {
2164
return (new DOMParser).parseFromString(await this.text(), mimeType);
2165
}
2166
async html() {
2167
return this.xml("text/html");
2168
}
2169
async xlsx() {
2170
const [ExcelJS, buffer] = await Promise.all([requireDefault(exceljs.resolve()), this.arrayBuffer()]);
2171
return new Workbook(await new ExcelJS.Workbook().xlsx.load(buffer));
2172
}
2173
}
2174
2175
class FileAttachment extends AbstractFile {
2176
constructor(url, name, mimeType) {
2177
super(name, mimeType);
2178
Object.defineProperty(this, "_url", {value: url});
2179
}
2180
async url() {
2181
return (await this._url) + "";
2182
}
2183
}
2184
2185
function NoFileAttachments(name) {
2186
throw new Error(`File not found: ${name}`);
2187
}
2188
2189
function FileAttachments(resolve) {
2190
return Object.assign(
2191
name => {
2192
const result = resolve(name += "");
2193
if (result == null) throw new Error(`File not found: ${name}`);
2194
if (typeof result === "object" && "url" in result) {
2195
const {url, mimeType} = result;
2196
return new FileAttachment(url, name, mimeType);
2197
}
2198
return new FileAttachment(result, name);
2199
},
2200
{prototype: FileAttachment.prototype} // instanceof
2201
);
2202
}
2203
2204
class ZipArchive {
2205
constructor(archive) {
2206
Object.defineProperty(this, "_", {value: archive});
2207
this.filenames = Object.keys(archive.files).filter(name => !archive.files[name].dir);
2208
}
2209
file(path) {
2210
const object = this._.file(path += "");
2211
if (!object || object.dir) throw new Error(`file not found: ${path}`);
2212
return new ZipArchiveEntry(object);
2213
}
2214
}
2215
2216
class ZipArchiveEntry extends AbstractFile {
2217
constructor(object) {
2218
super(object.name);
2219
Object.defineProperty(this, "_", {value: object});
2220
Object.defineProperty(this, "_url", {writable: true});
2221
}
2222
async url() {
2223
return this._url || (this._url = this.blob().then(URL.createObjectURL));
2224
}
2225
async blob() {
2226
return this._.async("blob");
2227
}
2228
async arrayBuffer() {
2229
return this._.async("arraybuffer");
2230
}
2231
async text() {
2232
return this._.async("text");
2233
}
2234
async json() {
2235
return JSON.parse(await this.text());
2236
}
2237
}
2238
2239
function canvas(width, height) {
2240
var canvas = document.createElement("canvas");
2241
canvas.width = width;
2242
canvas.height = height;
2243
return canvas;
2244
}
2245
2246
function context2d(width, height, dpi) {
2247
if (dpi == null) dpi = devicePixelRatio;
2248
var canvas = document.createElement("canvas");
2249
canvas.width = width * dpi;
2250
canvas.height = height * dpi;
2251
canvas.style.width = width + "px";
2252
var context = canvas.getContext("2d");
2253
context.scale(dpi, dpi);
2254
return context;
2255
}
2256
2257
function download(value, name = "untitled", label = "Save") {
2258
const a = document.createElement("a");
2259
const b = a.appendChild(document.createElement("button"));
2260
b.textContent = label;
2261
a.download = name;
2262
2263
async function reset() {
2264
await new Promise(requestAnimationFrame);
2265
URL.revokeObjectURL(a.href);
2266
a.removeAttribute("href");
2267
b.textContent = label;
2268
b.disabled = false;
2269
}
2270
2271
a.onclick = async event => {
2272
b.disabled = true;
2273
if (a.href) return reset(); // Already saved.
2274
b.textContent = "Saving…";
2275
try {
2276
const object = await (typeof value === "function" ? value() : value);
2277
b.textContent = "Download";
2278
a.href = URL.createObjectURL(object); // eslint-disable-line require-atomic-updates
2279
} catch (ignore) {
2280
b.textContent = label;
2281
}
2282
if (event.eventPhase) return reset(); // Already downloaded.
2283
b.disabled = false;
2284
};
2285
2286
return a;
2287
}
2288
2289
var namespaces = {
2290
math: "http://www.w3.org/1998/Math/MathML",
2291
svg: "http://www.w3.org/2000/svg",
2292
xhtml: "http://www.w3.org/1999/xhtml",
2293
xlink: "http://www.w3.org/1999/xlink",
2294
xml: "http://www.w3.org/XML/1998/namespace",
2295
xmlns: "http://www.w3.org/2000/xmlns/"
2296
};
2297
2298
function element(name, attributes) {
2299
var prefix = name += "", i = prefix.indexOf(":"), value;
2300
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
2301
var element = namespaces.hasOwnProperty(prefix) // eslint-disable-line no-prototype-builtins
2302
? document.createElementNS(namespaces[prefix], name)
2303
: document.createElement(name);
2304
if (attributes) for (var key in attributes) {
2305
prefix = key, i = prefix.indexOf(":"), value = attributes[key];
2306
if (i >= 0 && (prefix = key.slice(0, i)) !== "xmlns") key = key.slice(i + 1);
2307
if (namespaces.hasOwnProperty(prefix)) element.setAttributeNS(namespaces[prefix], key, value); // eslint-disable-line no-prototype-builtins
2308
else element.setAttribute(key, value);
2309
}
2310
return element;
2311
}
2312
2313
function input$1(type) {
2314
var input = document.createElement("input");
2315
if (type != null) input.type = type;
2316
return input;
2317
}
2318
2319
function range$1(min, max, step) {
2320
if (arguments.length === 1) max = min, min = null;
2321
var input = document.createElement("input");
2322
input.min = min = min == null ? 0 : +min;
2323
input.max = max = max == null ? 1 : +max;
2324
input.step = step == null ? "any" : step = +step;
2325
input.type = "range";
2326
return input;
2327
}
2328
2329
function select(values) {
2330
var select = document.createElement("select");
2331
Array.prototype.forEach.call(values, function(value) {
2332
var option = document.createElement("option");
2333
option.value = option.textContent = value;
2334
select.appendChild(option);
2335
});
2336
return select;
2337
}
2338
2339
function svg$1(width, height) {
2340
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
2341
svg.setAttribute("viewBox", [0, 0, width, height]);
2342
svg.setAttribute("width", width);
2343
svg.setAttribute("height", height);
2344
return svg;
2345
}
2346
2347
function text$1(value) {
2348
return document.createTextNode(value);
2349
}
2350
2351
var count$1 = 0;
2352
2353
function uid(name) {
2354
return new Id("O-" + (name == null ? "" : name + "-") + ++count$1);
2355
}
2356
2357
function Id(id) {
2358
this.id = id;
2359
this.href = new URL(`#${id}`, location) + "";
2360
}
2361
2362
Id.prototype.toString = function() {
2363
return "url(" + this.href + ")";
2364
};
2365
2366
var DOM = /*#__PURE__*/Object.freeze({
2367
__proto__: null,
2368
canvas: canvas,
2369
context2d: context2d,
2370
download: download,
2371
element: element,
2372
input: input$1,
2373
range: range$1,
2374
select: select,
2375
svg: svg$1,
2376
text: text$1,
2377
uid: uid
2378
});
2379
2380
function buffer(file) {
2381
return new Promise(function(resolve, reject) {
2382
var reader = new FileReader;
2383
reader.onload = function() { resolve(reader.result); };
2384
reader.onerror = reject;
2385
reader.readAsArrayBuffer(file);
2386
});
2387
}
2388
2389
function text(file) {
2390
return new Promise(function(resolve, reject) {
2391
var reader = new FileReader;
2392
reader.onload = function() { resolve(reader.result); };
2393
reader.onerror = reject;
2394
reader.readAsText(file);
2395
});
2396
}
2397
2398
function url(file) {
2399
return new Promise(function(resolve, reject) {
2400
var reader = new FileReader;
2401
reader.onload = function() { resolve(reader.result); };
2402
reader.onerror = reject;
2403
reader.readAsDataURL(file);
2404
});
2405
}
2406
2407
var Files = /*#__PURE__*/Object.freeze({
2408
__proto__: null,
2409
buffer: buffer,
2410
text: text,
2411
url: url
2412
});
2413
2414
function that() {
2415
return this;
2416
}
2417
2418
function disposable(value, dispose) {
2419
let done = false;
2420
if (typeof dispose !== "function") {
2421
throw new Error("dispose is not a function");
2422
}
2423
return {
2424
[Symbol.iterator]: that,
2425
next: () => done ? {done: true} : (done = true, {done: false, value}),
2426
return: () => (done = true, dispose(value), {done: true}),
2427
throw: () => ({done: done = true})
2428
};
2429
}
2430
2431
function* filter(iterator, test) {
2432
var result, index = -1;
2433
while (!(result = iterator.next()).done) {
2434
if (test(result.value, ++index)) {
2435
yield result.value;
2436
}
2437
}
2438
}
2439
2440
function observe(initialize) {
2441
let stale = false;
2442
let value;
2443
let resolve;
2444
const dispose = initialize(change);
2445
2446
if (dispose != null && typeof dispose !== "function") {
2447
throw new Error(typeof dispose.then === "function"
2448
? "async initializers are not supported"
2449
: "initializer returned something, but not a dispose function");
2450
}
2451
2452
function change(x) {
2453
if (resolve) resolve(x), resolve = null;
2454
else stale = true;
2455
return value = x;
2456
}
2457
2458
function next() {
2459
return {done: false, value: stale
2460
? (stale = false, Promise.resolve(value))
2461
: new Promise(_ => (resolve = _))};
2462
}
2463
2464
return {
2465
[Symbol.iterator]: that,
2466
throw: () => ({done: true}),
2467
return: () => (dispose != null && dispose(), {done: true}),
2468
next
2469
};
2470
}
2471
2472
function input(input) {
2473
return observe(function(change) {
2474
var event = eventof(input), value = valueof$1(input);
2475
function inputted() { change(valueof$1(input)); }
2476
input.addEventListener(event, inputted);
2477
if (value !== undefined) change(value);
2478
return function() { input.removeEventListener(event, inputted); };
2479
});
2480
}
2481
2482
function valueof$1(input) {
2483
switch (input.type) {
2484
case "range":
2485
case "number": return input.valueAsNumber;
2486
case "date": return input.valueAsDate;
2487
case "checkbox": return input.checked;
2488
case "file": return input.multiple ? input.files : input.files[0];
2489
case "select-multiple": return Array.from(input.selectedOptions, o => o.value);
2490
default: return input.value;
2491
}
2492
}
2493
2494
function eventof(input) {
2495
switch (input.type) {
2496
case "button":
2497
case "submit":
2498
case "checkbox": return "click";
2499
case "file": return "change";
2500
default: return "input";
2501
}
2502
}
2503
2504
function* map$1(iterator, transform) {
2505
var result, index = -1;
2506
while (!(result = iterator.next()).done) {
2507
yield transform(result.value, ++index);
2508
}
2509
}
2510
2511
function queue(initialize) {
2512
let resolve;
2513
const queue = [];
2514
const dispose = initialize(push);
2515
2516
if (dispose != null && typeof dispose !== "function") {
2517
throw new Error(typeof dispose.then === "function"
2518
? "async initializers are not supported"
2519
: "initializer returned something, but not a dispose function");
2520
}
2521
2522
function push(x) {
2523
queue.push(x);
2524
if (resolve) resolve(queue.shift()), resolve = null;
2525
return x;
2526
}
2527
2528
function next() {
2529
return {done: false, value: queue.length
2530
? Promise.resolve(queue.shift())
2531
: new Promise(_ => (resolve = _))};
2532
}
2533
2534
return {
2535
[Symbol.iterator]: that,
2536
throw: () => ({done: true}),
2537
return: () => (dispose != null && dispose(), {done: true}),
2538
next
2539
};
2540
}
2541
2542
function* range(start, stop, step) {
2543
start = +start;
2544
stop = +stop;
2545
step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
2546
var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0;
2547
while (++i < n) {
2548
yield start + i * step;
2549
}
2550
}
2551
2552
function valueAt(iterator, i) {
2553
if (!isFinite(i = +i) || i < 0 || i !== i | 0) return;
2554
var result, index = -1;
2555
while (!(result = iterator.next()).done) {
2556
if (++index === i) {
2557
return result.value;
2558
}
2559
}
2560
}
2561
2562
function worker(source) {
2563
const url = URL.createObjectURL(new Blob([source], {type: "text/javascript"}));
2564
const worker = new Worker(url);
2565
return disposable(worker, () => {
2566
worker.terminate();
2567
URL.revokeObjectURL(url);
2568
});
2569
}
2570
2571
var Generators$1 = /*#__PURE__*/Object.freeze({
2572
__proto__: null,
2573
disposable: disposable,
2574
filter: filter,
2575
input: input,
2576
map: map$1,
2577
observe: observe,
2578
queue: queue,
2579
range: range,
2580
valueAt: valueAt,
2581
worker: worker
2582
});
2583
2584
function template(render, wrapper) {
2585
return function(strings) {
2586
var string = strings[0],
2587
parts = [], part,
2588
root = null,
2589
node, nodes,
2590
walker,
2591
i, n, j, m, k = -1;
2592
2593
// Concatenate the text using comments as placeholders.
2594
for (i = 1, n = arguments.length; i < n; ++i) {
2595
part = arguments[i];
2596
if (part instanceof Node) {
2597
parts[++k] = part;
2598
string += "<!--o:" + k + "-->";
2599
} else if (Array.isArray(part)) {
2600
for (j = 0, m = part.length; j < m; ++j) {
2601
node = part[j];
2602
if (node instanceof Node) {
2603
if (root === null) {
2604
parts[++k] = root = document.createDocumentFragment();
2605
string += "<!--o:" + k + "-->";
2606
}
2607
root.appendChild(node);
2608
} else {
2609
root = null;
2610
string += node;
2611
}
2612
}
2613
root = null;
2614
} else {
2615
string += part;
2616
}
2617
string += strings[i];
2618
}
2619
2620
// Render the text.
2621
root = render(string);
2622
2623
// Walk the rendered content to replace comment placeholders.
2624
if (++k > 0) {
2625
nodes = new Array(k);
2626
walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT, null, false);
2627
while (walker.nextNode()) {
2628
node = walker.currentNode;
2629
if (/^o:/.test(node.nodeValue)) {
2630
nodes[+node.nodeValue.slice(2)] = node;
2631
}
2632
}
2633
for (i = 0; i < k; ++i) {
2634
if (node = nodes[i]) {
2635
node.parentNode.replaceChild(parts[i], node);
2636
}
2637
}
2638
}
2639
2640
// Is the rendered content
2641
// … a parent of a single child? Detach and return the child.
2642
// … a document fragment? Replace the fragment with an element.
2643
// … some other node? Return it.
2644
return root.childNodes.length === 1 ? root.removeChild(root.firstChild)
2645
: root.nodeType === 11 ? ((node = wrapper()).appendChild(root), node)
2646
: root;
2647
};
2648
}
2649
2650
const html$1 = template(function(string) {
2651
var template = document.createElement("template");
2652
template.innerHTML = string.trim();
2653
return document.importNode(template.content, true);
2654
}, function() {
2655
return document.createElement("span");
2656
});
2657
2658
async function leaflet(require) {
2659
const L = await require(leaflet$1.resolve());
2660
if (!L._style) {
2661
const link = document.createElement("link");
2662
link.rel = "stylesheet";
2663
link.href = await require.resolve(leaflet$1.resolve("dist/leaflet.css"));
2664
L._style = document.head.appendChild(link);
2665
}
2666
return L;
2667
}
2668
2669
function md(require) {
2670
return require(marked.resolve()).then(function(marked) {
2671
return template(
2672
function(string) {
2673
var root = document.createElement("div");
2674
root.innerHTML = marked(string, {langPrefix: ""}).trim();
2675
var code = root.querySelectorAll("pre code[class]");
2676
if (code.length > 0) {
2677
require(highlight.resolve()).then(function(hl) {
2678
code.forEach(function(block) {
2679
function done() {
2680
hl.highlightBlock(block);
2681
block.parentNode.classList.add("observablehq--md-pre");
2682
}
2683
if (hl.getLanguage(block.className)) {
2684
done();
2685
} else {
2686
require(highlight.resolve("async-languages/index.js"))
2687
.then(index => {
2688
if (index.has(block.className)) {
2689
return require(highlight.resolve("async-languages/" + index.get(block.className))).then(language => {
2690
hl.registerLanguage(block.className, language);
2691
});
2692
}
2693
})
2694
.then(done, done);
2695
}
2696
});
2697
});
2698
}
2699
return root;
2700
},
2701
function() {
2702
return document.createElement("div");
2703
}
2704
);
2705
});
2706
}
2707
2708
async function mermaid(require) {
2709
const mer = await require(mermaid$1.resolve());
2710
mer.initialize({securityLevel: "loose", theme: "neutral"});
2711
return function mermaid() {
2712
const root = document.createElement("div");
2713
root.innerHTML = mer.render(uid().id, String.raw.apply(String, arguments));
2714
return root.removeChild(root.firstChild);
2715
};
2716
}
2717
2718
function Mutable(value) {
2719
let change;
2720
Object.defineProperties(this, {
2721
generator: {value: observe(_ => void (change = _))},
2722
value: {get: () => value, set: x => change(value = x)} // eslint-disable-line no-setter-return
2723
});
2724
if (value !== undefined) change(value);
2725
}
2726
2727
function* now() {
2728
while (true) {
2729
yield Date.now();
2730
}
2731
}
2732
2733
function delay(duration, value) {
2734
return new Promise(function(resolve) {
2735
setTimeout(function() {
2736
resolve(value);
2737
}, duration);
2738
});
2739
}
2740
2741
var timeouts = new Map;
2742
2743
function timeout(now, time) {
2744
var t = new Promise(function(resolve) {
2745
timeouts.delete(time);
2746
var delay = time - now;
2747
if (!(delay > 0)) throw new Error("invalid time");
2748
if (delay > 0x7fffffff) throw new Error("too long to wait");
2749
setTimeout(resolve, delay);
2750
});
2751
timeouts.set(time, t);
2752
return t;
2753
}
2754
2755
function when(time, value) {
2756
var now;
2757
return (now = timeouts.get(time = +time)) ? now.then(() => value)
2758
: (now = Date.now()) >= time ? Promise.resolve(value)
2759
: timeout(now, time).then(() => value);
2760
}
2761
2762
function tick(duration, value) {
2763
return when(Math.ceil((Date.now() + 1) / duration) * duration, value);
2764
}
2765
2766
var Promises = /*#__PURE__*/Object.freeze({
2767
__proto__: null,
2768
delay: delay,
2769
tick: tick,
2770
when: when
2771
});
2772
2773
function resolve(name, base) {
2774
if (/^(\w+:)|\/\//i.test(name)) return name;
2775
if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href;
2776
if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new Error("illegal name");
2777
return "https://unpkg.com/" + name;
2778
}
2779
2780
const svg = template(function(string) {
2781
var root = document.createElementNS("http://www.w3.org/2000/svg", "g");
2782
root.innerHTML = string.trim();
2783
return root;
2784
}, function() {
2785
return document.createElementNS("http://www.w3.org/2000/svg", "g");
2786
});
2787
2788
var raw = String.raw;
2789
2790
function style(href) {
2791
return new Promise(function(resolve, reject) {
2792
var link = document.createElement("link");
2793
link.rel = "stylesheet";
2794
link.href = href;
2795
link.onerror = reject;
2796
link.onload = resolve;
2797
document.head.appendChild(link);
2798
});
2799
}
2800
2801
function tex(require) {
2802
return Promise.all([
2803
require(katex.resolve()),
2804
require.resolve(katex.resolve("dist/katex.min.css")).then(style)
2805
]).then(function(values) {
2806
var katex = values[0], tex = renderer();
2807
2808
function renderer(options) {
2809
return function() {
2810
var root = document.createElement("div");
2811
katex.render(raw.apply(String, arguments), root, options);
2812
return root.removeChild(root.firstChild);
2813
};
2814
}
2815
2816
tex.options = renderer;
2817
tex.block = renderer({displayMode: true});
2818
return tex;
2819
});
2820
}
2821
2822
async function vl(require) {
2823
const [v, vl, api] = await Promise.all([vega, vegalite, vegaliteApi].map(d => require(d.resolve())));
2824
return api.register(v, vl);
2825
}
2826
2827
function width() {
2828
return observe(function(change) {
2829
var width = change(document.body.clientWidth);
2830
function resized() {
2831
var w = document.body.clientWidth;
2832
if (w !== width) change(width = w);
2833
}
2834
window.addEventListener("resize", resized);
2835
return function() {
2836
window.removeEventListener("resize", resized);
2837
};
2838
});
2839
}
2840
2841
const Library = Object.assign(Object.defineProperties(function Library(resolver) {
2842
const require = requirer(resolver);
2843
Object.defineProperties(this, properties({
2844
FileAttachment: () => NoFileAttachments,
2845
Mutable: () => Mutable,
2846
now,
2847
width,
2848
2849
// Tagged template literals
2850
dot: () => require(graphviz.resolve()),
2851
htl: () => require(htl.resolve()),
2852
html: () => html$1,
2853
md: () => md(require),
2854
svg: () => svg,
2855
tex: () => tex(require),
2856
2857
// Recommended libraries
2858
// https://observablehq.com/@observablehq/recommended-libraries
2859
_: () => require(lodash.resolve()),
2860
aq: () => require.alias({"apache-arrow": arrow4.resolve()})(arquero.resolve()), // TODO upgrade to apache-arrow@9
2861
Arrow: () => require(arrow4.resolve()), // TODO upgrade to apache-arrow@9
2862
d3: () => require(d3.resolve()),
2863
DuckDBClient: () => DuckDBClient,
2864
Inputs: () => require(inputs.resolve()).then(Inputs => ({...Inputs, file: Inputs.fileOf(AbstractFile)})),
2865
L: () => leaflet(require),
2866
mermaid: () => mermaid(require),
2867
Plot: () => require(plot.resolve()),
2868
__query: () => __query,
2869
require: () => require,
2870
resolve: () => resolve, // deprecated; use async require.resolve instead
2871
SQLite: () => SQLite(require),
2872
SQLiteDatabaseClient: () => SQLiteDatabaseClient,
2873
topojson: () => require(topojson.resolve()),
2874
vl: () => vl(require),
2875
2876
// Sample datasets
2877
// https://observablehq.com/@observablehq/sample-datasets
2878
aapl: () => new FileAttachment("https://static.observableusercontent.com/files/3ccff97fd2d93da734e76829b2b066eafdaac6a1fafdec0faf6ebc443271cfc109d29e80dd217468fcb2aff1e6bffdc73f356cc48feb657f35378e6abbbb63b9").csv({typed: true}),
2879
alphabet: () => new FileAttachment("https://static.observableusercontent.com/files/75d52e6c3130b1cae83cda89305e17b50f33e7420ef205587a135e8562bcfd22e483cf4fa2fb5df6dff66f9c5d19740be1cfaf47406286e2eb6574b49ffc685d").csv({typed: true}),
2880
cars: () => new FileAttachment("https://static.observableusercontent.com/files/048ec3dfd528110c0665dfa363dd28bc516ffb7247231f3ab25005036717f5c4c232a5efc7bb74bc03037155cb72b1abe85a33d86eb9f1a336196030443be4f6").csv({typed: true}),
2881
citywages: () => new FileAttachment("https://static.observableusercontent.com/files/39837ec5121fcc163131dbc2fe8c1a2e0b3423a5d1e96b5ce371e2ac2e20a290d78b71a4fb08b9fa6a0107776e17fb78af313b8ea70f4cc6648fad68ddf06f7a").csv({typed: true}),
2882
diamonds: () => new FileAttachment("https://static.observableusercontent.com/files/87942b1f5d061a21fa4bb8f2162db44e3ef0f7391301f867ab5ba718b225a63091af20675f0bfe7f922db097b217b377135203a7eab34651e21a8d09f4e37252").csv({typed: true}),
2883
flare: () => new FileAttachment("https://static.observableusercontent.com/files/a6b0d94a7f5828fd133765a934f4c9746d2010e2f342d335923991f31b14120de96b5cb4f160d509d8dc627f0107d7f5b5070d2516f01e4c862b5b4867533000").csv({typed: true}),
2884
industries: () => new FileAttachment("https://static.observableusercontent.com/files/76f13741128340cc88798c0a0b7fa5a2df8370f57554000774ab8ee9ae785ffa2903010cad670d4939af3e9c17e5e18e7e05ed2b38b848ac2fc1a0066aa0005f").csv({typed: true}),
2885
miserables: () => new FileAttachment("https://static.observableusercontent.com/files/31d904f6e21d42d4963ece9c8cc4fbd75efcbdc404bf511bc79906f0a1be68b5a01e935f65123670ed04e35ca8cae3c2b943f82bf8db49c5a67c85cbb58db052").json(),
2886
olympians: () => new FileAttachment("https://static.observableusercontent.com/files/31ca24545a0603dce099d10ee89ee5ae72d29fa55e8fc7c9ffb5ded87ac83060d80f1d9e21f4ae8eb04c1e8940b7287d179fe8060d887fb1f055f430e210007c").csv({typed: true}),
2887
penguins: () => new FileAttachment("https://static.observableusercontent.com/files/715db1223e067f00500780077febc6cebbdd90c151d3d78317c802732252052ab0e367039872ab9c77d6ef99e5f55a0724b35ddc898a1c99cb14c31a379af80a").csv({typed: true}),
2888
pizza: () => new FileAttachment("https://static.observableusercontent.com/files/c653108ab176088cacbb338eaf2344c4f5781681702bd6afb55697a3f91b511c6686ff469f3e3a27c75400001a2334dbd39a4499fe46b50a8b3c278b7d2f7fb5").csv({typed: true}),
2889
weather: () => new FileAttachment("https://static.observableusercontent.com/files/693a46b22b33db0f042728700e0c73e836fa13d55446df89120682d55339c6db7cc9e574d3d73f24ecc9bc7eb9ac9a1e7e104a1ee52c00aab1e77eb102913c1f").csv({typed: true}),
2890
2891
// Note: these are namespace objects, and thus exposed directly rather than
2892
// being wrapped in a function. This allows library.Generators to resolve,
2893
// rather than needing module.value.
2894
DOM,
2895
Files,
2896
Generators: Generators$1,
2897
Promises
2898
}));
2899
}, {
2900
resolve: {
2901
get: () => requireDefault.resolve,
2902
enumerable: true,
2903
configurable: true
2904
},
2905
require: {
2906
get: () => requireDefault,
2907
set: setDefaultRequire,
2908
enumerable: true,
2909
configurable: true
2910
}
2911
}), {
2912
resolveFrom,
2913
requireFrom
2914
});
2915
2916
function properties(values) {
2917
return Object.fromEntries(Object.entries(values).map(property));
2918
}
2919
2920
function property([key, value]) {
2921
return [key, ({value, writable: true, enumerable: true})];
2922
}
2923
2924
// src/main.js
2925
class PandocCodeDecorator {
2926
constructor(node) {
2927
this._node = node;
2928
this._spans = [];
2929
this.normalizeCodeRange();
2930
this.initializeEntryPoints();
2931
}
2932
normalizeCodeRange() {
2933
const n = this._node;
2934
const lines = n.querySelectorAll("code > span");
2935
for (const line of lines) {
2936
Array.from(line.childNodes).filter((n2) => n2.nodeType === n2.TEXT_NODE).forEach((n2) => {
2937
const newSpan = document.createElement("span");
2938
newSpan.textContent = n2.wholeText;
2939
n2.replaceWith(newSpan);
2940
});
2941
}
2942
}
2943
initializeEntryPoints() {
2944
const lines = this._node.querySelectorAll("code > span");
2945
let result = [];
2946
let offset = this._node.parentElement.dataset.sourceOffset && -Number(this._node.parentElement.dataset.sourceOffset) || 0;
2947
for (const line of lines) {
2948
let lineNumber = Number(line.id.split("-").pop());
2949
let column = 1;
2950
Array.from(line.childNodes).filter((n) => n.nodeType === n.ELEMENT_NODE && n.nodeName === "SPAN").forEach((n) => {
2951
result.push({
2952
offset,
2953
line: lineNumber,
2954
column,
2955
node: n
2956
});
2957
offset += n.textContent.length;
2958
column += n.textContent.length;
2959
});
2960
offset += 1;
2961
}
2962
this._elementEntryPoints = result;
2963
}
2964
locateEntry(offset) {
2965
let candidate;
2966
if (offset === Infinity)
2967
return void 0;
2968
for (let i = 0; i < this._elementEntryPoints.length; ++i) {
2969
const entry = this._elementEntryPoints[i];
2970
if (entry.offset > offset) {
2971
return { entry: candidate, index: i - 1 };
2972
}
2973
candidate = entry;
2974
}
2975
if (offset < candidate.offset + candidate.node.textContent.length) {
2976
return { entry: candidate, index: this._elementEntryPoints.length - 1 };
2977
} else {
2978
return void 0;
2979
}
2980
}
2981
offsetToLineColumn(offset) {
2982
let entry = this.locateEntry(offset);
2983
if (entry === void 0) {
2984
const entries = this._elementEntryPoints;
2985
const last = entries[entries.length - 1];
2986
return {
2987
line: last.line,
2988
column: last.column + Math.min(last.node.textContent.length, offset - last.offset)
2989
};
2990
}
2991
return {
2992
line: entry.entry.line,
2993
column: entry.entry.column + offset - entry.entry.offset
2994
};
2995
}
2996
*spanSelection(start, end) {
2997
this.ensureExactSpan(start, end);
2998
const startEntry = this.locateEntry(start);
2999
const endEntry = this.locateEntry(end);
3000
if (startEntry === void 0) {
3001
return;
3002
}
3003
const startIndex = startEntry.index;
3004
const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length;
3005
for (let i = startIndex; i < endIndex; ++i) {
3006
if (this._elementEntryPoints[i] !== void 0) {
3007
yield this._elementEntryPoints[i];
3008
}
3009
}
3010
}
3011
decorateSpan(start, end, classes) {
3012
for (const entryPoint of this.spanSelection(start, end)) {
3013
for (const cssClass of classes) {
3014
entryPoint.node.classList.add(cssClass);
3015
}
3016
}
3017
}
3018
clearSpan(start, end, classes) {
3019
for (const entryPoint of this.spanSelection(start, end)) {
3020
for (const cssClass of classes) {
3021
entryPoint.node.classList.remove(cssClass);
3022
}
3023
}
3024
}
3025
ensureExactSpan(start, end) {
3026
const splitEntry = (entry, offset) => {
3027
const newSpan = document.createElement("span");
3028
for (const cssClass of entry.node.classList) {
3029
newSpan.classList.add(cssClass);
3030
}
3031
const beforeText = entry.node.textContent.slice(0, offset - entry.offset);
3032
const afterText = entry.node.textContent.slice(offset - entry.offset);
3033
entry.node.textContent = beforeText;
3034
newSpan.textContent = afterText;
3035
entry.node.after(newSpan);
3036
this._elementEntryPoints.push({
3037
column: entry.column + offset - entry.offset,
3038
line: entry.line,
3039
node: newSpan,
3040
offset
3041
});
3042
this._elementEntryPoints.sort((a, b) => a.offset - b.offset);
3043
};
3044
const startEntry = this.locateEntry(start);
3045
if (startEntry !== void 0 && startEntry.entry !== void 0 && startEntry.entry.offset != start) {
3046
splitEntry(startEntry.entry, start);
3047
}
3048
const endEntry = this.locateEntry(end);
3049
if (endEntry !== void 0 && startEntry.entry !== void 0 && endEntry.entry.offset !== end) {
3050
splitEntry(endEntry.entry, end);
3051
}
3052
}
3053
clearSpan(start, end, classes) {
3054
this.ensureExactSpan(start, end);
3055
const startEntry = this.locateEntry(start);
3056
const endEntry = this.locateEntry(end);
3057
if (startEntry === void 0) {
3058
return;
3059
}
3060
const startIndex = startEntry.index;
3061
const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length;
3062
for (let i = startIndex; i < endIndex; ++i) {
3063
for (const cssClass of classes) {
3064
this._elementEntryPoints[i].node.classList.remove(cssClass);
3065
}
3066
}
3067
}
3068
}
3069
3070
function dispatch(node, type, detail) {
3071
detail = detail || {};
3072
var document = node.ownerDocument, event = document.defaultView.CustomEvent;
3073
if (typeof event === "function") {
3074
event = new event(type, {detail: detail});
3075
} else {
3076
event = document.createEvent("Event");
3077
event.initEvent(type, false, false);
3078
event.detail = detail;
3079
}
3080
node.dispatchEvent(event);
3081
}
3082
3083
// TODO https://twitter.com/mbostock/status/702737065121742848
3084
function isarray(value) {
3085
return Array.isArray(value)
3086
|| value instanceof Int8Array
3087
|| value instanceof Int16Array
3088
|| value instanceof Int32Array
3089
|| value instanceof Uint8Array
3090
|| value instanceof Uint8ClampedArray
3091
|| value instanceof Uint16Array
3092
|| value instanceof Uint32Array
3093
|| value instanceof Float32Array
3094
|| value instanceof Float64Array;
3095
}
3096
3097
// Non-integer keys in arrays, e.g. [1, 2, 0.5: "value"].
3098
function isindex(key) {
3099
return key === (key | 0) + "";
3100
}
3101
3102
function inspectName(name) {
3103
const n = document.createElement("span");
3104
n.className = "observablehq--cellname";
3105
n.textContent = `${name} = `;
3106
return n;
3107
}
3108
3109
const symbolToString = Symbol.prototype.toString;
3110
3111
// Symbols do not coerce to strings; they must be explicitly converted.
3112
function formatSymbol(symbol) {
3113
return symbolToString.call(symbol);
3114
}
3115
3116
const {getOwnPropertySymbols, prototype: {hasOwnProperty: hasOwnProperty$1}} = Object;
3117
const {toStringTag} = Symbol;
3118
3119
const FORBIDDEN = {};
3120
3121
const symbolsof = getOwnPropertySymbols;
3122
3123
function isown(object, key) {
3124
return hasOwnProperty$1.call(object, key);
3125
}
3126
3127
function tagof(object) {
3128
return object[toStringTag]
3129
|| (object.constructor && object.constructor.name)
3130
|| "Object";
3131
}
3132
3133
function valueof(object, key) {
3134
try {
3135
const value = object[key];
3136
if (value) value.constructor; // Test for SecurityError.
3137
return value;
3138
} catch (ignore) {
3139
return FORBIDDEN;
3140
}
3141
}
3142
3143
const SYMBOLS = [
3144
{ symbol: "@@__IMMUTABLE_INDEXED__@@", name: "Indexed", modifier: true },
3145
{ symbol: "@@__IMMUTABLE_KEYED__@@", name: "Keyed", modifier: true },
3146
{ symbol: "@@__IMMUTABLE_LIST__@@", name: "List", arrayish: true },
3147
{ symbol: "@@__IMMUTABLE_MAP__@@", name: "Map" },
3148
{
3149
symbol: "@@__IMMUTABLE_ORDERED__@@",
3150
name: "Ordered",
3151
modifier: true,
3152
prefix: true
3153
},
3154
{ symbol: "@@__IMMUTABLE_RECORD__@@", name: "Record" },
3155
{
3156
symbol: "@@__IMMUTABLE_SET__@@",
3157
name: "Set",
3158
arrayish: true,
3159
setish: true
3160
},
3161
{ symbol: "@@__IMMUTABLE_STACK__@@", name: "Stack", arrayish: true }
3162
];
3163
3164
function immutableName(obj) {
3165
try {
3166
let symbols = SYMBOLS.filter(({ symbol }) => obj[symbol] === true);
3167
if (!symbols.length) return;
3168
3169
const name = symbols.find(s => !s.modifier);
3170
const prefix =
3171
name.name === "Map" && symbols.find(s => s.modifier && s.prefix);
3172
3173
const arrayish = symbols.some(s => s.arrayish);
3174
const setish = symbols.some(s => s.setish);
3175
3176
return {
3177
name: `${prefix ? prefix.name : ""}${name.name}`,
3178
symbols,
3179
arrayish: arrayish && !setish,
3180
setish
3181
};
3182
} catch (e) {
3183
return null;
3184
}
3185
}
3186
3187
const {getPrototypeOf, getOwnPropertyDescriptors} = Object;
3188
const objectPrototype = getPrototypeOf({});
3189
3190
function inspectExpanded(object, _, name, proto) {
3191
let arrayish = isarray(object);
3192
let tag, fields, next, n;
3193
3194
if (object instanceof Map) {
3195
if (object instanceof object.constructor) {
3196
tag = `Map(${object.size})`;
3197
fields = iterateMap$1;
3198
} else { // avoid incompatible receiver error for prototype
3199
tag = "Map()";
3200
fields = iterateObject$1;
3201
}
3202
} else if (object instanceof Set) {
3203
if (object instanceof object.constructor) {
3204
tag = `Set(${object.size})`;
3205
fields = iterateSet$1;
3206
} else { // avoid incompatible receiver error for prototype
3207
tag = "Set()";
3208
fields = iterateObject$1;
3209
}
3210
} else if (arrayish) {
3211
tag = `${object.constructor.name}(${object.length})`;
3212
fields = iterateArray$1;
3213
} else if ((n = immutableName(object))) {
3214
tag = `Immutable.${n.name}${n.name === "Record" ? "" : `(${object.size})`}`;
3215
arrayish = n.arrayish;
3216
fields = n.arrayish
3217
? iterateImArray$1
3218
: n.setish
3219
? iterateImSet$1
3220
: iterateImObject$1;
3221
} else if (proto) {
3222
tag = tagof(object);
3223
fields = iterateProto;
3224
} else {
3225
tag = tagof(object);
3226
fields = iterateObject$1;
3227
}
3228
3229
const span = document.createElement("span");
3230
span.className = "observablehq--expanded";
3231
if (name) {
3232
span.appendChild(inspectName(name));
3233
}
3234
const a = span.appendChild(document.createElement("a"));
3235
a.innerHTML = `<svg width=8 height=8 class='observablehq--caret'>
3236
<path d='M4 7L0 1h8z' fill='currentColor' />
3237
</svg>`;
3238
a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`));
3239
a.addEventListener("mouseup", function(event) {
3240
event.stopPropagation();
3241
replace(span, inspectCollapsed(object, null, name, proto));
3242
});
3243
3244
fields = fields(object);
3245
for (let i = 0; !(next = fields.next()).done && i < 20; ++i) {
3246
span.appendChild(next.value);
3247
}
3248
3249
if (!next.done) {
3250
const a = span.appendChild(document.createElement("a"));
3251
a.className = "observablehq--field";
3252
a.style.display = "block";
3253
a.appendChild(document.createTextNode(` … more`));
3254
a.addEventListener("mouseup", function(event) {
3255
event.stopPropagation();
3256
span.insertBefore(next.value, span.lastChild.previousSibling);
3257
for (let i = 0; !(next = fields.next()).done && i < 19; ++i) {
3258
span.insertBefore(next.value, span.lastChild.previousSibling);
3259
}
3260
if (next.done) span.removeChild(span.lastChild.previousSibling);
3261
dispatch(span, "load");
3262
});
3263
}
3264
3265
span.appendChild(document.createTextNode(arrayish ? "]" : "}"));
3266
3267
return span;
3268
}
3269
3270
function* iterateMap$1(map) {
3271
for (const [key, value] of map) {
3272
yield formatMapField$1(key, value);
3273
}
3274
yield* iterateObject$1(map);
3275
}
3276
3277
function* iterateSet$1(set) {
3278
for (const value of set) {
3279
yield formatSetField(value);
3280
}
3281
yield* iterateObject$1(set);
3282
}
3283
3284
function* iterateImSet$1(set) {
3285
for (const value of set) {
3286
yield formatSetField(value);
3287
}
3288
}
3289
3290
function* iterateArray$1(array) {
3291
for (let i = 0, n = array.length; i < n; ++i) {
3292
if (i in array) {
3293
yield formatField$1(i, valueof(array, i), "observablehq--index");
3294
}
3295
}
3296
for (const key in array) {
3297
if (!isindex(key) && isown(array, key)) {
3298
yield formatField$1(key, valueof(array, key), "observablehq--key");
3299
}
3300
}
3301
for (const symbol of symbolsof(array)) {
3302
yield formatField$1(
3303
formatSymbol(symbol),
3304
valueof(array, symbol),
3305
"observablehq--symbol"
3306
);
3307
}
3308
}
3309
3310
function* iterateImArray$1(array) {
3311
let i1 = 0;
3312
for (const n = array.size; i1 < n; ++i1) {
3313
yield formatField$1(i1, array.get(i1), true);
3314
}
3315
}
3316
3317
function* iterateProto(object) {
3318
for (const key in getOwnPropertyDescriptors(object)) {
3319
yield formatField$1(key, valueof(object, key), "observablehq--key");
3320
}
3321
for (const symbol of symbolsof(object)) {
3322
yield formatField$1(
3323
formatSymbol(symbol),
3324
valueof(object, symbol),
3325
"observablehq--symbol"
3326
);
3327
}
3328
3329
const proto = getPrototypeOf(object);
3330
if (proto && proto !== objectPrototype) {
3331
yield formatPrototype(proto);
3332
}
3333
}
3334
3335
function* iterateObject$1(object) {
3336
for (const key in object) {
3337
if (isown(object, key)) {
3338
yield formatField$1(key, valueof(object, key), "observablehq--key");
3339
}
3340
}
3341
for (const symbol of symbolsof(object)) {
3342
yield formatField$1(
3343
formatSymbol(symbol),
3344
valueof(object, symbol),
3345
"observablehq--symbol"
3346
);
3347
}
3348
3349
const proto = getPrototypeOf(object);
3350
if (proto && proto !== objectPrototype) {
3351
yield formatPrototype(proto);
3352
}
3353
}
3354
3355
function* iterateImObject$1(object) {
3356
for (const [key, value] of object) {
3357
yield formatField$1(key, value, "observablehq--key");
3358
}
3359
}
3360
3361
function formatPrototype(value) {
3362
const item = document.createElement("div");
3363
const span = item.appendChild(document.createElement("span"));
3364
item.className = "observablehq--field";
3365
span.className = "observablehq--prototype-key";
3366
span.textContent = ` <prototype>`;
3367
item.appendChild(document.createTextNode(": "));
3368
item.appendChild(inspect(value, undefined, undefined, undefined, true));
3369
return item;
3370
}
3371
3372
function formatField$1(key, value, className) {
3373
const item = document.createElement("div");
3374
const span = item.appendChild(document.createElement("span"));
3375
item.className = "observablehq--field";
3376
span.className = className;
3377
span.textContent = ` ${key}`;
3378
item.appendChild(document.createTextNode(": "));
3379
item.appendChild(inspect(value));
3380
return item;
3381
}
3382
3383
function formatMapField$1(key, value) {
3384
const item = document.createElement("div");
3385
item.className = "observablehq--field";
3386
item.appendChild(document.createTextNode(" "));
3387
item.appendChild(inspect(key));
3388
item.appendChild(document.createTextNode(" => "));
3389
item.appendChild(inspect(value));
3390
return item;
3391
}
3392
3393
function formatSetField(value) {
3394
const item = document.createElement("div");
3395
item.className = "observablehq--field";
3396
item.appendChild(document.createTextNode(" "));
3397
item.appendChild(inspect(value));
3398
return item;
3399
}
3400
3401
function hasSelection(elem) {
3402
const sel = window.getSelection();
3403
return (
3404
sel.type === "Range" &&
3405
(sel.containsNode(elem, true) ||
3406
sel.anchorNode.isSelfOrDescendant(elem) ||
3407
sel.focusNode.isSelfOrDescendant(elem))
3408
);
3409
}
3410
3411
function inspectCollapsed(object, shallow, name, proto) {
3412
let arrayish = isarray(object);
3413
let tag, fields, next, n;
3414
3415
if (object instanceof Map) {
3416
if (object instanceof object.constructor) {
3417
tag = `Map(${object.size})`;
3418
fields = iterateMap;
3419
} else { // avoid incompatible receiver error for prototype
3420
tag = "Map()";
3421
fields = iterateObject;
3422
}
3423
} else if (object instanceof Set) {
3424
if (object instanceof object.constructor) {
3425
tag = `Set(${object.size})`;
3426
fields = iterateSet;
3427
} else { // avoid incompatible receiver error for prototype
3428
tag = "Set()";
3429
fields = iterateObject;
3430
}
3431
} else if (arrayish) {
3432
tag = `${object.constructor.name}(${object.length})`;
3433
fields = iterateArray;
3434
} else if ((n = immutableName(object))) {
3435
tag = `Immutable.${n.name}${n.name === 'Record' ? '' : `(${object.size})`}`;
3436
arrayish = n.arrayish;
3437
fields = n.arrayish ? iterateImArray : n.setish ? iterateImSet : iterateImObject;
3438
} else {
3439
tag = tagof(object);
3440
fields = iterateObject;
3441
}
3442
3443
if (shallow) {
3444
const span = document.createElement("span");
3445
span.className = "observablehq--shallow";
3446
if (name) {
3447
span.appendChild(inspectName(name));
3448
}
3449
span.appendChild(document.createTextNode(tag));
3450
span.addEventListener("mouseup", function(event) {
3451
if (hasSelection(span)) return;
3452
event.stopPropagation();
3453
replace(span, inspectCollapsed(object));
3454
});
3455
return span;
3456
}
3457
3458
const span = document.createElement("span");
3459
span.className = "observablehq--collapsed";
3460
if (name) {
3461
span.appendChild(inspectName(name));
3462
}
3463
const a = span.appendChild(document.createElement("a"));
3464
a.innerHTML = `<svg width=8 height=8 class='observablehq--caret'>
3465
<path d='M7 4L1 8V0z' fill='currentColor' />
3466
</svg>`;
3467
a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`));
3468
span.addEventListener("mouseup", function(event) {
3469
if (hasSelection(span)) return;
3470
event.stopPropagation();
3471
replace(span, inspectExpanded(object, null, name, proto));
3472
}, true);
3473
3474
fields = fields(object);
3475
for (let i = 0; !(next = fields.next()).done && i < 20; ++i) {
3476
if (i > 0) span.appendChild(document.createTextNode(", "));
3477
span.appendChild(next.value);
3478
}
3479
3480
if (!next.done) span.appendChild(document.createTextNode(", …"));
3481
span.appendChild(document.createTextNode(arrayish ? "]" : "}"));
3482
3483
return span;
3484
}
3485
3486
function* iterateMap(map) {
3487
for (const [key, value] of map) {
3488
yield formatMapField(key, value);
3489
}
3490
yield* iterateObject(map);
3491
}
3492
3493
function* iterateSet(set) {
3494
for (const value of set) {
3495
yield inspect(value, true);
3496
}
3497
yield* iterateObject(set);
3498
}
3499
3500
function* iterateImSet(set) {
3501
for (const value of set) {
3502
yield inspect(value, true);
3503
}
3504
}
3505
3506
function* iterateImArray(array) {
3507
let i0 = -1, i1 = 0;
3508
for (const n = array.size; i1 < n; ++i1) {
3509
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
3510
yield inspect(array.get(i1), true);
3511
i0 = i1;
3512
}
3513
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
3514
}
3515
3516
function* iterateArray(array) {
3517
let i0 = -1, i1 = 0;
3518
for (const n = array.length; i1 < n; ++i1) {
3519
if (i1 in array) {
3520
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
3521
yield inspect(valueof(array, i1), true);
3522
i0 = i1;
3523
}
3524
}
3525
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
3526
for (const key in array) {
3527
if (!isindex(key) && isown(array, key)) {
3528
yield formatField(key, valueof(array, key), "observablehq--key");
3529
}
3530
}
3531
for (const symbol of symbolsof(array)) {
3532
yield formatField(formatSymbol(symbol), valueof(array, symbol), "observablehq--symbol");
3533
}
3534
}
3535
3536
function* iterateObject(object) {
3537
for (const key in object) {
3538
if (isown(object, key)) {
3539
yield formatField(key, valueof(object, key), "observablehq--key");
3540
}
3541
}
3542
for (const symbol of symbolsof(object)) {
3543
yield formatField(formatSymbol(symbol), valueof(object, symbol), "observablehq--symbol");
3544
}
3545
}
3546
3547
function* iterateImObject(object) {
3548
for (const [key, value] of object) {
3549
yield formatField(key, value, "observablehq--key");
3550
}
3551
}
3552
3553
function formatEmpty(e) {
3554
const span = document.createElement("span");
3555
span.className = "observablehq--empty";
3556
span.textContent = e === 1 ? "empty" : `empty × ${e}`;
3557
return span;
3558
}
3559
3560
function formatField(key, value, className) {
3561
const fragment = document.createDocumentFragment();
3562
const span = fragment.appendChild(document.createElement("span"));
3563
span.className = className;
3564
span.textContent = key;
3565
fragment.appendChild(document.createTextNode(": "));
3566
fragment.appendChild(inspect(value, true));
3567
return fragment;
3568
}
3569
3570
function formatMapField(key, value) {
3571
const fragment = document.createDocumentFragment();
3572
fragment.appendChild(inspect(key, true));
3573
fragment.appendChild(document.createTextNode(" => "));
3574
fragment.appendChild(inspect(value, true));
3575
return fragment;
3576
}
3577
3578
function format(date, fallback) {
3579
if (!(date instanceof Date)) date = new Date(+date);
3580
if (isNaN(date)) return typeof fallback === "function" ? fallback(date) : fallback;
3581
const hours = date.getUTCHours();
3582
const minutes = date.getUTCMinutes();
3583
const seconds = date.getUTCSeconds();
3584
const milliseconds = date.getUTCMilliseconds();
3585
return `${formatYear(date.getUTCFullYear())}-${pad(date.getUTCMonth() + 1, 2)}-${pad(date.getUTCDate(), 2)}${
3586
hours || minutes || seconds || milliseconds ? `T${pad(hours, 2)}:${pad(minutes, 2)}${
3587
seconds || milliseconds ? `:${pad(seconds, 2)}${
3588
milliseconds ? `.${pad(milliseconds, 3)}` : ``
3589
}` : ``
3590
}Z` : ``
3591
}`;
3592
}
3593
3594
function formatYear(year) {
3595
return year < 0 ? `-${pad(-year, 6)}`
3596
: year > 9999 ? `+${pad(year, 6)}`
3597
: pad(year, 4);
3598
}
3599
3600
function pad(value, width) {
3601
return `${value}`.padStart(width, "0");
3602
}
3603
3604
function formatDate$1(date) {
3605
return format(date, "Invalid Date");
3606
}
3607
3608
var errorToString = Error.prototype.toString;
3609
3610
function formatError(value) {
3611
return value.stack || errorToString.call(value);
3612
}
3613
3614
var regExpToString = RegExp.prototype.toString;
3615
3616
function formatRegExp(value) {
3617
return regExpToString.call(value);
3618
}
3619
3620
/* eslint-disable no-control-regex */
3621
const NEWLINE_LIMIT = 20;
3622
3623
function formatString(string, shallow, expanded, name) {
3624
if (shallow === false) {
3625
// String has fewer escapes displayed with double quotes
3626
if (count(string, /["\n]/g) <= count(string, /`|\${/g)) {
3627
const span = document.createElement("span");
3628
if (name) span.appendChild(inspectName(name));
3629
const textValue = span.appendChild(document.createElement("span"));
3630
textValue.className = "observablehq--string";
3631
textValue.textContent = JSON.stringify(string);
3632
return span;
3633
}
3634
const lines = string.split("\n");
3635
if (lines.length > NEWLINE_LIMIT && !expanded) {
3636
const div = document.createElement("div");
3637
if (name) div.appendChild(inspectName(name));
3638
const textValue = div.appendChild(document.createElement("span"));
3639
textValue.className = "observablehq--string";
3640
textValue.textContent = "`" + templatify(lines.slice(0, NEWLINE_LIMIT).join("\n"));
3641
const splitter = div.appendChild(document.createElement("span"));
3642
const truncatedCount = lines.length - NEWLINE_LIMIT;
3643
splitter.textContent = `Show ${truncatedCount} truncated line${truncatedCount > 1 ? "s": ""}`; splitter.className = "observablehq--string-expand";
3644
splitter.addEventListener("mouseup", function (event) {
3645
event.stopPropagation();
3646
replace(div, inspect(string, shallow, true, name));
3647
});
3648
return div;
3649
}
3650
const span = document.createElement("span");
3651
if (name) span.appendChild(inspectName(name));
3652
const textValue = span.appendChild(document.createElement("span"));
3653
textValue.className = `observablehq--string${expanded ? " observablehq--expanded" : ""}`;
3654
textValue.textContent = "`" + templatify(string) + "`";
3655
return span;
3656
}
3657
3658
const span = document.createElement("span");
3659
if (name) span.appendChild(inspectName(name));
3660
const textValue = span.appendChild(document.createElement("span"));
3661
textValue.className = "observablehq--string";
3662
textValue.textContent = JSON.stringify(string.length > 100 ?
3663
`${string.slice(0, 50)}…${string.slice(-49)}` : string);
3664
return span;
3665
}
3666
3667
function templatify(string) {
3668
return string.replace(/[\\`\x00-\x09\x0b-\x19]|\${/g, templatifyChar);
3669
}
3670
3671
function templatifyChar(char) {
3672
var code = char.charCodeAt(0);
3673
switch (code) {
3674
case 0x8: return "\\b";
3675
case 0x9: return "\\t";
3676
case 0xb: return "\\v";
3677
case 0xc: return "\\f";
3678
case 0xd: return "\\r";
3679
}
3680
return code < 0x10 ? "\\x0" + code.toString(16)
3681
: code < 0x20 ? "\\x" + code.toString(16)
3682
: "\\" + char;
3683
}
3684
3685
function count(string, re) {
3686
var n = 0;
3687
while (re.exec(string)) ++n;
3688
return n;
3689
}
3690
3691
var toString$2 = Function.prototype.toString,
3692
TYPE_ASYNC = {prefix: "async ƒ"},
3693
TYPE_ASYNC_GENERATOR = {prefix: "async ƒ*"},
3694
TYPE_CLASS = {prefix: "class"},
3695
TYPE_FUNCTION = {prefix: "ƒ"},
3696
TYPE_GENERATOR = {prefix: "ƒ*"};
3697
3698
function inspectFunction(f, name) {
3699
var type, m, t = toString$2.call(f);
3700
3701
switch (f.constructor && f.constructor.name) {
3702
case "AsyncFunction": type = TYPE_ASYNC; break;
3703
case "AsyncGeneratorFunction": type = TYPE_ASYNC_GENERATOR; break;
3704
case "GeneratorFunction": type = TYPE_GENERATOR; break;
3705
default: type = /^class\b/.test(t) ? TYPE_CLASS : TYPE_FUNCTION; break;
3706
}
3707
3708
// A class, possibly named.
3709
// class Name
3710
if (type === TYPE_CLASS) {
3711
return formatFunction(type, "", name);
3712
}
3713
3714
// An arrow function with a single argument.
3715
// foo =>
3716
// async foo =>
3717
if ((m = /^(?:async\s*)?(\w+)\s*=>/.exec(t))) {
3718
return formatFunction(type, "(" + m[1] + ")", name);
3719
}
3720
3721
// An arrow function with parenthesized arguments.
3722
// (…)
3723
// async (…)
3724
if ((m = /^(?:async\s*)?\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) {
3725
return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name);
3726
}
3727
3728
// A function, possibly: async, generator, anonymous, simply arguments.
3729
// function name(…)
3730
// function* name(…)
3731
// async function name(…)
3732
// async function* name(…)
3733
if ((m = /^(?:async\s*)?function(?:\s*\*)?(?:\s*\w+)?\s*\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) {
3734
return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name);
3735
}
3736
3737
// Something else, like destructuring, comments or default values.
3738
return formatFunction(type, "(…)", name);
3739
}
3740
3741
function formatFunction(type, args, cellname) {
3742
var span = document.createElement("span");
3743
span.className = "observablehq--function";
3744
if (cellname) {
3745
span.appendChild(inspectName(cellname));
3746
}
3747
var spanType = span.appendChild(document.createElement("span"));
3748
spanType.className = "observablehq--keyword";
3749
spanType.textContent = type.prefix;
3750
span.appendChild(document.createTextNode(args));
3751
return span;
3752
}
3753
3754
const {prototype: {toString: toString$1}} = Object;
3755
3756
function inspect(value, shallow, expand, name, proto) {
3757
let type = typeof value;
3758
switch (type) {
3759
case "boolean":
3760
case "undefined": { value += ""; break; }
3761
case "number": { value = value === 0 && 1 / value < 0 ? "-0" : value + ""; break; }
3762
case "bigint": { value = value + "n"; break; }
3763
case "symbol": { value = formatSymbol(value); break; }
3764
case "function": { return inspectFunction(value, name); }
3765
case "string": { return formatString(value, shallow, expand, name); }
3766
default: {
3767
if (value === null) { type = null, value = "null"; break; }
3768
if (value instanceof Date) { type = "date", value = formatDate$1(value); break; }
3769
if (value === FORBIDDEN) { type = "forbidden", value = "[forbidden]"; break; }
3770
switch (toString$1.call(value)) {
3771
case "[object RegExp]": { type = "regexp", value = formatRegExp(value); break; }
3772
case "[object Error]": // https://github.com/lodash/lodash/blob/master/isError.js#L26
3773
case "[object DOMException]": { type = "error", value = formatError(value); break; }
3774
default: return (expand ? inspectExpanded : inspectCollapsed)(value, shallow, name, proto);
3775
}
3776
break;
3777
}
3778
}
3779
const span = document.createElement("span");
3780
if (name) span.appendChild(inspectName(name));
3781
const n = span.appendChild(document.createElement("span"));
3782
n.className = `observablehq--${type}`;
3783
n.textContent = value;
3784
return span;
3785
}
3786
3787
function replace(spanOld, spanNew) {
3788
if (spanOld.classList.contains("observablehq--inspect")) spanNew.classList.add("observablehq--inspect");
3789
spanOld.parentNode.replaceChild(spanNew, spanOld);
3790
dispatch(spanNew, "load");
3791
}
3792
3793
const LOCATION_MATCH = /\s+\(\d+:\d+\)$/m;
3794
3795
class Inspector {
3796
constructor(node) {
3797
if (!node) throw new Error("invalid node");
3798
this._node = node;
3799
node.classList.add("observablehq");
3800
}
3801
pending() {
3802
const {_node} = this;
3803
_node.classList.remove("observablehq--error");
3804
_node.classList.add("observablehq--running");
3805
}
3806
fulfilled(value, name) {
3807
const {_node} = this;
3808
if (!isnode(value) || (value.parentNode && value.parentNode !== _node)) {
3809
value = inspect(value, false, _node.firstChild // TODO Do this better.
3810
&& _node.firstChild.classList
3811
&& _node.firstChild.classList.contains("observablehq--expanded"), name);
3812
value.classList.add("observablehq--inspect");
3813
}
3814
_node.classList.remove("observablehq--running", "observablehq--error");
3815
if (_node.firstChild !== value) {
3816
if (_node.firstChild) {
3817
while (_node.lastChild !== _node.firstChild) _node.removeChild(_node.lastChild);
3818
_node.replaceChild(value, _node.firstChild);
3819
} else {
3820
_node.appendChild(value);
3821
}
3822
}
3823
dispatch(_node, "update");
3824
}
3825
rejected(error, name) {
3826
const {_node} = this;
3827
_node.classList.remove("observablehq--running");
3828
_node.classList.add("observablehq--error");
3829
while (_node.lastChild) _node.removeChild(_node.lastChild);
3830
var div = document.createElement("div");
3831
div.className = "observablehq--inspect";
3832
if (name) div.appendChild(inspectName(name));
3833
div.appendChild(document.createTextNode((error + "").replace(LOCATION_MATCH, "")));
3834
_node.appendChild(div);
3835
dispatch(_node, "error", {error: error});
3836
}
3837
}
3838
3839
Inspector.into = function(container) {
3840
if (typeof container === "string") {
3841
container = document.querySelector(container);
3842
if (container == null) throw new Error("container not found");
3843
}
3844
return function() {
3845
return new Inspector(container.appendChild(document.createElement("div")));
3846
};
3847
};
3848
3849
// Returns true if the given value is something that should be added to the DOM
3850
// by the inspector, rather than being inspected. This deliberately excludes
3851
// DocumentFragment since appending a fragment “dissolves” (mutates) the
3852
// fragment, and we wish for the inspector to not have side-effects. Also,
3853
// HTMLElement.prototype is an instanceof Element, but not an element!
3854
function isnode(value) {
3855
return (value instanceof Element || value instanceof Text)
3856
&& (value instanceof value.constructor);
3857
}
3858
3859
class RuntimeError extends Error {
3860
constructor(message, input) {
3861
super(message);
3862
this.input = input;
3863
}
3864
}
3865
3866
RuntimeError.prototype.name = "RuntimeError";
3867
3868
function generatorish(value) {
3869
return value
3870
&& typeof value.next === "function"
3871
&& typeof value.return === "function";
3872
}
3873
3874
function load(notebook, library, observer) {
3875
if (typeof library == "function") observer = library, library = null;
3876
if (typeof observer !== "function") throw new Error("invalid observer");
3877
if (library == null) library = new Library();
3878
3879
const {modules, id} = notebook;
3880
const map = new Map;
3881
const runtime = new Runtime(library);
3882
const main = runtime_module(id);
3883
3884
function runtime_module(id) {
3885
let module = map.get(id);
3886
if (!module) map.set(id, module = runtime.module());
3887
return module;
3888
}
3889
3890
for (const m of modules) {
3891
const module = runtime_module(m.id);
3892
let i = 0;
3893
for (const v of m.variables) {
3894
if (v.from) module.import(v.remote, v.name, runtime_module(v.from));
3895
else if (module === main) module.variable(observer(v, i, m.variables)).define(v.name, v.inputs, v.value);
3896
else module.define(v.name, v.inputs, v.value);
3897
++i;
3898
}
3899
}
3900
3901
return runtime;
3902
}
3903
3904
function constant(x) {
3905
return () => x;
3906
}
3907
3908
function identity$1(x) {
3909
return x;
3910
}
3911
3912
function rethrow(error) {
3913
return () => {
3914
throw error;
3915
};
3916
}
3917
3918
const prototype = Array.prototype;
3919
const map = prototype.map;
3920
3921
function noop() {}
3922
3923
const TYPE_NORMAL = 1; // a normal variable
3924
const TYPE_IMPLICIT = 2; // created on reference
3925
const TYPE_DUPLICATE = 3; // created on duplicate definition
3926
3927
const no_observer = Symbol("no-observer");
3928
3929
function Variable(type, module, observer, options) {
3930
if (!observer) observer = no_observer;
3931
Object.defineProperties(this, {
3932
_observer: {value: observer, writable: true},
3933
_definition: {value: variable_undefined, writable: true},
3934
_duplicate: {value: undefined, writable: true},
3935
_duplicates: {value: undefined, writable: true},
3936
_indegree: {value: NaN, writable: true}, // The number of computing inputs.
3937
_inputs: {value: [], writable: true},
3938
_invalidate: {value: noop, writable: true},
3939
_module: {value: module},
3940
_name: {value: null, writable: true},
3941
_outputs: {value: new Set, writable: true},
3942
_promise: {value: Promise.resolve(undefined), writable: true},
3943
_reachable: {value: observer !== no_observer, writable: true}, // Is this variable transitively visible?
3944
_rejector: {value: variable_rejector(this)},
3945
_shadow: {value: initShadow(module, options)},
3946
_type: {value: type},
3947
_value: {value: undefined, writable: true},
3948
_version: {value: 0, writable: true}
3949
});
3950
}
3951
3952
Object.defineProperties(Variable.prototype, {
3953
_pending: {value: variable_pending, writable: true, configurable: true},
3954
_fulfilled: {value: variable_fulfilled, writable: true, configurable: true},
3955
_rejected: {value: variable_rejected, writable: true, configurable: true},
3956
_resolve: {value: variable_resolve, writable: true, configurable: true},
3957
define: {value: variable_define, writable: true, configurable: true},
3958
delete: {value: variable_delete, writable: true, configurable: true},
3959
import: {value: variable_import, writable: true, configurable: true}
3960
});
3961
3962
function initShadow(module, options) {
3963
if (!options?.shadow) return null;
3964
return new Map(
3965
Object.entries(options.shadow)
3966
.map(([name, definition]) => [name, (new Variable(TYPE_IMPLICIT, module)).define([], definition)])
3967
);
3968
}
3969
3970
function variable_attach(variable) {
3971
variable._module._runtime._dirty.add(variable);
3972
variable._outputs.add(this);
3973
}
3974
3975
function variable_detach(variable) {
3976
variable._module._runtime._dirty.add(variable);
3977
variable._outputs.delete(this);
3978
}
3979
3980
function variable_undefined() {
3981
throw variable_undefined;
3982
}
3983
3984
function variable_stale() {
3985
throw variable_stale;
3986
}
3987
3988
function variable_rejector(variable) {
3989
return (error) => {
3990
if (error === variable_stale) throw error;
3991
if (error === variable_undefined) throw new RuntimeError(`${variable._name} is not defined`, variable._name);
3992
if (error instanceof Error && error.message) throw new RuntimeError(error.message, variable._name);
3993
throw new RuntimeError(`${variable._name} could not be resolved`, variable._name);
3994
};
3995
}
3996
3997
function variable_duplicate(name) {
3998
return () => {
3999
throw new RuntimeError(`${name} is defined more than once`);
4000
};
4001
}
4002
4003
function variable_define(name, inputs, definition) {
4004
switch (arguments.length) {
4005
case 1: {
4006
definition = name, name = inputs = null;
4007
break;
4008
}
4009
case 2: {
4010
definition = inputs;
4011
if (typeof name === "string") inputs = null;
4012
else inputs = name, name = null;
4013
break;
4014
}
4015
}
4016
return variable_defineImpl.call(this,
4017
name == null ? null : String(name),
4018
inputs == null ? [] : map.call(inputs, this._resolve, this),
4019
typeof definition === "function" ? definition : constant(definition)
4020
);
4021
}
4022
4023
function variable_resolve(name) {
4024
return this._shadow?.get(name) ?? this._module._resolve(name);
4025
}
4026
4027
function variable_defineImpl(name, inputs, definition) {
4028
const scope = this._module._scope, runtime = this._module._runtime;
4029
4030
this._inputs.forEach(variable_detach, this);
4031
inputs.forEach(variable_attach, this);
4032
this._inputs = inputs;
4033
this._definition = definition;
4034
this._value = undefined;
4035
4036
// Is this an active variable (that may require disposal)?
4037
if (definition === noop) runtime._variables.delete(this);
4038
else runtime._variables.add(this);
4039
4040
// Did the variable’s name change? Time to patch references!
4041
if (name !== this._name || scope.get(name) !== this) {
4042
let error, found;
4043
4044
if (this._name) { // Did this variable previously have a name?
4045
if (this._outputs.size) { // And did other variables reference this variable?
4046
scope.delete(this._name);
4047
found = this._module._resolve(this._name);
4048
found._outputs = this._outputs, this._outputs = new Set;
4049
found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(this)] = found; }, this);
4050
found._outputs.forEach(runtime._updates.add, runtime._updates);
4051
runtime._dirty.add(found).add(this);
4052
scope.set(this._name, found);
4053
} else if ((found = scope.get(this._name)) === this) { // Do no other variables reference this variable?
4054
scope.delete(this._name); // It’s safe to delete!
4055
} else if (found._type === TYPE_DUPLICATE) { // Do other variables assign this name?
4056
found._duplicates.delete(this); // This variable no longer assigns this name.
4057
this._duplicate = undefined;
4058
if (found._duplicates.size === 1) { // Is there now only one variable assigning this name?
4059
found = found._duplicates.keys().next().value; // Any references are now fixed!
4060
error = scope.get(this._name);
4061
found._outputs = error._outputs, error._outputs = new Set;
4062
found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(error)] = found; });
4063
found._definition = found._duplicate, found._duplicate = undefined;
4064
runtime._dirty.add(error).add(found);
4065
runtime._updates.add(found);
4066
scope.set(this._name, found);
4067
}
4068
} else {
4069
throw new Error;
4070
}
4071
}
4072
4073
if (this._outputs.size) throw new Error;
4074
4075
if (name) { // Does this variable have a new name?
4076
if (found = scope.get(name)) { // Do other variables reference or assign this name?
4077
if (found._type === TYPE_DUPLICATE) { // Do multiple other variables already define this name?
4078
this._definition = variable_duplicate(name), this._duplicate = definition;
4079
found._duplicates.add(this);
4080
} else if (found._type === TYPE_IMPLICIT) { // Are the variable references broken?
4081
this._outputs = found._outputs, found._outputs = new Set; // Now they’re fixed!
4082
this._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = this; }, this);
4083
runtime._dirty.add(found).add(this);
4084
scope.set(name, this);
4085
} else { // Does another variable define this name?
4086
found._duplicate = found._definition, this._duplicate = definition; // Now they’re duplicates.
4087
error = new Variable(TYPE_DUPLICATE, this._module);
4088
error._name = name;
4089
error._definition = this._definition = found._definition = variable_duplicate(name);
4090
error._outputs = found._outputs, found._outputs = new Set;
4091
error._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = error; });
4092
error._duplicates = new Set([this, found]);
4093
runtime._dirty.add(found).add(error);
4094
runtime._updates.add(found).add(error);
4095
scope.set(name, error);
4096
}
4097
} else {
4098
scope.set(name, this);
4099
}
4100
}
4101
4102
this._name = name;
4103
}
4104
4105
// If this redefined variable was previously evaluated, invalidate it. (If the
4106
// variable was never evaluated, then the invalidated value could never have
4107
// been exposed and we can avoid this extra work.)
4108
if (this._version > 0) ++this._version;
4109
4110
runtime._updates.add(this);
4111
runtime._compute();
4112
return this;
4113
}
4114
4115
function variable_import(remote, name, module) {
4116
if (arguments.length < 3) module = name, name = remote;
4117
return variable_defineImpl.call(this, String(name), [module._resolve(String(remote))], identity$1);
4118
}
4119
4120
function variable_delete() {
4121
return variable_defineImpl.call(this, null, [], noop);
4122
}
4123
4124
function variable_pending() {
4125
if (this._observer.pending) this._observer.pending();
4126
}
4127
4128
function variable_fulfilled(value) {
4129
if (this._observer.fulfilled) this._observer.fulfilled(value, this._name);
4130
}
4131
4132
function variable_rejected(error) {
4133
if (this._observer.rejected) this._observer.rejected(error, this._name);
4134
}
4135
4136
const variable_variable = Symbol("variable");
4137
const variable_invalidation = Symbol("invalidation");
4138
const variable_visibility = Symbol("visibility");
4139
4140
function Module(runtime, builtins = []) {
4141
Object.defineProperties(this, {
4142
_runtime: {value: runtime},
4143
_scope: {value: new Map},
4144
_builtins: {value: new Map([
4145
["@variable", variable_variable],
4146
["invalidation", variable_invalidation],
4147
["visibility", variable_visibility],
4148
...builtins
4149
])},
4150
_source: {value: null, writable: true}
4151
});
4152
}
4153
4154
Object.defineProperties(Module.prototype, {
4155
_resolve: {value: module_resolve, writable: true, configurable: true},
4156
redefine: {value: module_redefine, writable: true, configurable: true},
4157
define: {value: module_define, writable: true, configurable: true},
4158
derive: {value: module_derive, writable: true, configurable: true},
4159
import: {value: module_import, writable: true, configurable: true},
4160
value: {value: module_value, writable: true, configurable: true},
4161
variable: {value: module_variable, writable: true, configurable: true},
4162
builtin: {value: module_builtin, writable: true, configurable: true}
4163
});
4164
4165
function module_redefine(name) {
4166
const v = this._scope.get(name);
4167
if (!v) throw new RuntimeError(`${name} is not defined`);
4168
if (v._type === TYPE_DUPLICATE) throw new RuntimeError(`${name} is defined more than once`);
4169
return v.define.apply(v, arguments);
4170
}
4171
4172
function module_define() {
4173
const v = new Variable(TYPE_NORMAL, this);
4174
return v.define.apply(v, arguments);
4175
}
4176
4177
function module_import() {
4178
const v = new Variable(TYPE_NORMAL, this);
4179
return v.import.apply(v, arguments);
4180
}
4181
4182
function module_variable(observer, options) {
4183
return new Variable(TYPE_NORMAL, this, observer, options);
4184
}
4185
4186
async function module_value(name) {
4187
let v = this._scope.get(name);
4188
if (!v) throw new RuntimeError(`${name} is not defined`);
4189
if (v._observer === no_observer) {
4190
v = this.variable(true).define([name], identity$1);
4191
try {
4192
return await module_revalue(this._runtime, v);
4193
} finally {
4194
v.delete();
4195
}
4196
} else {
4197
return module_revalue(this._runtime, v);
4198
}
4199
}
4200
4201
// If the variable is redefined before its value resolves, try again.
4202
async function module_revalue(runtime, variable) {
4203
await runtime._compute();
4204
try {
4205
return await variable._promise;
4206
} catch (error) {
4207
if (error === variable_stale) return module_revalue(runtime, variable);
4208
throw error;
4209
}
4210
}
4211
4212
function module_derive(injects, injectModule) {
4213
const map = new Map();
4214
const modules = new Set();
4215
const copies = [];
4216
4217
// Given a module, derives an alias of that module with an initially-empty
4218
// definition. The variables will be copied later in a second pass below.
4219
function alias(source) {
4220
let target = map.get(source);
4221
if (target) return target;
4222
target = new Module(source._runtime, source._builtins);
4223
target._source = source;
4224
map.set(source, target);
4225
copies.push([target, source]);
4226
modules.add(source);
4227
return target;
4228
}
4229
4230
// Inject the given variables as reverse imports into the derived module.
4231
const derive = alias(this);
4232
for (const inject of injects) {
4233
const {alias, name} = typeof inject === "object" ? inject : {name: inject};
4234
derive.import(name, alias == null ? name : alias, injectModule);
4235
}
4236
4237
// Iterate over all the variables (currently) in this module. If any
4238
// represents an import-with (i.e., an import of a module with a _source), the
4239
// transitive import-with must be copied, too, as direct injections may affect
4240
// transitive injections. Note that an import-with can only be created with
4241
// module.derive and hence it’s not possible for an import-with to be added
4242
// later; therefore we only need to apply this check once, now.
4243
for (const module of modules) {
4244
for (const [name, variable] of module._scope) {
4245
if (variable._definition === identity$1) { // import
4246
if (module === this && derive._scope.has(name)) continue; // overridden by injection
4247
const importedModule = variable._inputs[0]._module;
4248
if (importedModule._source) alias(importedModule);
4249
}
4250
}
4251
}
4252
4253
// Finally, with the modules resolved, copy the variable definitions.
4254
for (const [target, source] of copies) {
4255
for (const [name, sourceVariable] of source._scope) {
4256
const targetVariable = target._scope.get(name);
4257
if (targetVariable && targetVariable._type !== TYPE_IMPLICIT) continue; // preserve injection
4258
if (sourceVariable._definition === identity$1) { // import
4259
const sourceInput = sourceVariable._inputs[0];
4260
const sourceModule = sourceInput._module;
4261
target.import(sourceInput._name, name, map.get(sourceModule) || sourceModule);
4262
} else { // non-import
4263
target.define(name, sourceVariable._inputs.map(variable_name), sourceVariable._definition);
4264
}
4265
}
4266
}
4267
4268
return derive;
4269
}
4270
4271
function module_resolve(name) {
4272
let variable = this._scope.get(name), value;
4273
if (!variable) {
4274
variable = new Variable(TYPE_IMPLICIT, this);
4275
if (this._builtins.has(name)) {
4276
variable.define(name, constant(this._builtins.get(name)));
4277
} else if (this._runtime._builtin._scope.has(name)) {
4278
variable.import(name, this._runtime._builtin);
4279
} else {
4280
try {
4281
value = this._runtime._global(name);
4282
} catch (error) {
4283
return variable.define(name, rethrow(error));
4284
}
4285
if (value === undefined) {
4286
this._scope.set(variable._name = name, variable);
4287
} else {
4288
variable.define(name, constant(value));
4289
}
4290
}
4291
}
4292
return variable;
4293
}
4294
4295
function module_builtin(name, value) {
4296
this._builtins.set(name, value);
4297
}
4298
4299
function variable_name(variable) {
4300
return variable._name;
4301
}
4302
4303
const frame = typeof requestAnimationFrame === "function" ? requestAnimationFrame
4304
: typeof setImmediate === "function" ? setImmediate
4305
: f => setTimeout(f, 0);
4306
4307
function Runtime(builtins = new Library, global = window_global) {
4308
const builtin = this.module();
4309
Object.defineProperties(this, {
4310
_dirty: {value: new Set},
4311
_updates: {value: new Set},
4312
_precomputes: {value: [], writable: true},
4313
_computing: {value: null, writable: true},
4314
_init: {value: null, writable: true},
4315
_modules: {value: new Map},
4316
_variables: {value: new Set},
4317
_disposed: {value: false, writable: true},
4318
_builtin: {value: builtin},
4319
_global: {value: global}
4320
});
4321
if (builtins) for (const name in builtins) {
4322
(new Variable(TYPE_IMPLICIT, builtin)).define(name, [], builtins[name]);
4323
}
4324
}
4325
4326
Object.defineProperties(Runtime.prototype, {
4327
_precompute: {value: runtime_precompute, writable: true, configurable: true},
4328
_compute: {value: runtime_compute, writable: true, configurable: true},
4329
_computeSoon: {value: runtime_computeSoon, writable: true, configurable: true},
4330
_computeNow: {value: runtime_computeNow, writable: true, configurable: true},
4331
dispose: {value: runtime_dispose, writable: true, configurable: true},
4332
module: {value: runtime_module, writable: true, configurable: true},
4333
fileAttachments: {value: FileAttachments, writable: true, configurable: true},
4334
load: {value: load, writable: true, configurable: true}
4335
});
4336
4337
function runtime_dispose() {
4338
this._computing = Promise.resolve();
4339
this._disposed = true;
4340
this._variables.forEach(v => {
4341
v._invalidate();
4342
v._version = NaN;
4343
});
4344
}
4345
4346
function runtime_module(define, observer = noop) {
4347
let module;
4348
if (define === undefined) {
4349
if (module = this._init) {
4350
this._init = null;
4351
return module;
4352
}
4353
return new Module(this);
4354
}
4355
module = this._modules.get(define);
4356
if (module) return module;
4357
this._init = module = new Module(this);
4358
this._modules.set(define, module);
4359
try {
4360
define(this, observer);
4361
} finally {
4362
this._init = null;
4363
}
4364
return module;
4365
}
4366
4367
function runtime_precompute(callback) {
4368
this._precomputes.push(callback);
4369
this._compute();
4370
}
4371
4372
function runtime_compute() {
4373
return this._computing || (this._computing = this._computeSoon());
4374
}
4375
4376
function runtime_computeSoon() {
4377
return new Promise(frame).then(() => this._disposed ? undefined : this._computeNow());
4378
}
4379
4380
async function runtime_computeNow() {
4381
let queue = [],
4382
variables,
4383
variable,
4384
precomputes = this._precomputes;
4385
4386
// If there are any paused generators, resume them before computing so they
4387
// can update (if synchronous) before computing downstream variables.
4388
if (precomputes.length) {
4389
this._precomputes = [];
4390
for (const callback of precomputes) callback();
4391
await runtime_defer(3);
4392
}
4393
4394
// Compute the reachability of the transitive closure of dirty variables.
4395
// Any newly-reachable variable must also be recomputed.
4396
// Any no-longer-reachable variable must be terminated.
4397
variables = new Set(this._dirty);
4398
variables.forEach(function(variable) {
4399
variable._inputs.forEach(variables.add, variables);
4400
const reachable = variable_reachable(variable);
4401
if (reachable > variable._reachable) {
4402
this._updates.add(variable);
4403
} else if (reachable < variable._reachable) {
4404
variable._invalidate();
4405
}
4406
variable._reachable = reachable;
4407
}, this);
4408
4409
// Compute the transitive closure of updating, reachable variables.
4410
variables = new Set(this._updates);
4411
variables.forEach(function(variable) {
4412
if (variable._reachable) {
4413
variable._indegree = 0;
4414
variable._outputs.forEach(variables.add, variables);
4415
} else {
4416
variable._indegree = NaN;
4417
variables.delete(variable);
4418
}
4419
});
4420
4421
this._computing = null;
4422
this._updates.clear();
4423
this._dirty.clear();
4424
4425
// Compute the indegree of updating variables.
4426
variables.forEach(function(variable) {
4427
variable._outputs.forEach(variable_increment);
4428
});
4429
4430
do {
4431
// Identify the root variables (those with no updating inputs).
4432
variables.forEach(function(variable) {
4433
if (variable._indegree === 0) {
4434
queue.push(variable);
4435
}
4436
});
4437
4438
// Compute the variables in topological order.
4439
while (variable = queue.pop()) {
4440
variable_compute(variable);
4441
variable._outputs.forEach(postqueue);
4442
variables.delete(variable);
4443
}
4444
4445
// Any remaining variables are circular, or depend on them.
4446
variables.forEach(function(variable) {
4447
if (variable_circular(variable)) {
4448
variable_error(variable, new RuntimeError("circular definition"));
4449
variable._outputs.forEach(variable_decrement);
4450
variables.delete(variable);
4451
}
4452
});
4453
} while (variables.size);
4454
4455
function postqueue(variable) {
4456
if (--variable._indegree === 0) {
4457
queue.push(variable);
4458
}
4459
}
4460
}
4461
4462
// We want to give generators, if they’re defined synchronously, a chance to
4463
// update before computing downstream variables. This creates a synchronous
4464
// promise chain of the given depth that we’ll await before recomputing
4465
// downstream variables.
4466
function runtime_defer(depth = 0) {
4467
let p = Promise.resolve();
4468
for (let i = 0; i < depth; ++i) p = p.then(() => {});
4469
return p;
4470
}
4471
4472
function variable_circular(variable) {
4473
const inputs = new Set(variable._inputs);
4474
for (const i of inputs) {
4475
if (i === variable) return true;
4476
i._inputs.forEach(inputs.add, inputs);
4477
}
4478
return false;
4479
}
4480
4481
function variable_increment(variable) {
4482
++variable._indegree;
4483
}
4484
4485
function variable_decrement(variable) {
4486
--variable._indegree;
4487
}
4488
4489
function variable_value(variable) {
4490
return variable._promise.catch(variable._rejector);
4491
}
4492
4493
function variable_invalidator(variable) {
4494
return new Promise(function(resolve) {
4495
variable._invalidate = resolve;
4496
});
4497
}
4498
4499
function variable_intersector(invalidation, variable) {
4500
let node = typeof IntersectionObserver === "function" && variable._observer && variable._observer._node;
4501
let visible = !node, resolve = noop, reject = noop, promise, observer;
4502
if (node) {
4503
observer = new IntersectionObserver(([entry]) => (visible = entry.isIntersecting) && (promise = null, resolve()));
4504
observer.observe(node);
4505
invalidation.then(() => (observer.disconnect(), observer = null, reject()));
4506
}
4507
return function(value) {
4508
if (visible) return Promise.resolve(value);
4509
if (!observer) return Promise.reject();
4510
if (!promise) promise = new Promise((y, n) => (resolve = y, reject = n));
4511
return promise.then(() => value);
4512
};
4513
}
4514
4515
function variable_compute(variable) {
4516
variable._invalidate();
4517
variable._invalidate = noop;
4518
variable._pending();
4519
4520
const value0 = variable._value;
4521
const version = ++variable._version;
4522
4523
// Lazily-constructed invalidation variable; only constructed if referenced as an input.
4524
let invalidation = null;
4525
4526
// If the variable doesn’t have any inputs, we can optimize slightly.
4527
const promise = variable._promise = (variable._inputs.length
4528
? Promise.all(variable._inputs.map(variable_value)).then(define)
4529
: new Promise(resolve => resolve(variable._definition.call(value0))))
4530
.then(generate);
4531
4532
// Compute the initial value of the variable.
4533
function define(inputs) {
4534
if (variable._version !== version) throw variable_stale;
4535
4536
// Replace any reference to invalidation with the promise, lazily.
4537
for (let i = 0, n = inputs.length; i < n; ++i) {
4538
switch (inputs[i]) {
4539
case variable_invalidation: {
4540
inputs[i] = invalidation = variable_invalidator(variable);
4541
break;
4542
}
4543
case variable_visibility: {
4544
if (!invalidation) invalidation = variable_invalidator(variable);
4545
inputs[i] = variable_intersector(invalidation, variable);
4546
break;
4547
}
4548
case variable_variable: {
4549
inputs[i] = variable;
4550
break;
4551
}
4552
}
4553
}
4554
4555
return variable._definition.apply(value0, inputs);
4556
}
4557
4558
// If the value is a generator, then retrieve its first value, and dispose of
4559
// the generator if the variable is invalidated. Note that the cell may
4560
// already have been invalidated here, in which case we need to terminate the
4561
// generator immediately!
4562
function generate(value) {
4563
if (variable._version !== version) throw variable_stale;
4564
if (generatorish(value)) {
4565
(invalidation || variable_invalidator(variable)).then(variable_return(value));
4566
return variable_generate(variable, version, value);
4567
}
4568
return value;
4569
}
4570
4571
promise.then((value) => {
4572
variable._value = value;
4573
variable._fulfilled(value);
4574
}, (error) => {
4575
if (error === variable_stale || variable._version !== version) return;
4576
variable._value = undefined;
4577
variable._rejected(error);
4578
});
4579
}
4580
4581
function variable_generate(variable, version, generator) {
4582
const runtime = variable._module._runtime;
4583
let currentValue; // so that yield resolves to the yielded value
4584
4585
// Retrieve the next value from the generator; if successful, invoke the
4586
// specified callback. The returned promise resolves to the yielded value, or
4587
// to undefined if the generator is done.
4588
function compute(onfulfilled) {
4589
return new Promise(resolve => resolve(generator.next(currentValue))).then(({done, value}) => {
4590
return done ? undefined : Promise.resolve(value).then(onfulfilled);
4591
});
4592
}
4593
4594
// Retrieve the next value from the generator; if successful, fulfill the
4595
// variable, compute downstream variables, and schedule the next value to be
4596
// pulled from the generator at the start of the next animation frame. If not
4597
// successful, reject the variable, compute downstream variables, and return.
4598
function recompute() {
4599
const promise = compute((value) => {
4600
if (variable._version !== version) throw variable_stale;
4601
currentValue = value;
4602
postcompute(value, promise).then(() => runtime._precompute(recompute));
4603
variable._fulfilled(value);
4604
return value;
4605
});
4606
promise.catch((error) => {
4607
if (error === variable_stale || variable._version !== version) return;
4608
postcompute(undefined, promise);
4609
variable._rejected(error);
4610
});
4611
}
4612
4613
// After the generator fulfills or rejects, set its current value, promise,
4614
// and schedule any downstream variables for update.
4615
function postcompute(value, promise) {
4616
variable._value = value;
4617
variable._promise = promise;
4618
variable._outputs.forEach(runtime._updates.add, runtime._updates);
4619
return runtime._compute();
4620
}
4621
4622
// When retrieving the first value from the generator, the promise graph is
4623
// already established, so we only need to queue the next pull.
4624
return compute((value) => {
4625
if (variable._version !== version) throw variable_stale;
4626
currentValue = value;
4627
runtime._precompute(recompute);
4628
return value;
4629
});
4630
}
4631
4632
function variable_error(variable, error) {
4633
variable._invalidate();
4634
variable._invalidate = noop;
4635
variable._pending();
4636
++variable._version;
4637
variable._indegree = NaN;
4638
(variable._promise = Promise.reject(error)).catch(noop);
4639
variable._value = undefined;
4640
variable._rejected(error);
4641
}
4642
4643
function variable_return(generator) {
4644
return function() {
4645
generator.return();
4646
};
4647
}
4648
4649
function variable_reachable(variable) {
4650
if (variable._observer !== no_observer) return true; // Directly reachable.
4651
const outputs = new Set(variable._outputs);
4652
for (const output of outputs) {
4653
if (output._observer !== no_observer) return true;
4654
output._outputs.forEach(outputs.add, outputs);
4655
}
4656
return false;
4657
}
4658
4659
function window_global(name) {
4660
return globalThis[name];
4661
}
4662
4663
function renderHtml(string) {
4664
const template = document.createElement("template");
4665
template.innerHTML = string;
4666
return document.importNode(template.content, true);
4667
}
4668
4669
function renderSvg(string) {
4670
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
4671
g.innerHTML = string;
4672
return g;
4673
}
4674
4675
const html = Object.assign(hypertext(renderHtml, fragment => {
4676
if (fragment.firstChild === null) return null;
4677
if (fragment.firstChild === fragment.lastChild) return fragment.removeChild(fragment.firstChild);
4678
const span = document.createElement("span");
4679
span.appendChild(fragment);
4680
return span;
4681
}), {fragment: hypertext(renderHtml, fragment => fragment)});
4682
4683
Object.assign(hypertext(renderSvg, g => {
4684
if (g.firstChild === null) return null;
4685
if (g.firstChild === g.lastChild) return g.removeChild(g.firstChild);
4686
return g;
4687
}), {fragment: hypertext(renderSvg, g => {
4688
const fragment = document.createDocumentFragment();
4689
while (g.firstChild) fragment.appendChild(g.firstChild);
4690
return fragment;
4691
})});
4692
4693
const
4694
CODE_TAB = 9,
4695
CODE_LF = 10,
4696
CODE_FF = 12,
4697
CODE_CR = 13,
4698
CODE_SPACE = 32,
4699
CODE_UPPER_A = 65,
4700
CODE_UPPER_Z = 90,
4701
CODE_LOWER_A = 97,
4702
CODE_LOWER_Z = 122,
4703
CODE_LT = 60,
4704
CODE_GT = 62,
4705
CODE_SLASH = 47,
4706
CODE_DASH = 45,
4707
CODE_BANG = 33,
4708
CODE_EQ = 61,
4709
CODE_DQUOTE = 34,
4710
CODE_SQUOTE = 39,
4711
CODE_QUESTION = 63,
4712
STATE_DATA = 1,
4713
STATE_TAG_OPEN = 2,
4714
STATE_END_TAG_OPEN = 3,
4715
STATE_TAG_NAME = 4,
4716
STATE_BOGUS_COMMENT = 5,
4717
STATE_BEFORE_ATTRIBUTE_NAME = 6,
4718
STATE_AFTER_ATTRIBUTE_NAME = 7,
4719
STATE_ATTRIBUTE_NAME = 8,
4720
STATE_BEFORE_ATTRIBUTE_VALUE = 9,
4721
STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED = 10,
4722
STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED = 11,
4723
STATE_ATTRIBUTE_VALUE_UNQUOTED = 12,
4724
STATE_AFTER_ATTRIBUTE_VALUE_QUOTED = 13,
4725
STATE_SELF_CLOSING_START_TAG = 14,
4726
STATE_COMMENT_START = 15,
4727
STATE_COMMENT_START_DASH = 16,
4728
STATE_COMMENT = 17,
4729
STATE_COMMENT_LESS_THAN_SIGN = 18,
4730
STATE_COMMENT_LESS_THAN_SIGN_BANG = 19,
4731
STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH = 20,
4732
STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH = 21,
4733
STATE_COMMENT_END_DASH = 22,
4734
STATE_COMMENT_END = 23,
4735
STATE_COMMENT_END_BANG = 24,
4736
STATE_MARKUP_DECLARATION_OPEN = 25,
4737
STATE_RAWTEXT = 26,
4738
STATE_RAWTEXT_LESS_THAN_SIGN = 27,
4739
STATE_RAWTEXT_END_TAG_OPEN = 28,
4740
STATE_RAWTEXT_END_TAG_NAME = 29,
4741
SHOW_COMMENT = 128,
4742
SHOW_ELEMENT = 1,
4743
TYPE_COMMENT = 8,
4744
TYPE_ELEMENT = 1,
4745
NS_SVG = "http://www.w3.org/2000/svg",
4746
NS_XLINK = "http://www.w3.org/1999/xlink",
4747
NS_XML = "http://www.w3.org/XML/1998/namespace",
4748
NS_XMLNS = "http://www.w3.org/2000/xmlns/";
4749
4750
const svgAdjustAttributes = new Map([
4751
"attributeName",
4752
"attributeType",
4753
"baseFrequency",
4754
"baseProfile",
4755
"calcMode",
4756
"clipPathUnits",
4757
"diffuseConstant",
4758
"edgeMode",
4759
"filterUnits",
4760
"glyphRef",
4761
"gradientTransform",
4762
"gradientUnits",
4763
"kernelMatrix",
4764
"kernelUnitLength",
4765
"keyPoints",
4766
"keySplines",
4767
"keyTimes",
4768
"lengthAdjust",
4769
"limitingConeAngle",
4770
"markerHeight",
4771
"markerUnits",
4772
"markerWidth",
4773
"maskContentUnits",
4774
"maskUnits",
4775
"numOctaves",
4776
"pathLength",
4777
"patternContentUnits",
4778
"patternTransform",
4779
"patternUnits",
4780
"pointsAtX",
4781
"pointsAtY",
4782
"pointsAtZ",
4783
"preserveAlpha",
4784
"preserveAspectRatio",
4785
"primitiveUnits",
4786
"refX",
4787
"refY",
4788
"repeatCount",
4789
"repeatDur",
4790
"requiredExtensions",
4791
"requiredFeatures",
4792
"specularConstant",
4793
"specularExponent",
4794
"spreadMethod",
4795
"startOffset",
4796
"stdDeviation",
4797
"stitchTiles",
4798
"surfaceScale",
4799
"systemLanguage",
4800
"tableValues",
4801
"targetX",
4802
"targetY",
4803
"textLength",
4804
"viewBox",
4805
"viewTarget",
4806
"xChannelSelector",
4807
"yChannelSelector",
4808
"zoomAndPan"
4809
].map(name => [name.toLowerCase(), name]));
4810
4811
const svgForeignAttributes = new Map([
4812
["xlink:actuate", NS_XLINK],
4813
["xlink:arcrole", NS_XLINK],
4814
["xlink:href", NS_XLINK],
4815
["xlink:role", NS_XLINK],
4816
["xlink:show", NS_XLINK],
4817
["xlink:title", NS_XLINK],
4818
["xlink:type", NS_XLINK],
4819
["xml:lang", NS_XML],
4820
["xml:space", NS_XML],
4821
["xmlns", NS_XMLNS],
4822
["xmlns:xlink", NS_XMLNS]
4823
]);
4824
4825
function hypertext(render, postprocess) {
4826
return function({raw: strings}) {
4827
let state = STATE_DATA;
4828
let string = "";
4829
let tagNameStart; // either an open tag or an end tag
4830
let tagName; // only open; beware nesting! used only for rawtext
4831
let attributeNameStart;
4832
let attributeNameEnd;
4833
let nodeFilter = 0;
4834
4835
for (let j = 0, m = arguments.length; j < m; ++j) {
4836
const input = strings[j];
4837
4838
if (j > 0) {
4839
const value = arguments[j];
4840
switch (state) {
4841
case STATE_RAWTEXT: {
4842
if (value != null) {
4843
const text = `${value}`;
4844
if (isEscapableRawText(tagName)) {
4845
string += text.replace(/[<]/g, entity);
4846
} else if (new RegExp(`</${tagName}[\\s>/]`, "i").test(string.slice(-tagName.length - 2) + text)) {
4847
throw new Error("unsafe raw text"); // appropriate end tag
4848
} else {
4849
string += text;
4850
}
4851
}
4852
break;
4853
}
4854
case STATE_DATA: {
4855
if (value == null) ; else if (value instanceof Node
4856
|| (typeof value !== "string" && value[Symbol.iterator])
4857
|| (/(?:^|>)$/.test(strings[j - 1]) && /^(?:<|$)/.test(input))) {
4858
string += "<!--::" + j + "-->";
4859
nodeFilter |= SHOW_COMMENT;
4860
} else {
4861
string += `${value}`.replace(/[<&]/g, entity);
4862
}
4863
break;
4864
}
4865
case STATE_BEFORE_ATTRIBUTE_VALUE: {
4866
state = STATE_ATTRIBUTE_VALUE_UNQUOTED;
4867
let text;
4868
if (/^[\s>]/.test(input)) {
4869
if (value == null || value === false) {
4870
string = string.slice(0, attributeNameStart - strings[j - 1].length);
4871
break;
4872
}
4873
if (value === true || (text = `${value}`) === "") {
4874
string += "''";
4875
break;
4876
}
4877
const name = strings[j - 1].slice(attributeNameStart, attributeNameEnd);
4878
if ((name === "style" && isObjectLiteral(value)) || typeof value === "function") {
4879
string += "::" + j;
4880
nodeFilter |= SHOW_ELEMENT;
4881
break;
4882
}
4883
}
4884
if (text === undefined) text = `${value}`;
4885
if (text === "") throw new Error("unsafe unquoted empty string");
4886
string += text.replace(/^['"]|[\s>&]/g, entity);
4887
break;
4888
}
4889
case STATE_ATTRIBUTE_VALUE_UNQUOTED: {
4890
string += `${value}`.replace(/[\s>&]/g, entity);
4891
break;
4892
}
4893
case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
4894
string += `${value}`.replace(/['&]/g, entity);
4895
break;
4896
}
4897
case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
4898
string += `${value}`.replace(/["&]/g, entity);
4899
break;
4900
}
4901
case STATE_BEFORE_ATTRIBUTE_NAME: {
4902
if (isObjectLiteral(value)) {
4903
string += "::" + j + "=''";
4904
nodeFilter |= SHOW_ELEMENT;
4905
break;
4906
}
4907
throw new Error("invalid binding");
4908
}
4909
case STATE_COMMENT: break;
4910
default: throw new Error("invalid binding");
4911
}
4912
}
4913
4914
for (let i = 0, n = input.length; i < n; ++i) {
4915
const code = input.charCodeAt(i);
4916
4917
switch (state) {
4918
case STATE_DATA: {
4919
if (code === CODE_LT) {
4920
state = STATE_TAG_OPEN;
4921
}
4922
break;
4923
}
4924
case STATE_TAG_OPEN: {
4925
if (code === CODE_BANG) {
4926
state = STATE_MARKUP_DECLARATION_OPEN;
4927
} else if (code === CODE_SLASH) {
4928
state = STATE_END_TAG_OPEN;
4929
} else if (isAsciiAlphaCode(code)) {
4930
tagNameStart = i, tagName = undefined;
4931
state = STATE_TAG_NAME, --i;
4932
} else if (code === CODE_QUESTION) {
4933
state = STATE_BOGUS_COMMENT, --i;
4934
} else {
4935
state = STATE_DATA, --i;
4936
}
4937
break;
4938
}
4939
case STATE_END_TAG_OPEN: {
4940
if (isAsciiAlphaCode(code)) {
4941
state = STATE_TAG_NAME, --i;
4942
} else if (code === CODE_GT) {
4943
state = STATE_DATA;
4944
} else {
4945
state = STATE_BOGUS_COMMENT, --i;
4946
}
4947
break;
4948
}
4949
case STATE_TAG_NAME: {
4950
if (isSpaceCode(code)) {
4951
state = STATE_BEFORE_ATTRIBUTE_NAME;
4952
tagName = lower(input, tagNameStart, i);
4953
} else if (code === CODE_SLASH) {
4954
state = STATE_SELF_CLOSING_START_TAG;
4955
} else if (code === CODE_GT) {
4956
tagName = lower(input, tagNameStart, i);
4957
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
4958
}
4959
break;
4960
}
4961
case STATE_BEFORE_ATTRIBUTE_NAME: {
4962
if (isSpaceCode(code)) ; else if (code === CODE_SLASH || code === CODE_GT) {
4963
state = STATE_AFTER_ATTRIBUTE_NAME, --i;
4964
} else if (code === CODE_EQ) {
4965
state = STATE_ATTRIBUTE_NAME;
4966
attributeNameStart = i + 1, attributeNameEnd = undefined;
4967
} else {
4968
state = STATE_ATTRIBUTE_NAME, --i;
4969
attributeNameStart = i + 1, attributeNameEnd = undefined;
4970
}
4971
break;
4972
}
4973
case STATE_ATTRIBUTE_NAME: {
4974
if (isSpaceCode(code) || code === CODE_SLASH || code === CODE_GT) {
4975
state = STATE_AFTER_ATTRIBUTE_NAME, --i;
4976
attributeNameEnd = i;
4977
} else if (code === CODE_EQ) {
4978
state = STATE_BEFORE_ATTRIBUTE_VALUE;
4979
attributeNameEnd = i;
4980
}
4981
break;
4982
}
4983
case STATE_AFTER_ATTRIBUTE_NAME: {
4984
if (isSpaceCode(code)) ; else if (code === CODE_SLASH) {
4985
state = STATE_SELF_CLOSING_START_TAG;
4986
} else if (code === CODE_EQ) {
4987
state = STATE_BEFORE_ATTRIBUTE_VALUE;
4988
} else if (code === CODE_GT) {
4989
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
4990
} else {
4991
state = STATE_ATTRIBUTE_NAME, --i;
4992
attributeNameStart = i + 1, attributeNameEnd = undefined;
4993
}
4994
break;
4995
}
4996
case STATE_BEFORE_ATTRIBUTE_VALUE: {
4997
if (isSpaceCode(code)) ; else if (code === CODE_DQUOTE) {
4998
state = STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
4999
} else if (code === CODE_SQUOTE) {
5000
state = STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED;
5001
} else if (code === CODE_GT) {
5002
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
5003
} else {
5004
state = STATE_ATTRIBUTE_VALUE_UNQUOTED, --i;
5005
}
5006
break;
5007
}
5008
case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
5009
if (code === CODE_DQUOTE) {
5010
state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
5011
}
5012
break;
5013
}
5014
case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
5015
if (code === CODE_SQUOTE) {
5016
state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
5017
}
5018
break;
5019
}
5020
case STATE_ATTRIBUTE_VALUE_UNQUOTED: {
5021
if (isSpaceCode(code)) {
5022
state = STATE_BEFORE_ATTRIBUTE_NAME;
5023
} else if (code === CODE_GT) {
5024
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
5025
}
5026
break;
5027
}
5028
case STATE_AFTER_ATTRIBUTE_VALUE_QUOTED: {
5029
if (isSpaceCode(code)) {
5030
state = STATE_BEFORE_ATTRIBUTE_NAME;
5031
} else if (code === CODE_SLASH) {
5032
state = STATE_SELF_CLOSING_START_TAG;
5033
} else if (code === CODE_GT) {
5034
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
5035
} else {
5036
state = STATE_BEFORE_ATTRIBUTE_NAME, --i;
5037
}
5038
break;
5039
}
5040
case STATE_SELF_CLOSING_START_TAG: {
5041
if (code === CODE_GT) {
5042
state = STATE_DATA;
5043
} else {
5044
state = STATE_BEFORE_ATTRIBUTE_NAME, --i;
5045
}
5046
break;
5047
}
5048
case STATE_BOGUS_COMMENT: {
5049
if (code === CODE_GT) {
5050
state = STATE_DATA;
5051
}
5052
break;
5053
}
5054
case STATE_COMMENT_START: {
5055
if (code === CODE_DASH) {
5056
state = STATE_COMMENT_START_DASH;
5057
} else if (code === CODE_GT) {
5058
state = STATE_DATA;
5059
} else {
5060
state = STATE_COMMENT, --i;
5061
}
5062
break;
5063
}
5064
case STATE_COMMENT_START_DASH: {
5065
if (code === CODE_DASH) {
5066
state = STATE_COMMENT_END;
5067
} else if (code === CODE_GT) {
5068
state = STATE_DATA;
5069
} else {
5070
state = STATE_COMMENT, --i;
5071
}
5072
break;
5073
}
5074
case STATE_COMMENT: {
5075
if (code === CODE_LT) {
5076
state = STATE_COMMENT_LESS_THAN_SIGN;
5077
} else if (code === CODE_DASH) {
5078
state = STATE_COMMENT_END_DASH;
5079
}
5080
break;
5081
}
5082
case STATE_COMMENT_LESS_THAN_SIGN: {
5083
if (code === CODE_BANG) {
5084
state = STATE_COMMENT_LESS_THAN_SIGN_BANG;
5085
} else if (code !== CODE_LT) {
5086
state = STATE_COMMENT, --i;
5087
}
5088
break;
5089
}
5090
case STATE_COMMENT_LESS_THAN_SIGN_BANG: {
5091
if (code === CODE_DASH) {
5092
state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH;
5093
} else {
5094
state = STATE_COMMENT, --i;
5095
}
5096
break;
5097
}
5098
case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH: {
5099
if (code === CODE_DASH) {
5100
state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
5101
} else {
5102
state = STATE_COMMENT_END, --i;
5103
}
5104
break;
5105
}
5106
case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: {
5107
state = STATE_COMMENT_END, --i;
5108
break;
5109
}
5110
case STATE_COMMENT_END_DASH: {
5111
if (code === CODE_DASH) {
5112
state = STATE_COMMENT_END;
5113
} else {
5114
state = STATE_COMMENT, --i;
5115
}
5116
break;
5117
}
5118
case STATE_COMMENT_END: {
5119
if (code === CODE_GT) {
5120
state = STATE_DATA;
5121
} else if (code === CODE_BANG) {
5122
state = STATE_COMMENT_END_BANG;
5123
} else if (code !== CODE_DASH) {
5124
state = STATE_COMMENT, --i;
5125
}
5126
break;
5127
}
5128
case STATE_COMMENT_END_BANG: {
5129
if (code === CODE_DASH) {
5130
state = STATE_COMMENT_END_DASH;
5131
} else if (code === CODE_GT) {
5132
state = STATE_DATA;
5133
} else {
5134
state = STATE_COMMENT, --i;
5135
}
5136
break;
5137
}
5138
case STATE_MARKUP_DECLARATION_OPEN: {
5139
if (code === CODE_DASH && input.charCodeAt(i + 1) === CODE_DASH) {
5140
state = STATE_COMMENT_START, ++i;
5141
} else { // Note: CDATA and DOCTYPE unsupported!
5142
state = STATE_BOGUS_COMMENT, --i;
5143
}
5144
break;
5145
}
5146
case STATE_RAWTEXT: {
5147
if (code === CODE_LT) {
5148
state = STATE_RAWTEXT_LESS_THAN_SIGN;
5149
}
5150
break;
5151
}
5152
case STATE_RAWTEXT_LESS_THAN_SIGN: {
5153
if (code === CODE_SLASH) {
5154
state = STATE_RAWTEXT_END_TAG_OPEN;
5155
} else {
5156
state = STATE_RAWTEXT, --i;
5157
}
5158
break;
5159
}
5160
case STATE_RAWTEXT_END_TAG_OPEN: {
5161
if (isAsciiAlphaCode(code)) {
5162
tagNameStart = i;
5163
state = STATE_RAWTEXT_END_TAG_NAME, --i;
5164
} else {
5165
state = STATE_RAWTEXT, --i;
5166
}
5167
break;
5168
}
5169
case STATE_RAWTEXT_END_TAG_NAME: {
5170
if (isSpaceCode(code) && tagName === lower(input, tagNameStart, i)) {
5171
state = STATE_BEFORE_ATTRIBUTE_NAME;
5172
} else if (code === CODE_SLASH && tagName === lower(input, tagNameStart, i)) {
5173
state = STATE_SELF_CLOSING_START_TAG;
5174
} else if (code === CODE_GT && tagName === lower(input, tagNameStart, i)) {
5175
state = STATE_DATA;
5176
} else if (!isAsciiAlphaCode(code)) {
5177
state = STATE_RAWTEXT, --i;
5178
}
5179
break;
5180
}
5181
default: {
5182
state = undefined;
5183
break;
5184
}
5185
}
5186
}
5187
5188
string += input;
5189
}
5190
5191
const root = render(string);
5192
5193
const walker = document.createTreeWalker(root, nodeFilter, null, false);
5194
const removeNodes = [];
5195
while (walker.nextNode()) {
5196
const node = walker.currentNode;
5197
switch (node.nodeType) {
5198
case TYPE_ELEMENT: {
5199
const attributes = node.attributes;
5200
for (let i = 0, n = attributes.length; i < n; ++i) {
5201
const {name, value: currentValue} = attributes[i];
5202
if (/^::/.test(name)) {
5203
const value = arguments[+name.slice(2)];
5204
removeAttribute(node, name), --i, --n;
5205
for (const key in value) {
5206
const subvalue = value[key];
5207
if (subvalue == null || subvalue === false) ; else if (typeof subvalue === "function") {
5208
node[key] = subvalue;
5209
} else if (key === "style" && isObjectLiteral(subvalue)) {
5210
setStyles(node[key], subvalue);
5211
} else {
5212
setAttribute(node, key, subvalue === true ? "" : subvalue);
5213
}
5214
}
5215
} else if (/^::/.test(currentValue)) {
5216
const value = arguments[+currentValue.slice(2)];
5217
removeAttribute(node, name), --i, --n;
5218
if (typeof value === "function") {
5219
node[name] = value;
5220
} else { // style
5221
setStyles(node[name], value);
5222
}
5223
}
5224
}
5225
break;
5226
}
5227
case TYPE_COMMENT: {
5228
if (/^::/.test(node.data)) {
5229
const parent = node.parentNode;
5230
const value = arguments[+node.data.slice(2)];
5231
if (value instanceof Node) {
5232
parent.insertBefore(value, node);
5233
} else if (typeof value !== "string" && value[Symbol.iterator]) {
5234
if (value instanceof NodeList || value instanceof HTMLCollection) {
5235
for (let i = value.length - 1, r = node; i >= 0; --i) {
5236
r = parent.insertBefore(value[i], r);
5237
}
5238
} else {
5239
for (const subvalue of value) {
5240
if (subvalue == null) continue;
5241
parent.insertBefore(subvalue instanceof Node ? subvalue : document.createTextNode(subvalue), node);
5242
}
5243
}
5244
} else {
5245
parent.insertBefore(document.createTextNode(value), node);
5246
}
5247
removeNodes.push(node);
5248
}
5249
break;
5250
}
5251
}
5252
}
5253
5254
for (const node of removeNodes) {
5255
node.parentNode.removeChild(node);
5256
}
5257
5258
return postprocess(root);
5259
};
5260
}
5261
5262
function entity(character) {
5263
return `&#${character.charCodeAt(0).toString()};`;
5264
}
5265
5266
function isAsciiAlphaCode(code) {
5267
return (CODE_UPPER_A <= code && code <= CODE_UPPER_Z)
5268
|| (CODE_LOWER_A <= code && code <= CODE_LOWER_Z);
5269
}
5270
5271
function isSpaceCode(code) {
5272
return code === CODE_TAB
5273
|| code === CODE_LF
5274
|| code === CODE_FF
5275
|| code === CODE_SPACE
5276
|| code === CODE_CR; // normalize newlines
5277
}
5278
5279
function isObjectLiteral(value) {
5280
return value && value.toString === Object.prototype.toString;
5281
}
5282
5283
function isRawText(tagName) {
5284
return tagName === "script" || tagName === "style" || isEscapableRawText(tagName);
5285
}
5286
5287
function isEscapableRawText(tagName) {
5288
return tagName === "textarea" || tagName === "title";
5289
}
5290
5291
function lower(input, start, end) {
5292
return input.slice(start, end).toLowerCase();
5293
}
5294
5295
function setAttribute(node, name, value) {
5296
if (node.namespaceURI === NS_SVG) {
5297
name = name.toLowerCase();
5298
name = svgAdjustAttributes.get(name) || name;
5299
if (svgForeignAttributes.has(name)) {
5300
node.setAttributeNS(svgForeignAttributes.get(name), name, value);
5301
return;
5302
}
5303
}
5304
node.setAttribute(name, value);
5305
}
5306
5307
function removeAttribute(node, name) {
5308
if (node.namespaceURI === NS_SVG) {
5309
name = name.toLowerCase();
5310
name = svgAdjustAttributes.get(name) || name;
5311
if (svgForeignAttributes.has(name)) {
5312
node.removeAttributeNS(svgForeignAttributes.get(name), name);
5313
return;
5314
}
5315
}
5316
node.removeAttribute(name);
5317
}
5318
5319
// We can’t use Object.assign because custom properties…
5320
function setStyles(style, values) {
5321
for (const name in values) {
5322
const value = values[name];
5323
if (name.startsWith("--")) style.setProperty(name, value);
5324
else style[name] = value;
5325
}
5326
}
5327
5328
function length(x) {
5329
return x == null ? null : typeof x === "number" ? `${x}px` : `${x}`;
5330
}
5331
5332
const bubbles = {bubbles: true};
5333
5334
function preventDefault(event) {
5335
event.preventDefault();
5336
}
5337
5338
function dispatchInput({currentTarget}) {
5339
(currentTarget.form || currentTarget).dispatchEvent(new Event("input", bubbles));
5340
}
5341
5342
function identity(x) {
5343
return x;
5344
}
5345
5346
let nextId = 0;
5347
5348
function newId() {
5349
return `__ns__-${++nextId}`;
5350
}
5351
5352
function maybeLabel(label, input) {
5353
if (!label) return;
5354
label = html`<label>${label}`;
5355
if (input !== undefined) label.htmlFor = input.id = newId();
5356
return label;
5357
}
5358
5359
function button(content = "≡", {
5360
label = "",
5361
value,
5362
reduce,
5363
disabled,
5364
required = false,
5365
width
5366
} = {}) {
5367
const solitary = typeof content === "string" || content instanceof Node;
5368
if (solitary) {
5369
if (!required && value === undefined) value = 0;
5370
if (reduce === undefined) reduce = (value = 0) => value + 1;
5371
disabled = new Set(disabled ? [content] : []);
5372
content = [[content, reduce]];
5373
} else {
5374
if (!required && value === undefined) value = null;
5375
disabled = new Set(disabled === true ? Array.from(content, ([content]) => content) : disabled || undefined);
5376
}
5377
const form = html`<form class=__ns__ onsubmit=${preventDefault}>`;
5378
const style = {width: length(width)};
5379
const buttons = Array.from(content, ([content, reduce = identity]) => {
5380
if (typeof reduce !== "function") throw new TypeError("reduce is not a function");
5381
return html`<button disabled=${disabled.has(content)} style=${style} onclick=${event => {
5382
form.value = reduce(form.value);
5383
dispatchInput(event);
5384
}}>${content}`;
5385
});
5386
if (label = maybeLabel(label, solitary ? buttons[0] : undefined)) form.append(label);
5387
form.append(...buttons);
5388
form.value = value;
5389
return form;
5390
}
5391
5392
const formatLocaleAuto = localize(locale => {
5393
const formatNumber = formatLocaleNumber(locale);
5394
return value => value == null ? ""
5395
: typeof value === "number" ? formatNumber(value)
5396
: value instanceof Date ? formatDate(value)
5397
: `${value}`;
5398
});
5399
5400
const formatLocaleNumber = localize(locale => {
5401
return value => value === 0 ? "0" : value.toLocaleString(locale); // handle negative zero
5402
});
5403
5404
formatLocaleAuto();
5405
5406
formatLocaleNumber();
5407
5408
function formatDate(date) {
5409
return format(date, "Invalid Date");
5410
}
5411
5412
// Memoize the last-returned locale.
5413
function localize(f) {
5414
let key = localize, value;
5415
return (locale = "en") => locale === key ? value : (value = f(key = locale));
5416
}
5417
5418
/*
5419
* quarto-inspector.js
5420
*
5421
* Copyright (C) 2022 RStudio, PBC
5422
*
5423
*/
5424
5425
class QuartoInspector extends Inspector {
5426
constructor(node, cellAst) {
5427
super(node);
5428
this._cellAst = cellAst;
5429
}
5430
rejected(error) {
5431
console.error(`Error evaluating OJS cell\n${this._cellAst.input}\n${String(error)}`);
5432
return super.rejected(error);
5433
}
5434
}
5435
5436
/*global Shiny, $
5437
*
5438
* quarto-observable-shiny.js
5439
*
5440
* Copyright (C) 2022 RStudio, PBC
5441
*/
5442
5443
const shinyInputVars = new Set();
5444
let shinyInitialValue = {};
5445
5446
function extendObservableStdlib(lib) {
5447
class NamedVariableOutputBinding extends Shiny.OutputBinding {
5448
constructor(name, change) {
5449
super();
5450
this._name = name;
5451
this._change = change;
5452
}
5453
find(scope) {
5454
return $(scope).find("#" + this._name);
5455
}
5456
getId(el) {
5457
return el.id;
5458
}
5459
renderValue(_el, data) {
5460
this._change(data);
5461
}
5462
onValueError(el, err) {
5463
const group = `Shiny error in ${el.id}`;
5464
console.groupCollapsed(`%c${group}`, "color:red");
5465
console.log(`${err.message}`);
5466
console.log(`call: ${err.call}`);
5467
console.groupEnd(group);
5468
}
5469
}
5470
5471
$(document).on("shiny:connected", function (_event) {
5472
Object.entries(shinyInitialValue).map(([k, v]) => {
5473
window.Shiny.setInputValue(k, v);
5474
});
5475
shinyInitialValue = {};
5476
});
5477
5478
lib.shinyInput = function () {
5479
return (name) => {
5480
shinyInputVars.add(name);
5481
window._ojs.ojsConnector.mainModule.value(name)
5482
.then((val) => {
5483
if (window.Shiny && window.Shiny.setInputValue) {
5484
window.Shiny.setInputValue(name, val);
5485
} else {
5486
shinyInitialValue[name] = val;
5487
}
5488
});
5489
};
5490
};
5491
5492
lib.shinyOutput = function () {
5493
return function (name) {
5494
const dummySpan = document.createElement("div");
5495
dummySpan.id = name;
5496
dummySpan.classList.add("ojs-variable-writer");
5497
window._ojs.shinyElementRoot.appendChild(dummySpan);
5498
return lib.Generators.observe((change) => {
5499
Shiny.outputBindings.register(
5500
new NamedVariableOutputBinding(name, change),
5501
);
5502
});
5503
};
5504
};
5505
}
5506
5507
class ShinyInspector extends QuartoInspector {
5508
constructor(node, cellAst) {
5509
super(node, cellAst);
5510
}
5511
fulfilled(value, name) {
5512
if (shinyInputVars.has(name) && window.Shiny) {
5513
if (window.Shiny.setInputValue === undefined) {
5514
shinyInitialValue[name] = value;
5515
} else {
5516
window.Shiny.setInputValue(name, value);
5517
}
5518
}
5519
return super.fulfilled(value, name);
5520
}
5521
}
5522
5523
const { Generators } = new Library();
5524
5525
class OjsButtonInput /*extends ShinyInput*/ {
5526
find(_scope) {
5527
return document.querySelectorAll(".ojs-inputs-button");
5528
}
5529
5530
init(el, change) {
5531
const btn = button(el.textContent);
5532
el.innerHTML = "";
5533
el.appendChild(btn);
5534
5535
const obs = Generators.input(el.firstChild);
5536
(async function () {
5537
// throw away the first value, it doesn't count for buttons
5538
await obs.next().value;
5539
for (const x of obs) {
5540
change(await x);
5541
}
5542
})();
5543
// TODO: error handling
5544
5545
return {
5546
onSetValue: (_value) => {
5547
},
5548
dispose: () => {
5549
obs.return();
5550
},
5551
};
5552
}
5553
}
5554
5555
function initOjsShinyRuntime() {
5556
const valueSym = Symbol("value");
5557
const callbackSym = Symbol("callback");
5558
const instanceSym = Symbol("instance");
5559
// const values = new WeakMap(); // unused?
5560
5561
class BindingAdapter extends Shiny.InputBinding {
5562
constructor(x) {
5563
super();
5564
this.x = x;
5565
}
5566
5567
find(scope) {
5568
const matches = this.x.find(scope);
5569
return $(matches);
5570
}
5571
getId(el) {
5572
if (this.x.getId) {
5573
return this.x.getId(el);
5574
} else {
5575
return super.getId(el);
5576
}
5577
}
5578
initialize(el) {
5579
const changeHandler = (value) => {
5580
el[valueSym] = value;
5581
el[callbackSym]();
5582
};
5583
const instance = this.x.init(el, changeHandler);
5584
el[instanceSym] = instance;
5585
}
5586
getValue(el) {
5587
return el[valueSym];
5588
}
5589
setValue(el, value) {
5590
el[valueSym] = value;
5591
el[instanceSym].onSetValue(value);
5592
}
5593
subscribe(el, callback) {
5594
el[callbackSym] = callback;
5595
}
5596
unsubscribe(el) {
5597
el[instanceSym].dispose();
5598
}
5599
}
5600
5601
class InspectorOutputBinding extends Shiny.OutputBinding {
5602
find(scope) {
5603
return $(scope).find(".observablehq-inspector");
5604
}
5605
getId(el) {
5606
return el.id;
5607
}
5608
renderValue(el, data) {
5609
(new Inspector(el)).fulfilled(data);
5610
}
5611
}
5612
5613
if (window.Shiny === undefined) {
5614
console.warn("Shiny runtime not found; Shiny features won't work.");
5615
return false;
5616
}
5617
5618
Shiny.inputBindings.register(new BindingAdapter(new OjsButtonInput()));
5619
Shiny.outputBindings.register(new InspectorOutputBinding());
5620
5621
// Handle requests from the server to export Shiny outputs to ojs.
5622
Shiny.addCustomMessageHandler("ojs-export", ({ name }) => {
5623
window._ojs.ojsConnector.mainModule.redefine(
5624
name,
5625
window._ojs.ojsConnector.library.shinyOutput()(name),
5626
);
5627
// shinyOutput() creates an output DOM element, but we have to cause it to
5628
// be actually bound. I don't love this code being here, I'd prefer if we
5629
// could receive Shiny outputs without using output bindings at all (for
5630
// this case, not for things that truly are DOM-oriented outputs).
5631
Shiny.bindAll(document.body);
5632
});
5633
5634
return true;
5635
}
5636
5637
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5638
5639
var dist = {exports: {}};
5640
5641
(function (module, exports) {
5642
(function(g,f){f(exports);}(commonjsGlobal,(function(exports){
5643
var reservedWords = {
5644
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",
5645
5: "class enum extends super const export import",
5646
6: "enum",
5647
strict: "implements interface let package private protected public static yield",
5648
strictBind: "eval arguments"
5649
};
5650
5651
// And the keywords
5652
5653
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";
5654
5655
var keywords = {
5656
5: ecma5AndLessKeywords,
5657
"5module": ecma5AndLessKeywords + " export import",
5658
6: ecma5AndLessKeywords + " const class extends export import super"
5659
};
5660
5661
var keywordRelationalOperator = /^in(stanceof)?$/;
5662
5663
// ## Character categories
5664
5665
// Big ugly regular expressions that match characters in the
5666
// whitespace, identifier, and identifier-start categories. These
5667
// are only applied when a character is found to actually have a
5668
// code point above 128.
5669
// Generated by `bin/generate-identifier-regex.js`.
5670
var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\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-\u08c7\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\u0d04-\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-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\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-\uab69\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";
5671
var nonASCIIidentifierChars = "\u200c\u200d\xb7\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\u0b55-\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\u0d81-\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\u1abf\u1ac0\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\ua82c\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";
5672
5673
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
5674
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
5675
5676
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
5677
5678
// These are a run-length and offset encoded representation of the
5679
// >0xffff code points that are a valid part of identifiers. The
5680
// offset starts at 0x10000, and each pair of numbers represents an
5681
// offset to the next range, and then a size of the range. They were
5682
// generated by bin/generate-identifier-regex.js
5683
5684
// eslint-disable-next-line comma-spacing
5685
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,349,41,7,1,79,28,11,0,9,21,107,20,28,22,13,52,76,44,33,24,27,35,30,0,3,0,9,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,2,31,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,14,0,72,26,230,43,117,63,32,7,3,0,3,7,2,1,2,23,16,0,2,0,95,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,190,0,80,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,1237,43,8,8952,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,42717,35,4148,12,221,3,5761,15,7472,3104,541,1507,4938];
5686
5687
// eslint-disable-next-line comma-spacing
5688
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,370,1,154,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,2,11,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,71,5,2,1,3,3,2,0,2,1,13,9,120,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,82,0,12,1,19628,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,4759,9,787719,239];
5689
5690
// This has a complexity linear to the value of the code. The
5691
// assumption is that looking up astral identifier characters is
5692
// rare.
5693
function isInAstralSet(code, set) {
5694
var pos = 0x10000;
5695
for (var i = 0; i < set.length; i += 2) {
5696
pos += set[i];
5697
if (pos > code) { return false }
5698
pos += set[i + 1];
5699
if (pos >= code) { return true }
5700
}
5701
}
5702
5703
// Test whether a given character code starts an identifier.
5704
5705
function isIdentifierStart(code, astral) {
5706
if (code < 65) { return code === 36 }
5707
if (code < 91) { return true }
5708
if (code < 97) { return code === 95 }
5709
if (code < 123) { return true }
5710
if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
5711
if (astral === false) { return false }
5712
return isInAstralSet(code, astralIdentifierStartCodes)
5713
}
5714
5715
// Test whether a given character is part of an identifier.
5716
5717
function isIdentifierChar(code, astral) {
5718
if (code < 48) { return code === 36 }
5719
if (code < 58) { return true }
5720
if (code < 65) { return false }
5721
if (code < 91) { return true }
5722
if (code < 97) { return code === 95 }
5723
if (code < 123) { return true }
5724
if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
5725
if (astral === false) { return false }
5726
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
5727
}
5728
5729
// ## Token types
5730
5731
// The assignment of fine-grained, information-carrying type objects
5732
// allows the tokenizer to store the information it has about a
5733
// token in a way that is very cheap for the parser to look up.
5734
5735
// All token type variables start with an underscore, to make them
5736
// easy to recognize.
5737
5738
// The `beforeExpr` property is used to disambiguate between regular
5739
// expressions and divisions. It is set on all token types that can
5740
// be followed by an expression (thus, a slash after them would be a
5741
// regular expression).
5742
//
5743
// The `startsExpr` property is used to check if the token ends a
5744
// `yield` expression. It is set on all token types that either can
5745
// directly start an expression (like a quotation mark) or can
5746
// continue an expression (like the body of a string).
5747
//
5748
// `isLoop` marks a keyword as starting a loop, which is important
5749
// to know when parsing a label, in order to allow or disallow
5750
// continue jumps to that label.
5751
5752
var TokenType = function TokenType(label, conf) {
5753
if ( conf === void 0 ) conf = {};
5754
5755
this.label = label;
5756
this.keyword = conf.keyword;
5757
this.beforeExpr = !!conf.beforeExpr;
5758
this.startsExpr = !!conf.startsExpr;
5759
this.isLoop = !!conf.isLoop;
5760
this.isAssign = !!conf.isAssign;
5761
this.prefix = !!conf.prefix;
5762
this.postfix = !!conf.postfix;
5763
this.binop = conf.binop || null;
5764
this.updateContext = null;
5765
};
5766
5767
function binop(name, prec) {
5768
return new TokenType(name, {beforeExpr: true, binop: prec})
5769
}
5770
var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
5771
5772
// Map keyword names to token types.
5773
5774
var keywords$1 = {};
5775
5776
// Succinct definitions of keyword token types
5777
function kw(name, options) {
5778
if ( options === void 0 ) options = {};
5779
5780
options.keyword = name;
5781
return keywords$1[name] = new TokenType(name, options)
5782
}
5783
5784
var types = {
5785
num: new TokenType("num", startsExpr),
5786
regexp: new TokenType("regexp", startsExpr),
5787
string: new TokenType("string", startsExpr),
5788
name: new TokenType("name", startsExpr),
5789
eof: new TokenType("eof"),
5790
5791
// Punctuation token types.
5792
bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
5793
bracketR: new TokenType("]"),
5794
braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
5795
braceR: new TokenType("}"),
5796
parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
5797
parenR: new TokenType(")"),
5798
comma: new TokenType(",", beforeExpr),
5799
semi: new TokenType(";", beforeExpr),
5800
colon: new TokenType(":", beforeExpr),
5801
dot: new TokenType("."),
5802
question: new TokenType("?", beforeExpr),
5803
questionDot: new TokenType("?."),
5804
arrow: new TokenType("=>", beforeExpr),
5805
template: new TokenType("template"),
5806
invalidTemplate: new TokenType("invalidTemplate"),
5807
ellipsis: new TokenType("...", beforeExpr),
5808
backQuote: new TokenType("`", startsExpr),
5809
dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
5810
5811
// Operators. These carry several kinds of properties to help the
5812
// parser use them properly (the presence of these properties is
5813
// what categorizes them as operators).
5814
//
5815
// `binop`, when present, specifies that this operator is a binary
5816
// operator, and will refer to its precedence.
5817
//
5818
// `prefix` and `postfix` mark the operator as a prefix or postfix
5819
// unary operator.
5820
//
5821
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
5822
// binary operators with a very low precedence, that should result
5823
// in AssignmentExpression nodes.
5824
5825
eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
5826
assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
5827
incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
5828
prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
5829
logicalOR: binop("||", 1),
5830
logicalAND: binop("&&", 2),
5831
bitwiseOR: binop("|", 3),
5832
bitwiseXOR: binop("^", 4),
5833
bitwiseAND: binop("&", 5),
5834
equality: binop("==/!=/===/!==", 6),
5835
relational: binop("</>/<=/>=", 7),
5836
bitShift: binop("<</>>/>>>", 8),
5837
plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
5838
modulo: binop("%", 10),
5839
star: binop("*", 10),
5840
slash: binop("/", 10),
5841
starstar: new TokenType("**", {beforeExpr: true}),
5842
coalesce: binop("??", 1),
5843
5844
// Keyword token types.
5845
_break: kw("break"),
5846
_case: kw("case", beforeExpr),
5847
_catch: kw("catch"),
5848
_continue: kw("continue"),
5849
_debugger: kw("debugger"),
5850
_default: kw("default", beforeExpr),
5851
_do: kw("do", {isLoop: true, beforeExpr: true}),
5852
_else: kw("else", beforeExpr),
5853
_finally: kw("finally"),
5854
_for: kw("for", {isLoop: true}),
5855
_function: kw("function", startsExpr),
5856
_if: kw("if"),
5857
_return: kw("return", beforeExpr),
5858
_switch: kw("switch"),
5859
_throw: kw("throw", beforeExpr),
5860
_try: kw("try"),
5861
_var: kw("var"),
5862
_const: kw("const"),
5863
_while: kw("while", {isLoop: true}),
5864
_with: kw("with"),
5865
_new: kw("new", {beforeExpr: true, startsExpr: true}),
5866
_this: kw("this", startsExpr),
5867
_super: kw("super", startsExpr),
5868
_class: kw("class", startsExpr),
5869
_extends: kw("extends", beforeExpr),
5870
_export: kw("export"),
5871
_import: kw("import", startsExpr),
5872
_null: kw("null", startsExpr),
5873
_true: kw("true", startsExpr),
5874
_false: kw("false", startsExpr),
5875
_in: kw("in", {beforeExpr: true, binop: 7}),
5876
_instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
5877
_typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
5878
_void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
5879
_delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
5880
};
5881
5882
// Matches a whole line break (where CRLF is considered a single
5883
// line break). Used to count lines.
5884
5885
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
5886
var lineBreakG = new RegExp(lineBreak.source, "g");
5887
5888
function isNewLine(code, ecma2019String) {
5889
return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))
5890
}
5891
5892
var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
5893
5894
var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
5895
5896
var ref = Object.prototype;
5897
var hasOwnProperty = ref.hasOwnProperty;
5898
var toString = ref.toString;
5899
5900
// Checks if an object has a property.
5901
5902
function has(obj, propName) {
5903
return hasOwnProperty.call(obj, propName)
5904
}
5905
5906
var isArray = Array.isArray || (function (obj) { return (
5907
toString.call(obj) === "[object Array]"
5908
); });
5909
5910
function wordsRegexp(words) {
5911
return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
5912
}
5913
5914
// These are used when `options.locations` is on, for the
5915
// `startLoc` and `endLoc` properties.
5916
5917
var Position = function Position(line, col) {
5918
this.line = line;
5919
this.column = col;
5920
};
5921
5922
Position.prototype.offset = function offset (n) {
5923
return new Position(this.line, this.column + n)
5924
};
5925
5926
var SourceLocation = function SourceLocation(p, start, end) {
5927
this.start = start;
5928
this.end = end;
5929
if (p.sourceFile !== null) { this.source = p.sourceFile; }
5930
};
5931
5932
// The `getLineInfo` function is mostly useful when the
5933
// `locations` option is off (for performance reasons) and you
5934
// want to find the line/column position for a given character
5935
// offset. `input` should be the code string that the offset refers
5936
// into.
5937
5938
function getLineInfo(input, offset) {
5939
for (var line = 1, cur = 0;;) {
5940
lineBreakG.lastIndex = cur;
5941
var match = lineBreakG.exec(input);
5942
if (match && match.index < offset) {
5943
++line;
5944
cur = match.index + match[0].length;
5945
} else {
5946
return new Position(line, offset - cur)
5947
}
5948
}
5949
}
5950
5951
// A second optional argument can be given to further configure
5952
// the parser process. These options are recognized:
5953
5954
var defaultOptions = {
5955
// `ecmaVersion` indicates the ECMAScript version to parse. Must be
5956
// either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), or 10
5957
// (2019). This influences support for strict mode, the set of
5958
// reserved words, and support for new syntax features. The default
5959
// is 10.
5960
ecmaVersion: 10,
5961
// `sourceType` indicates the mode the code should be parsed in.
5962
// Can be either `"script"` or `"module"`. This influences global
5963
// strict mode and parsing of `import` and `export` declarations.
5964
sourceType: "script",
5965
// `onInsertedSemicolon` can be a callback that will be called
5966
// when a semicolon is automatically inserted. It will be passed
5967
// the position of the comma as an offset, and if `locations` is
5968
// enabled, it is given the location as a `{line, column}` object
5969
// as second argument.
5970
onInsertedSemicolon: null,
5971
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
5972
// trailing commas.
5973
onTrailingComma: null,
5974
// By default, reserved words are only enforced if ecmaVersion >= 5.
5975
// Set `allowReserved` to a boolean value to explicitly turn this on
5976
// an off. When this option has the value "never", reserved words
5977
// and keywords can also not be used as property names.
5978
allowReserved: null,
5979
// When enabled, a return at the top level is not considered an
5980
// error.
5981
allowReturnOutsideFunction: false,
5982
// When enabled, import/export statements are not constrained to
5983
// appearing at the top of the program.
5984
allowImportExportEverywhere: false,
5985
// When enabled, await identifiers are allowed to appear at the top-level scope,
5986
// but they are still not allowed in non-async functions.
5987
allowAwaitOutsideFunction: false,
5988
// When enabled, hashbang directive in the beginning of file
5989
// is allowed and treated as a line comment.
5990
allowHashBang: false,
5991
// When `locations` is on, `loc` properties holding objects with
5992
// `start` and `end` properties in `{line, column}` form (with
5993
// line being 1-based and column 0-based) will be attached to the
5994
// nodes.
5995
locations: false,
5996
// A function can be passed as `onToken` option, which will
5997
// cause Acorn to call that function with object in the same
5998
// format as tokens returned from `tokenizer().getToken()`. Note
5999
// that you are not allowed to call the parser from the
6000
// callback—that will corrupt its internal state.
6001
onToken: null,
6002
// A function can be passed as `onComment` option, which will
6003
// cause Acorn to call that function with `(block, text, start,
6004
// end)` parameters whenever a comment is skipped. `block` is a
6005
// boolean indicating whether this is a block (`/* */`) comment,
6006
// `text` is the content of the comment, and `start` and `end` are
6007
// character offsets that denote the start and end of the comment.
6008
// When the `locations` option is on, two more parameters are
6009
// passed, the full `{line, column}` locations of the start and
6010
// end of the comments. Note that you are not allowed to call the
6011
// parser from the callback—that will corrupt its internal state.
6012
onComment: null,
6013
// Nodes have their start and end characters offsets recorded in
6014
// `start` and `end` properties (directly on the node, rather than
6015
// the `loc` object, which holds line/column data. To also add a
6016
// [semi-standardized][range] `range` property holding a `[start,
6017
// end]` array with the same numbers, set the `ranges` option to
6018
// `true`.
6019
//
6020
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
6021
ranges: false,
6022
// It is possible to parse multiple files into a single AST by
6023
// passing the tree produced by parsing the first file as
6024
// `program` option in subsequent parses. This will add the
6025
// toplevel forms of the parsed file to the `Program` (top) node
6026
// of an existing parse tree.
6027
program: null,
6028
// When `locations` is on, you can pass this to record the source
6029
// file in every node's `loc` object.
6030
sourceFile: null,
6031
// This value, if given, is stored in every node, whether
6032
// `locations` is on or off.
6033
directSourceFile: null,
6034
// When enabled, parenthesized expressions are represented by
6035
// (non-standard) ParenthesizedExpression nodes
6036
preserveParens: false
6037
};
6038
6039
// Interpret and default an options object
6040
6041
function getOptions(opts) {
6042
var options = {};
6043
6044
for (var opt in defaultOptions)
6045
{ options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
6046
6047
if (options.ecmaVersion >= 2015)
6048
{ options.ecmaVersion -= 2009; }
6049
6050
if (options.allowReserved == null)
6051
{ options.allowReserved = options.ecmaVersion < 5; }
6052
6053
if (isArray(options.onToken)) {
6054
var tokens = options.onToken;
6055
options.onToken = function (token) { return tokens.push(token); };
6056
}
6057
if (isArray(options.onComment))
6058
{ options.onComment = pushComment(options, options.onComment); }
6059
6060
return options
6061
}
6062
6063
function pushComment(options, array) {
6064
return function(block, text, start, end, startLoc, endLoc) {
6065
var comment = {
6066
type: block ? "Block" : "Line",
6067
value: text,
6068
start: start,
6069
end: end
6070
};
6071
if (options.locations)
6072
{ comment.loc = new SourceLocation(this, startLoc, endLoc); }
6073
if (options.ranges)
6074
{ comment.range = [start, end]; }
6075
array.push(comment);
6076
}
6077
}
6078
6079
// Each scope gets a bitset that may contain these flags
6080
var
6081
SCOPE_TOP = 1,
6082
SCOPE_FUNCTION = 2,
6083
SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION,
6084
SCOPE_ASYNC = 4,
6085
SCOPE_GENERATOR = 8,
6086
SCOPE_ARROW = 16,
6087
SCOPE_SIMPLE_CATCH = 32,
6088
SCOPE_SUPER = 64,
6089
SCOPE_DIRECT_SUPER = 128;
6090
6091
function functionFlags(async, generator) {
6092
return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0)
6093
}
6094
6095
// Used in checkLVal and declareName to determine the type of a binding
6096
var
6097
BIND_NONE = 0, // Not a binding
6098
BIND_VAR = 1, // Var-style binding
6099
BIND_LEXICAL = 2, // Let- or const-style binding
6100
BIND_FUNCTION = 3, // Function declaration
6101
BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
6102
BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
6103
6104
var Parser = function Parser(options, input, startPos) {
6105
this.options = options = getOptions(options);
6106
this.sourceFile = options.sourceFile;
6107
this.keywords = wordsRegexp(keywords[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
6108
var reserved = "";
6109
if (options.allowReserved !== true) {
6110
for (var v = options.ecmaVersion;; v--)
6111
{ if (reserved = reservedWords[v]) { break } }
6112
if (options.sourceType === "module") { reserved += " await"; }
6113
}
6114
this.reservedWords = wordsRegexp(reserved);
6115
var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
6116
this.reservedWordsStrict = wordsRegexp(reservedStrict);
6117
this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
6118
this.input = String(input);
6119
6120
// Used to signal to callers of `readWord1` whether the word
6121
// contained any escape sequences. This is needed because words with
6122
// escape sequences must not be interpreted as keywords.
6123
this.containsEsc = false;
6124
6125
// Set up token state
6126
6127
// The current position of the tokenizer in the input.
6128
if (startPos) {
6129
this.pos = startPos;
6130
this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
6131
this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
6132
} else {
6133
this.pos = this.lineStart = 0;
6134
this.curLine = 1;
6135
}
6136
6137
// Properties of the current token:
6138
// Its type
6139
this.type = types.eof;
6140
// For tokens that include more information than their type, the value
6141
this.value = null;
6142
// Its start and end offset
6143
this.start = this.end = this.pos;
6144
// And, if locations are used, the {line, column} object
6145
// corresponding to those offsets
6146
this.startLoc = this.endLoc = this.curPosition();
6147
6148
// Position information for the previous token
6149
this.lastTokEndLoc = this.lastTokStartLoc = null;
6150
this.lastTokStart = this.lastTokEnd = this.pos;
6151
6152
// The context stack is used to superficially track syntactic
6153
// context to predict whether a regular expression is allowed in a
6154
// given position.
6155
this.context = this.initialContext();
6156
this.exprAllowed = true;
6157
6158
// Figure out if it's a module code.
6159
this.inModule = options.sourceType === "module";
6160
this.strict = this.inModule || this.strictDirective(this.pos);
6161
6162
// Used to signify the start of a potential arrow function
6163
this.potentialArrowAt = -1;
6164
6165
// Positions to delayed-check that yield/await does not exist in default parameters.
6166
this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
6167
// Labels in scope.
6168
this.labels = [];
6169
// Thus-far undefined exports.
6170
this.undefinedExports = {};
6171
6172
// If enabled, skip leading hashbang line.
6173
if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
6174
{ this.skipLineComment(2); }
6175
6176
// Scope tracking for duplicate variable names (see scope.js)
6177
this.scopeStack = [];
6178
this.enterScope(SCOPE_TOP);
6179
6180
// For RegExp validation
6181
this.regexpState = null;
6182
};
6183
6184
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true } };
6185
6186
Parser.prototype.parse = function parse () {
6187
var node = this.options.program || this.startNode();
6188
this.nextToken();
6189
return this.parseTopLevel(node)
6190
};
6191
6192
prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION) > 0 };
6193
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR) > 0 };
6194
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC) > 0 };
6195
prototypeAccessors.allowSuper.get = function () { return (this.currentThisScope().flags & SCOPE_SUPER) > 0 };
6196
prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
6197
prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
6198
6199
// Switch to a getter for 7.0.0.
6200
Parser.prototype.inNonArrowFunction = function inNonArrowFunction () { return (this.currentThisScope().flags & SCOPE_FUNCTION) > 0 };
6201
6202
Parser.extend = function extend () {
6203
var plugins = [], len = arguments.length;
6204
while ( len-- ) plugins[ len ] = arguments[ len ];
6205
6206
var cls = this;
6207
for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
6208
return cls
6209
};
6210
6211
Parser.parse = function parse (input, options) {
6212
return new this(options, input).parse()
6213
};
6214
6215
Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
6216
var parser = new this(options, input, pos);
6217
parser.nextToken();
6218
return parser.parseExpression()
6219
};
6220
6221
Parser.tokenizer = function tokenizer (input, options) {
6222
return new this(options, input)
6223
};
6224
6225
Object.defineProperties( Parser.prototype, prototypeAccessors );
6226
6227
var pp = Parser.prototype;
6228
6229
// ## Parser utilities
6230
6231
var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/;
6232
pp.strictDirective = function(start) {
6233
for (;;) {
6234
// Try to find string literal.
6235
skipWhiteSpace.lastIndex = start;
6236
start += skipWhiteSpace.exec(this.input)[0].length;
6237
var match = literal.exec(this.input.slice(start));
6238
if (!match) { return false }
6239
if ((match[1] || match[2]) === "use strict") {
6240
skipWhiteSpace.lastIndex = start + match[0].length;
6241
var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
6242
var next = this.input.charAt(end);
6243
return next === ";" || next === "}" ||
6244
(lineBreak.test(spaceAfter[0]) &&
6245
!(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
6246
}
6247
start += match[0].length;
6248
6249
// Skip semicolon, if any.
6250
skipWhiteSpace.lastIndex = start;
6251
start += skipWhiteSpace.exec(this.input)[0].length;
6252
if (this.input[start] === ";")
6253
{ start++; }
6254
}
6255
};
6256
6257
// Predicate that tests whether the next token is of the given
6258
// type, and if yes, consumes it as a side effect.
6259
6260
pp.eat = function(type) {
6261
if (this.type === type) {
6262
this.next();
6263
return true
6264
} else {
6265
return false
6266
}
6267
};
6268
6269
// Tests whether parsed token is a contextual keyword.
6270
6271
pp.isContextual = function(name) {
6272
return this.type === types.name && this.value === name && !this.containsEsc
6273
};
6274
6275
// Consumes contextual keyword if possible.
6276
6277
pp.eatContextual = function(name) {
6278
if (!this.isContextual(name)) { return false }
6279
this.next();
6280
return true
6281
};
6282
6283
// Asserts that following token is given contextual keyword.
6284
6285
pp.expectContextual = function(name) {
6286
if (!this.eatContextual(name)) { this.unexpected(); }
6287
};
6288
6289
// Test whether a semicolon can be inserted at the current position.
6290
6291
pp.canInsertSemicolon = function() {
6292
return this.type === types.eof ||
6293
this.type === types.braceR ||
6294
lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
6295
};
6296
6297
pp.insertSemicolon = function() {
6298
if (this.canInsertSemicolon()) {
6299
if (this.options.onInsertedSemicolon)
6300
{ this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
6301
return true
6302
}
6303
};
6304
6305
// Consume a semicolon, or, failing that, see if we are allowed to
6306
// pretend that there is a semicolon at this position.
6307
6308
pp.semicolon = function() {
6309
if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
6310
};
6311
6312
pp.afterTrailingComma = function(tokType, notNext) {
6313
if (this.type === tokType) {
6314
if (this.options.onTrailingComma)
6315
{ this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
6316
if (!notNext)
6317
{ this.next(); }
6318
return true
6319
}
6320
};
6321
6322
// Expect a token of a given type. If found, consume it, otherwise,
6323
// raise an unexpected token error.
6324
6325
pp.expect = function(type) {
6326
this.eat(type) || this.unexpected();
6327
};
6328
6329
// Raise an unexpected token error.
6330
6331
pp.unexpected = function(pos) {
6332
this.raise(pos != null ? pos : this.start, "Unexpected token");
6333
};
6334
6335
function DestructuringErrors() {
6336
this.shorthandAssign =
6337
this.trailingComma =
6338
this.parenthesizedAssign =
6339
this.parenthesizedBind =
6340
this.doubleProto =
6341
-1;
6342
}
6343
6344
pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
6345
if (!refDestructuringErrors) { return }
6346
if (refDestructuringErrors.trailingComma > -1)
6347
{ this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
6348
var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
6349
if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
6350
};
6351
6352
pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
6353
if (!refDestructuringErrors) { return false }
6354
var shorthandAssign = refDestructuringErrors.shorthandAssign;
6355
var doubleProto = refDestructuringErrors.doubleProto;
6356
if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
6357
if (shorthandAssign >= 0)
6358
{ this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
6359
if (doubleProto >= 0)
6360
{ this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
6361
};
6362
6363
pp.checkYieldAwaitInDefaultParams = function() {
6364
if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
6365
{ this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
6366
if (this.awaitPos)
6367
{ this.raise(this.awaitPos, "Await expression cannot be a default value"); }
6368
};
6369
6370
pp.isSimpleAssignTarget = function(expr) {
6371
if (expr.type === "ParenthesizedExpression")
6372
{ return this.isSimpleAssignTarget(expr.expression) }
6373
return expr.type === "Identifier" || expr.type === "MemberExpression"
6374
};
6375
6376
var pp$1 = Parser.prototype;
6377
6378
// ### Statement parsing
6379
6380
// Parse a program. Initializes the parser, reads any number of
6381
// statements, and wraps them in a Program node. Optionally takes a
6382
// `program` argument. If present, the statements will be appended
6383
// to its body instead of creating a new node.
6384
6385
pp$1.parseTopLevel = function(node) {
6386
var exports = {};
6387
if (!node.body) { node.body = []; }
6388
while (this.type !== types.eof) {
6389
var stmt = this.parseStatement(null, true, exports);
6390
node.body.push(stmt);
6391
}
6392
if (this.inModule)
6393
{ for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
6394
{
6395
var name = list[i];
6396
6397
this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
6398
} }
6399
this.adaptDirectivePrologue(node.body);
6400
this.next();
6401
node.sourceType = this.options.sourceType;
6402
return this.finishNode(node, "Program")
6403
};
6404
6405
var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
6406
6407
pp$1.isLet = function(context) {
6408
if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
6409
skipWhiteSpace.lastIndex = this.pos;
6410
var skip = skipWhiteSpace.exec(this.input);
6411
var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
6412
// For ambiguous cases, determine if a LexicalDeclaration (or only a
6413
// Statement) is allowed here. If context is not empty then only a Statement
6414
// is allowed. However, `let [` is an explicit negative lookahead for
6415
// ExpressionStatement, so special-case it first.
6416
if (nextCh === 91) { return true } // '['
6417
if (context) { return false }
6418
6419
if (nextCh === 123) { return true } // '{'
6420
if (isIdentifierStart(nextCh, true)) {
6421
var pos = next + 1;
6422
while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
6423
var ident = this.input.slice(next, pos);
6424
if (!keywordRelationalOperator.test(ident)) { return true }
6425
}
6426
return false
6427
};
6428
6429
// check 'async [no LineTerminator here] function'
6430
// - 'async /*foo*/ function' is OK.
6431
// - 'async /*\n*/ function' is invalid.
6432
pp$1.isAsyncFunction = function() {
6433
if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
6434
{ return false }
6435
6436
skipWhiteSpace.lastIndex = this.pos;
6437
var skip = skipWhiteSpace.exec(this.input);
6438
var next = this.pos + skip[0].length;
6439
return !lineBreak.test(this.input.slice(this.pos, next)) &&
6440
this.input.slice(next, next + 8) === "function" &&
6441
(next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
6442
};
6443
6444
// Parse a single statement.
6445
//
6446
// If expecting a statement and finding a slash operator, parse a
6447
// regular expression literal. This is to handle cases like
6448
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
6449
// does not help.
6450
6451
pp$1.parseStatement = function(context, topLevel, exports) {
6452
var starttype = this.type, node = this.startNode(), kind;
6453
6454
if (this.isLet(context)) {
6455
starttype = types._var;
6456
kind = "let";
6457
}
6458
6459
// Most types of statements are recognized by the keyword they
6460
// start with. Many are trivial to parse, some require a bit of
6461
// complexity.
6462
6463
switch (starttype) {
6464
case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
6465
case types._debugger: return this.parseDebuggerStatement(node)
6466
case types._do: return this.parseDoStatement(node)
6467
case types._for: return this.parseForStatement(node)
6468
case types._function:
6469
// Function as sole body of either an if statement or a labeled statement
6470
// works, but not when it is part of a labeled statement that is the sole
6471
// body of an if statement.
6472
if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
6473
return this.parseFunctionStatement(node, false, !context)
6474
case types._class:
6475
if (context) { this.unexpected(); }
6476
return this.parseClass(node, true)
6477
case types._if: return this.parseIfStatement(node)
6478
case types._return: return this.parseReturnStatement(node)
6479
case types._switch: return this.parseSwitchStatement(node)
6480
case types._throw: return this.parseThrowStatement(node)
6481
case types._try: return this.parseTryStatement(node)
6482
case types._const: case types._var:
6483
kind = kind || this.value;
6484
if (context && kind !== "var") { this.unexpected(); }
6485
return this.parseVarStatement(node, kind)
6486
case types._while: return this.parseWhileStatement(node)
6487
case types._with: return this.parseWithStatement(node)
6488
case types.braceL: return this.parseBlock(true, node)
6489
case types.semi: return this.parseEmptyStatement(node)
6490
case types._export:
6491
case types._import:
6492
if (this.options.ecmaVersion > 10 && starttype === types._import) {
6493
skipWhiteSpace.lastIndex = this.pos;
6494
var skip = skipWhiteSpace.exec(this.input);
6495
var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
6496
if (nextCh === 40 || nextCh === 46) // '(' or '.'
6497
{ return this.parseExpressionStatement(node, this.parseExpression()) }
6498
}
6499
6500
if (!this.options.allowImportExportEverywhere) {
6501
if (!topLevel)
6502
{ this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
6503
if (!this.inModule)
6504
{ this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
6505
}
6506
return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
6507
6508
// If the statement does not start with a statement keyword or a
6509
// brace, it's an ExpressionStatement or LabeledStatement. We
6510
// simply start parsing an expression, and afterwards, if the
6511
// next token is a colon and the expression was a simple
6512
// Identifier node, we switch to interpreting it as a label.
6513
default:
6514
if (this.isAsyncFunction()) {
6515
if (context) { this.unexpected(); }
6516
this.next();
6517
return this.parseFunctionStatement(node, true, !context)
6518
}
6519
6520
var maybeName = this.value, expr = this.parseExpression();
6521
if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
6522
{ return this.parseLabeledStatement(node, maybeName, expr, context) }
6523
else { return this.parseExpressionStatement(node, expr) }
6524
}
6525
};
6526
6527
pp$1.parseBreakContinueStatement = function(node, keyword) {
6528
var isBreak = keyword === "break";
6529
this.next();
6530
if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
6531
else if (this.type !== types.name) { this.unexpected(); }
6532
else {
6533
node.label = this.parseIdent();
6534
this.semicolon();
6535
}
6536
6537
// Verify that there is an actual destination to break or
6538
// continue to.
6539
var i = 0;
6540
for (; i < this.labels.length; ++i) {
6541
var lab = this.labels[i];
6542
if (node.label == null || lab.name === node.label.name) {
6543
if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
6544
if (node.label && isBreak) { break }
6545
}
6546
}
6547
if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
6548
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
6549
};
6550
6551
pp$1.parseDebuggerStatement = function(node) {
6552
this.next();
6553
this.semicolon();
6554
return this.finishNode(node, "DebuggerStatement")
6555
};
6556
6557
pp$1.parseDoStatement = function(node) {
6558
this.next();
6559
this.labels.push(loopLabel);
6560
node.body = this.parseStatement("do");
6561
this.labels.pop();
6562
this.expect(types._while);
6563
node.test = this.parseParenExpression();
6564
if (this.options.ecmaVersion >= 6)
6565
{ this.eat(types.semi); }
6566
else
6567
{ this.semicolon(); }
6568
return this.finishNode(node, "DoWhileStatement")
6569
};
6570
6571
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
6572
// loop is non-trivial. Basically, we have to parse the init `var`
6573
// statement or expression, disallowing the `in` operator (see
6574
// the second parameter to `parseExpression`), and then check
6575
// whether the next token is `in` or `of`. When there is no init
6576
// part (semicolon immediately after the opening parenthesis), it
6577
// is a regular `for` loop.
6578
6579
pp$1.parseForStatement = function(node) {
6580
this.next();
6581
var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
6582
this.labels.push(loopLabel);
6583
this.enterScope(0);
6584
this.expect(types.parenL);
6585
if (this.type === types.semi) {
6586
if (awaitAt > -1) { this.unexpected(awaitAt); }
6587
return this.parseFor(node, null)
6588
}
6589
var isLet = this.isLet();
6590
if (this.type === types._var || this.type === types._const || isLet) {
6591
var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
6592
this.next();
6593
this.parseVar(init$1, true, kind);
6594
this.finishNode(init$1, "VariableDeclaration");
6595
if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
6596
if (this.options.ecmaVersion >= 9) {
6597
if (this.type === types._in) {
6598
if (awaitAt > -1) { this.unexpected(awaitAt); }
6599
} else { node.await = awaitAt > -1; }
6600
}
6601
return this.parseForIn(node, init$1)
6602
}
6603
if (awaitAt > -1) { this.unexpected(awaitAt); }
6604
return this.parseFor(node, init$1)
6605
}
6606
var refDestructuringErrors = new DestructuringErrors;
6607
var init = this.parseExpression(true, refDestructuringErrors);
6608
if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
6609
if (this.options.ecmaVersion >= 9) {
6610
if (this.type === types._in) {
6611
if (awaitAt > -1) { this.unexpected(awaitAt); }
6612
} else { node.await = awaitAt > -1; }
6613
}
6614
this.toAssignable(init, false, refDestructuringErrors);
6615
this.checkLVal(init);
6616
return this.parseForIn(node, init)
6617
} else {
6618
this.checkExpressionErrors(refDestructuringErrors, true);
6619
}
6620
if (awaitAt > -1) { this.unexpected(awaitAt); }
6621
return this.parseFor(node, init)
6622
};
6623
6624
pp$1.parseFunctionStatement = function(node, isAsync, declarationPosition) {
6625
this.next();
6626
return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
6627
};
6628
6629
pp$1.parseIfStatement = function(node) {
6630
this.next();
6631
node.test = this.parseParenExpression();
6632
// allow function declarations in branches, but only in non-strict mode
6633
node.consequent = this.parseStatement("if");
6634
node.alternate = this.eat(types._else) ? this.parseStatement("if") : null;
6635
return this.finishNode(node, "IfStatement")
6636
};
6637
6638
pp$1.parseReturnStatement = function(node) {
6639
if (!this.inFunction && !this.options.allowReturnOutsideFunction)
6640
{ this.raise(this.start, "'return' outside of function"); }
6641
this.next();
6642
6643
// In `return` (and `break`/`continue`), the keywords with
6644
// optional arguments, we eagerly look for a semicolon or the
6645
// possibility to insert one.
6646
6647
if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
6648
else { node.argument = this.parseExpression(); this.semicolon(); }
6649
return this.finishNode(node, "ReturnStatement")
6650
};
6651
6652
pp$1.parseSwitchStatement = function(node) {
6653
this.next();
6654
node.discriminant = this.parseParenExpression();
6655
node.cases = [];
6656
this.expect(types.braceL);
6657
this.labels.push(switchLabel);
6658
this.enterScope(0);
6659
6660
// Statements under must be grouped (by label) in SwitchCase
6661
// nodes. `cur` is used to keep the node that we are currently
6662
// adding statements to.
6663
6664
var cur;
6665
for (var sawDefault = false; this.type !== types.braceR;) {
6666
if (this.type === types._case || this.type === types._default) {
6667
var isCase = this.type === types._case;
6668
if (cur) { this.finishNode(cur, "SwitchCase"); }
6669
node.cases.push(cur = this.startNode());
6670
cur.consequent = [];
6671
this.next();
6672
if (isCase) {
6673
cur.test = this.parseExpression();
6674
} else {
6675
if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
6676
sawDefault = true;
6677
cur.test = null;
6678
}
6679
this.expect(types.colon);
6680
} else {
6681
if (!cur) { this.unexpected(); }
6682
cur.consequent.push(this.parseStatement(null));
6683
}
6684
}
6685
this.exitScope();
6686
if (cur) { this.finishNode(cur, "SwitchCase"); }
6687
this.next(); // Closing brace
6688
this.labels.pop();
6689
return this.finishNode(node, "SwitchStatement")
6690
};
6691
6692
pp$1.parseThrowStatement = function(node) {
6693
this.next();
6694
if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
6695
{ this.raise(this.lastTokEnd, "Illegal newline after throw"); }
6696
node.argument = this.parseExpression();
6697
this.semicolon();
6698
return this.finishNode(node, "ThrowStatement")
6699
};
6700
6701
// Reused empty array added for node fields that are always empty.
6702
6703
var empty = [];
6704
6705
pp$1.parseTryStatement = function(node) {
6706
this.next();
6707
node.block = this.parseBlock();
6708
node.handler = null;
6709
if (this.type === types._catch) {
6710
var clause = this.startNode();
6711
this.next();
6712
if (this.eat(types.parenL)) {
6713
clause.param = this.parseBindingAtom();
6714
var simple = clause.param.type === "Identifier";
6715
this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
6716
this.checkLVal(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
6717
this.expect(types.parenR);
6718
} else {
6719
if (this.options.ecmaVersion < 10) { this.unexpected(); }
6720
clause.param = null;
6721
this.enterScope(0);
6722
}
6723
clause.body = this.parseBlock(false);
6724
this.exitScope();
6725
node.handler = this.finishNode(clause, "CatchClause");
6726
}
6727
node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
6728
if (!node.handler && !node.finalizer)
6729
{ this.raise(node.start, "Missing catch or finally clause"); }
6730
return this.finishNode(node, "TryStatement")
6731
};
6732
6733
pp$1.parseVarStatement = function(node, kind) {
6734
this.next();
6735
this.parseVar(node, false, kind);
6736
this.semicolon();
6737
return this.finishNode(node, "VariableDeclaration")
6738
};
6739
6740
pp$1.parseWhileStatement = function(node) {
6741
this.next();
6742
node.test = this.parseParenExpression();
6743
this.labels.push(loopLabel);
6744
node.body = this.parseStatement("while");
6745
this.labels.pop();
6746
return this.finishNode(node, "WhileStatement")
6747
};
6748
6749
pp$1.parseWithStatement = function(node) {
6750
if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
6751
this.next();
6752
node.object = this.parseParenExpression();
6753
node.body = this.parseStatement("with");
6754
return this.finishNode(node, "WithStatement")
6755
};
6756
6757
pp$1.parseEmptyStatement = function(node) {
6758
this.next();
6759
return this.finishNode(node, "EmptyStatement")
6760
};
6761
6762
pp$1.parseLabeledStatement = function(node, maybeName, expr, context) {
6763
for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
6764
{
6765
var label = list[i$1];
6766
6767
if (label.name === maybeName)
6768
{ this.raise(expr.start, "Label '" + maybeName + "' is already declared");
6769
} }
6770
var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
6771
for (var i = this.labels.length - 1; i >= 0; i--) {
6772
var label$1 = this.labels[i];
6773
if (label$1.statementStart === node.start) {
6774
// Update information about previous labels on this node
6775
label$1.statementStart = this.start;
6776
label$1.kind = kind;
6777
} else { break }
6778
}
6779
this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
6780
node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
6781
this.labels.pop();
6782
node.label = expr;
6783
return this.finishNode(node, "LabeledStatement")
6784
};
6785
6786
pp$1.parseExpressionStatement = function(node, expr) {
6787
node.expression = expr;
6788
this.semicolon();
6789
return this.finishNode(node, "ExpressionStatement")
6790
};
6791
6792
// Parse a semicolon-enclosed block of statements, handling `"use
6793
// strict"` declarations when `allowStrict` is true (used for
6794
// function bodies).
6795
6796
pp$1.parseBlock = function(createNewLexicalScope, node, exitStrict) {
6797
if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
6798
if ( node === void 0 ) node = this.startNode();
6799
6800
node.body = [];
6801
this.expect(types.braceL);
6802
if (createNewLexicalScope) { this.enterScope(0); }
6803
while (this.type !== types.braceR) {
6804
var stmt = this.parseStatement(null);
6805
node.body.push(stmt);
6806
}
6807
if (exitStrict) { this.strict = false; }
6808
this.next();
6809
if (createNewLexicalScope) { this.exitScope(); }
6810
return this.finishNode(node, "BlockStatement")
6811
};
6812
6813
// Parse a regular `for` loop. The disambiguation code in
6814
// `parseStatement` will already have parsed the init statement or
6815
// expression.
6816
6817
pp$1.parseFor = function(node, init) {
6818
node.init = init;
6819
this.expect(types.semi);
6820
node.test = this.type === types.semi ? null : this.parseExpression();
6821
this.expect(types.semi);
6822
node.update = this.type === types.parenR ? null : this.parseExpression();
6823
this.expect(types.parenR);
6824
node.body = this.parseStatement("for");
6825
this.exitScope();
6826
this.labels.pop();
6827
return this.finishNode(node, "ForStatement")
6828
};
6829
6830
// Parse a `for`/`in` and `for`/`of` loop, which are almost
6831
// same from parser's perspective.
6832
6833
pp$1.parseForIn = function(node, init) {
6834
var isForIn = this.type === types._in;
6835
this.next();
6836
6837
if (
6838
init.type === "VariableDeclaration" &&
6839
init.declarations[0].init != null &&
6840
(
6841
!isForIn ||
6842
this.options.ecmaVersion < 8 ||
6843
this.strict ||
6844
init.kind !== "var" ||
6845
init.declarations[0].id.type !== "Identifier"
6846
)
6847
) {
6848
this.raise(
6849
init.start,
6850
((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
6851
);
6852
} else if (init.type === "AssignmentPattern") {
6853
this.raise(init.start, "Invalid left-hand side in for-loop");
6854
}
6855
node.left = init;
6856
node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
6857
this.expect(types.parenR);
6858
node.body = this.parseStatement("for");
6859
this.exitScope();
6860
this.labels.pop();
6861
return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
6862
};
6863
6864
// Parse a list of variable declarations.
6865
6866
pp$1.parseVar = function(node, isFor, kind) {
6867
node.declarations = [];
6868
node.kind = kind;
6869
for (;;) {
6870
var decl = this.startNode();
6871
this.parseVarId(decl, kind);
6872
if (this.eat(types.eq)) {
6873
decl.init = this.parseMaybeAssign(isFor);
6874
} else if (kind === "const" && !(this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
6875
this.unexpected();
6876
} else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types._in || this.isContextual("of")))) {
6877
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
6878
} else {
6879
decl.init = null;
6880
}
6881
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
6882
if (!this.eat(types.comma)) { break }
6883
}
6884
return node
6885
};
6886
6887
pp$1.parseVarId = function(decl, kind) {
6888
decl.id = this.parseBindingAtom();
6889
this.checkLVal(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
6890
};
6891
6892
var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
6893
6894
// Parse a function declaration or literal (depending on the
6895
// `statement & FUNC_STATEMENT`).
6896
6897
// Remove `allowExpressionBody` for 7.0.0, as it is only called with false
6898
pp$1.parseFunction = function(node, statement, allowExpressionBody, isAsync) {
6899
this.initFunction(node);
6900
if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
6901
if (this.type === types.star && (statement & FUNC_HANGING_STATEMENT))
6902
{ this.unexpected(); }
6903
node.generator = this.eat(types.star);
6904
}
6905
if (this.options.ecmaVersion >= 8)
6906
{ node.async = !!isAsync; }
6907
6908
if (statement & FUNC_STATEMENT) {
6909
node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types.name ? null : this.parseIdent();
6910
if (node.id && !(statement & FUNC_HANGING_STATEMENT))
6911
// If it is a regular function declaration in sloppy mode, then it is
6912
// subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
6913
// mode depends on properties of the current scope (see
6914
// treatFunctionsAsVar).
6915
{ this.checkLVal(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
6916
}
6917
6918
var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
6919
this.yieldPos = 0;
6920
this.awaitPos = 0;
6921
this.awaitIdentPos = 0;
6922
this.enterScope(functionFlags(node.async, node.generator));
6923
6924
if (!(statement & FUNC_STATEMENT))
6925
{ node.id = this.type === types.name ? this.parseIdent() : null; }
6926
6927
this.parseFunctionParams(node);
6928
this.parseFunctionBody(node, allowExpressionBody, false);
6929
6930
this.yieldPos = oldYieldPos;
6931
this.awaitPos = oldAwaitPos;
6932
this.awaitIdentPos = oldAwaitIdentPos;
6933
return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
6934
};
6935
6936
pp$1.parseFunctionParams = function(node) {
6937
this.expect(types.parenL);
6938
node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
6939
this.checkYieldAwaitInDefaultParams();
6940
};
6941
6942
// Parse a class declaration or literal (depending on the
6943
// `isStatement` parameter).
6944
6945
pp$1.parseClass = function(node, isStatement) {
6946
this.next();
6947
6948
// ecma-262 14.6 Class Definitions
6949
// A class definition is always strict mode code.
6950
var oldStrict = this.strict;
6951
this.strict = true;
6952
6953
this.parseClassId(node, isStatement);
6954
this.parseClassSuper(node);
6955
var classBody = this.startNode();
6956
var hadConstructor = false;
6957
classBody.body = [];
6958
this.expect(types.braceL);
6959
while (this.type !== types.braceR) {
6960
var element = this.parseClassElement(node.superClass !== null);
6961
if (element) {
6962
classBody.body.push(element);
6963
if (element.type === "MethodDefinition" && element.kind === "constructor") {
6964
if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
6965
hadConstructor = true;
6966
}
6967
}
6968
}
6969
this.strict = oldStrict;
6970
this.next();
6971
node.body = this.finishNode(classBody, "ClassBody");
6972
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
6973
};
6974
6975
pp$1.parseClassElement = function(constructorAllowsSuper) {
6976
var this$1$1 = this;
6977
6978
if (this.eat(types.semi)) { return null }
6979
6980
var method = this.startNode();
6981
var tryContextual = function (k, noLineBreak) {
6982
if ( noLineBreak === void 0 ) noLineBreak = false;
6983
6984
var start = this$1$1.start, startLoc = this$1$1.startLoc;
6985
if (!this$1$1.eatContextual(k)) { return false }
6986
if (this$1$1.type !== types.parenL && (!noLineBreak || !this$1$1.canInsertSemicolon())) { return true }
6987
if (method.key) { this$1$1.unexpected(); }
6988
method.computed = false;
6989
method.key = this$1$1.startNodeAt(start, startLoc);
6990
method.key.name = k;
6991
this$1$1.finishNode(method.key, "Identifier");
6992
return false
6993
};
6994
6995
method.kind = "method";
6996
method.static = tryContextual("static");
6997
var isGenerator = this.eat(types.star);
6998
var isAsync = false;
6999
if (!isGenerator) {
7000
if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
7001
isAsync = true;
7002
isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
7003
} else if (tryContextual("get")) {
7004
method.kind = "get";
7005
} else if (tryContextual("set")) {
7006
method.kind = "set";
7007
}
7008
}
7009
if (!method.key) { this.parsePropertyName(method); }
7010
var key = method.key;
7011
var allowsDirectSuper = false;
7012
if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
7013
key.type === "Literal" && key.value === "constructor")) {
7014
if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
7015
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
7016
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
7017
method.kind = "constructor";
7018
allowsDirectSuper = constructorAllowsSuper;
7019
} else if (method.static && key.type === "Identifier" && key.name === "prototype") {
7020
this.raise(key.start, "Classes may not have a static property named prototype");
7021
}
7022
this.parseClassMethod(method, isGenerator, isAsync, allowsDirectSuper);
7023
if (method.kind === "get" && method.value.params.length !== 0)
7024
{ this.raiseRecoverable(method.value.start, "getter should have no params"); }
7025
if (method.kind === "set" && method.value.params.length !== 1)
7026
{ this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
7027
if (method.kind === "set" && method.value.params[0].type === "RestElement")
7028
{ this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
7029
return method
7030
};
7031
7032
pp$1.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
7033
method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
7034
return this.finishNode(method, "MethodDefinition")
7035
};
7036
7037
pp$1.parseClassId = function(node, isStatement) {
7038
if (this.type === types.name) {
7039
node.id = this.parseIdent();
7040
if (isStatement)
7041
{ this.checkLVal(node.id, BIND_LEXICAL, false); }
7042
} else {
7043
if (isStatement === true)
7044
{ this.unexpected(); }
7045
node.id = null;
7046
}
7047
};
7048
7049
pp$1.parseClassSuper = function(node) {
7050
node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
7051
};
7052
7053
// Parses module export declaration.
7054
7055
pp$1.parseExport = function(node, exports) {
7056
this.next();
7057
// export * from '...'
7058
if (this.eat(types.star)) {
7059
if (this.options.ecmaVersion >= 11) {
7060
if (this.eatContextual("as")) {
7061
node.exported = this.parseIdent(true);
7062
this.checkExport(exports, node.exported.name, this.lastTokStart);
7063
} else {
7064
node.exported = null;
7065
}
7066
}
7067
this.expectContextual("from");
7068
if (this.type !== types.string) { this.unexpected(); }
7069
node.source = this.parseExprAtom();
7070
this.semicolon();
7071
return this.finishNode(node, "ExportAllDeclaration")
7072
}
7073
if (this.eat(types._default)) { // export default ...
7074
this.checkExport(exports, "default", this.lastTokStart);
7075
var isAsync;
7076
if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
7077
var fNode = this.startNode();
7078
this.next();
7079
if (isAsync) { this.next(); }
7080
node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
7081
} else if (this.type === types._class) {
7082
var cNode = this.startNode();
7083
node.declaration = this.parseClass(cNode, "nullableID");
7084
} else {
7085
node.declaration = this.parseMaybeAssign();
7086
this.semicolon();
7087
}
7088
return this.finishNode(node, "ExportDefaultDeclaration")
7089
}
7090
// export var|const|let|function|class ...
7091
if (this.shouldParseExportStatement()) {
7092
node.declaration = this.parseStatement(null);
7093
if (node.declaration.type === "VariableDeclaration")
7094
{ this.checkVariableExport(exports, node.declaration.declarations); }
7095
else
7096
{ this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
7097
node.specifiers = [];
7098
node.source = null;
7099
} else { // export { x, y as z } [from '...']
7100
node.declaration = null;
7101
node.specifiers = this.parseExportSpecifiers(exports);
7102
if (this.eatContextual("from")) {
7103
if (this.type !== types.string) { this.unexpected(); }
7104
node.source = this.parseExprAtom();
7105
} else {
7106
for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
7107
// check for keywords used as local names
7108
var spec = list[i];
7109
7110
this.checkUnreserved(spec.local);
7111
// check if export is defined
7112
this.checkLocalExport(spec.local);
7113
}
7114
7115
node.source = null;
7116
}
7117
this.semicolon();
7118
}
7119
return this.finishNode(node, "ExportNamedDeclaration")
7120
};
7121
7122
pp$1.checkExport = function(exports, name, pos) {
7123
if (!exports) { return }
7124
if (has(exports, name))
7125
{ this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
7126
exports[name] = true;
7127
};
7128
7129
pp$1.checkPatternExport = function(exports, pat) {
7130
var type = pat.type;
7131
if (type === "Identifier")
7132
{ this.checkExport(exports, pat.name, pat.start); }
7133
else if (type === "ObjectPattern")
7134
{ for (var i = 0, list = pat.properties; i < list.length; i += 1)
7135
{
7136
var prop = list[i];
7137
7138
this.checkPatternExport(exports, prop);
7139
} }
7140
else if (type === "ArrayPattern")
7141
{ for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
7142
var elt = list$1[i$1];
7143
7144
if (elt) { this.checkPatternExport(exports, elt); }
7145
} }
7146
else if (type === "Property")
7147
{ this.checkPatternExport(exports, pat.value); }
7148
else if (type === "AssignmentPattern")
7149
{ this.checkPatternExport(exports, pat.left); }
7150
else if (type === "RestElement")
7151
{ this.checkPatternExport(exports, pat.argument); }
7152
else if (type === "ParenthesizedExpression")
7153
{ this.checkPatternExport(exports, pat.expression); }
7154
};
7155
7156
pp$1.checkVariableExport = function(exports, decls) {
7157
if (!exports) { return }
7158
for (var i = 0, list = decls; i < list.length; i += 1)
7159
{
7160
var decl = list[i];
7161
7162
this.checkPatternExport(exports, decl.id);
7163
}
7164
};
7165
7166
pp$1.shouldParseExportStatement = function() {
7167
return this.type.keyword === "var" ||
7168
this.type.keyword === "const" ||
7169
this.type.keyword === "class" ||
7170
this.type.keyword === "function" ||
7171
this.isLet() ||
7172
this.isAsyncFunction()
7173
};
7174
7175
// Parses a comma-separated list of module exports.
7176
7177
pp$1.parseExportSpecifiers = function(exports) {
7178
var nodes = [], first = true;
7179
// export { x, y as z } [from '...']
7180
this.expect(types.braceL);
7181
while (!this.eat(types.braceR)) {
7182
if (!first) {
7183
this.expect(types.comma);
7184
if (this.afterTrailingComma(types.braceR)) { break }
7185
} else { first = false; }
7186
7187
var node = this.startNode();
7188
node.local = this.parseIdent(true);
7189
node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
7190
this.checkExport(exports, node.exported.name, node.exported.start);
7191
nodes.push(this.finishNode(node, "ExportSpecifier"));
7192
}
7193
return nodes
7194
};
7195
7196
// Parses import declaration.
7197
7198
pp$1.parseImport = function(node) {
7199
this.next();
7200
// import '...'
7201
if (this.type === types.string) {
7202
node.specifiers = empty;
7203
node.source = this.parseExprAtom();
7204
} else {
7205
node.specifiers = this.parseImportSpecifiers();
7206
this.expectContextual("from");
7207
node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
7208
}
7209
this.semicolon();
7210
return this.finishNode(node, "ImportDeclaration")
7211
};
7212
7213
// Parses a comma-separated list of module imports.
7214
7215
pp$1.parseImportSpecifiers = function() {
7216
var nodes = [], first = true;
7217
if (this.type === types.name) {
7218
// import defaultObj, { x, y as z } from '...'
7219
var node = this.startNode();
7220
node.local = this.parseIdent();
7221
this.checkLVal(node.local, BIND_LEXICAL);
7222
nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
7223
if (!this.eat(types.comma)) { return nodes }
7224
}
7225
if (this.type === types.star) {
7226
var node$1 = this.startNode();
7227
this.next();
7228
this.expectContextual("as");
7229
node$1.local = this.parseIdent();
7230
this.checkLVal(node$1.local, BIND_LEXICAL);
7231
nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
7232
return nodes
7233
}
7234
this.expect(types.braceL);
7235
while (!this.eat(types.braceR)) {
7236
if (!first) {
7237
this.expect(types.comma);
7238
if (this.afterTrailingComma(types.braceR)) { break }
7239
} else { first = false; }
7240
7241
var node$2 = this.startNode();
7242
node$2.imported = this.parseIdent(true);
7243
if (this.eatContextual("as")) {
7244
node$2.local = this.parseIdent();
7245
} else {
7246
this.checkUnreserved(node$2.imported);
7247
node$2.local = node$2.imported;
7248
}
7249
this.checkLVal(node$2.local, BIND_LEXICAL);
7250
nodes.push(this.finishNode(node$2, "ImportSpecifier"));
7251
}
7252
return nodes
7253
};
7254
7255
// Set `ExpressionStatement#directive` property for directive prologues.
7256
pp$1.adaptDirectivePrologue = function(statements) {
7257
for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
7258
statements[i].directive = statements[i].expression.raw.slice(1, -1);
7259
}
7260
};
7261
pp$1.isDirectiveCandidate = function(statement) {
7262
return (
7263
statement.type === "ExpressionStatement" &&
7264
statement.expression.type === "Literal" &&
7265
typeof statement.expression.value === "string" &&
7266
// Reject parenthesized strings.
7267
(this.input[statement.start] === "\"" || this.input[statement.start] === "'")
7268
)
7269
};
7270
7271
var pp$2 = Parser.prototype;
7272
7273
// Convert existing expression atom to assignable pattern
7274
// if possible.
7275
7276
pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {
7277
if (this.options.ecmaVersion >= 6 && node) {
7278
switch (node.type) {
7279
case "Identifier":
7280
if (this.inAsync && node.name === "await")
7281
{ this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
7282
break
7283
7284
case "ObjectPattern":
7285
case "ArrayPattern":
7286
case "RestElement":
7287
break
7288
7289
case "ObjectExpression":
7290
node.type = "ObjectPattern";
7291
if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
7292
for (var i = 0, list = node.properties; i < list.length; i += 1) {
7293
var prop = list[i];
7294
7295
this.toAssignable(prop, isBinding);
7296
// Early error:
7297
// AssignmentRestProperty[Yield, Await] :
7298
// `...` DestructuringAssignmentTarget[Yield, Await]
7299
//
7300
// It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
7301
if (
7302
prop.type === "RestElement" &&
7303
(prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
7304
) {
7305
this.raise(prop.argument.start, "Unexpected token");
7306
}
7307
}
7308
break
7309
7310
case "Property":
7311
// AssignmentProperty has type === "Property"
7312
if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
7313
this.toAssignable(node.value, isBinding);
7314
break
7315
7316
case "ArrayExpression":
7317
node.type = "ArrayPattern";
7318
if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
7319
this.toAssignableList(node.elements, isBinding);
7320
break
7321
7322
case "SpreadElement":
7323
node.type = "RestElement";
7324
this.toAssignable(node.argument, isBinding);
7325
if (node.argument.type === "AssignmentPattern")
7326
{ this.raise(node.argument.start, "Rest elements cannot have a default value"); }
7327
break
7328
7329
case "AssignmentExpression":
7330
if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
7331
node.type = "AssignmentPattern";
7332
delete node.operator;
7333
this.toAssignable(node.left, isBinding);
7334
// falls through to AssignmentPattern
7335
7336
case "AssignmentPattern":
7337
break
7338
7339
case "ParenthesizedExpression":
7340
this.toAssignable(node.expression, isBinding, refDestructuringErrors);
7341
break
7342
7343
case "ChainExpression":
7344
this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
7345
break
7346
7347
case "MemberExpression":
7348
if (!isBinding) { break }
7349
7350
default:
7351
this.raise(node.start, "Assigning to rvalue");
7352
}
7353
} else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
7354
return node
7355
};
7356
7357
// Convert list of expression atoms to binding list.
7358
7359
pp$2.toAssignableList = function(exprList, isBinding) {
7360
var end = exprList.length;
7361
for (var i = 0; i < end; i++) {
7362
var elt = exprList[i];
7363
if (elt) { this.toAssignable(elt, isBinding); }
7364
}
7365
if (end) {
7366
var last = exprList[end - 1];
7367
if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
7368
{ this.unexpected(last.argument.start); }
7369
}
7370
return exprList
7371
};
7372
7373
// Parses spread element.
7374
7375
pp$2.parseSpread = function(refDestructuringErrors) {
7376
var node = this.startNode();
7377
this.next();
7378
node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
7379
return this.finishNode(node, "SpreadElement")
7380
};
7381
7382
pp$2.parseRestBinding = function() {
7383
var node = this.startNode();
7384
this.next();
7385
7386
// RestElement inside of a function parameter must be an identifier
7387
if (this.options.ecmaVersion === 6 && this.type !== types.name)
7388
{ this.unexpected(); }
7389
7390
node.argument = this.parseBindingAtom();
7391
7392
return this.finishNode(node, "RestElement")
7393
};
7394
7395
// Parses lvalue (assignable) atom.
7396
7397
pp$2.parseBindingAtom = function() {
7398
if (this.options.ecmaVersion >= 6) {
7399
switch (this.type) {
7400
case types.bracketL:
7401
var node = this.startNode();
7402
this.next();
7403
node.elements = this.parseBindingList(types.bracketR, true, true);
7404
return this.finishNode(node, "ArrayPattern")
7405
7406
case types.braceL:
7407
return this.parseObj(true)
7408
}
7409
}
7410
return this.parseIdent()
7411
};
7412
7413
pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
7414
var elts = [], first = true;
7415
while (!this.eat(close)) {
7416
if (first) { first = false; }
7417
else { this.expect(types.comma); }
7418
if (allowEmpty && this.type === types.comma) {
7419
elts.push(null);
7420
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
7421
break
7422
} else if (this.type === types.ellipsis) {
7423
var rest = this.parseRestBinding();
7424
this.parseBindingListItem(rest);
7425
elts.push(rest);
7426
if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
7427
this.expect(close);
7428
break
7429
} else {
7430
var elem = this.parseMaybeDefault(this.start, this.startLoc);
7431
this.parseBindingListItem(elem);
7432
elts.push(elem);
7433
}
7434
}
7435
return elts
7436
};
7437
7438
pp$2.parseBindingListItem = function(param) {
7439
return param
7440
};
7441
7442
// Parses assignment pattern around given atom if possible.
7443
7444
pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
7445
left = left || this.parseBindingAtom();
7446
if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
7447
var node = this.startNodeAt(startPos, startLoc);
7448
node.left = left;
7449
node.right = this.parseMaybeAssign();
7450
return this.finishNode(node, "AssignmentPattern")
7451
};
7452
7453
// Verify that a node is an lval — something that can be assigned
7454
// to.
7455
// bindingType can be either:
7456
// 'var' indicating that the lval creates a 'var' binding
7457
// 'let' indicating that the lval creates a lexical ('let' or 'const') binding
7458
// 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
7459
7460
pp$2.checkLVal = function(expr, bindingType, checkClashes) {
7461
if ( bindingType === void 0 ) bindingType = BIND_NONE;
7462
7463
switch (expr.type) {
7464
case "Identifier":
7465
if (bindingType === BIND_LEXICAL && expr.name === "let")
7466
{ this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
7467
if (this.strict && this.reservedWordsStrictBind.test(expr.name))
7468
{ this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
7469
if (checkClashes) {
7470
if (has(checkClashes, expr.name))
7471
{ this.raiseRecoverable(expr.start, "Argument name clash"); }
7472
checkClashes[expr.name] = true;
7473
}
7474
if (bindingType !== BIND_NONE && bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
7475
break
7476
7477
case "ChainExpression":
7478
this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
7479
break
7480
7481
case "MemberExpression":
7482
if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); }
7483
break
7484
7485
case "ObjectPattern":
7486
for (var i = 0, list = expr.properties; i < list.length; i += 1)
7487
{
7488
var prop = list[i];
7489
7490
this.checkLVal(prop, bindingType, checkClashes);
7491
}
7492
break
7493
7494
case "Property":
7495
// AssignmentProperty has type === "Property"
7496
this.checkLVal(expr.value, bindingType, checkClashes);
7497
break
7498
7499
case "ArrayPattern":
7500
for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
7501
var elem = list$1[i$1];
7502
7503
if (elem) { this.checkLVal(elem, bindingType, checkClashes); }
7504
}
7505
break
7506
7507
case "AssignmentPattern":
7508
this.checkLVal(expr.left, bindingType, checkClashes);
7509
break
7510
7511
case "RestElement":
7512
this.checkLVal(expr.argument, bindingType, checkClashes);
7513
break
7514
7515
case "ParenthesizedExpression":
7516
this.checkLVal(expr.expression, bindingType, checkClashes);
7517
break
7518
7519
default:
7520
this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
7521
}
7522
};
7523
7524
// A recursive descent parser operates by defining functions for all
7525
7526
var pp$3 = Parser.prototype;
7527
7528
// Check if property name clashes with already added.
7529
// Object/class getters and setters are not allowed to clash —
7530
// either with each other or with an init property — and in
7531
// strict mode, init properties are also not allowed to be repeated.
7532
7533
pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
7534
if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
7535
{ return }
7536
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
7537
{ return }
7538
var key = prop.key;
7539
var name;
7540
switch (key.type) {
7541
case "Identifier": name = key.name; break
7542
case "Literal": name = String(key.value); break
7543
default: return
7544
}
7545
var kind = prop.kind;
7546
if (this.options.ecmaVersion >= 6) {
7547
if (name === "__proto__" && kind === "init") {
7548
if (propHash.proto) {
7549
if (refDestructuringErrors) {
7550
if (refDestructuringErrors.doubleProto < 0)
7551
{ refDestructuringErrors.doubleProto = key.start; }
7552
// Backwards-compat kludge. Can be removed in version 6.0
7553
} else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
7554
}
7555
propHash.proto = true;
7556
}
7557
return
7558
}
7559
name = "$" + name;
7560
var other = propHash[name];
7561
if (other) {
7562
var redefinition;
7563
if (kind === "init") {
7564
redefinition = this.strict && other.init || other.get || other.set;
7565
} else {
7566
redefinition = other.init || other[kind];
7567
}
7568
if (redefinition)
7569
{ this.raiseRecoverable(key.start, "Redefinition of property"); }
7570
} else {
7571
other = propHash[name] = {
7572
init: false,
7573
get: false,
7574
set: false
7575
};
7576
}
7577
other[kind] = true;
7578
};
7579
7580
// ### Expression parsing
7581
7582
// These nest, from the most general expression type at the top to
7583
// 'atomic', nondivisible expression types at the bottom. Most of
7584
// the functions will simply let the function(s) below them parse,
7585
// and, *if* the syntactic construct they handle is present, wrap
7586
// the AST node that the inner parser gave them in another node.
7587
7588
// Parse a full expression. The optional arguments are used to
7589
// forbid the `in` operator (in for loops initalization expressions)
7590
// and provide reference for storing '=' operator inside shorthand
7591
// property assignment in contexts where both object expression
7592
// and object pattern might appear (so it's possible to raise
7593
// delayed syntax error at correct position).
7594
7595
pp$3.parseExpression = function(noIn, refDestructuringErrors) {
7596
var startPos = this.start, startLoc = this.startLoc;
7597
var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
7598
if (this.type === types.comma) {
7599
var node = this.startNodeAt(startPos, startLoc);
7600
node.expressions = [expr];
7601
while (this.eat(types.comma)) { node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors)); }
7602
return this.finishNode(node, "SequenceExpression")
7603
}
7604
return expr
7605
};
7606
7607
// Parse an assignment expression. This includes applications of
7608
// operators like `+=`.
7609
7610
pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
7611
if (this.isContextual("yield")) {
7612
if (this.inGenerator) { return this.parseYield(noIn) }
7613
// The tokenizer will assume an expression is allowed after
7614
// `yield`, but this isn't that kind of yield
7615
else { this.exprAllowed = false; }
7616
}
7617
7618
var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
7619
if (refDestructuringErrors) {
7620
oldParenAssign = refDestructuringErrors.parenthesizedAssign;
7621
oldTrailingComma = refDestructuringErrors.trailingComma;
7622
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
7623
} else {
7624
refDestructuringErrors = new DestructuringErrors;
7625
ownDestructuringErrors = true;
7626
}
7627
7628
var startPos = this.start, startLoc = this.startLoc;
7629
if (this.type === types.parenL || this.type === types.name)
7630
{ this.potentialArrowAt = this.start; }
7631
var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
7632
if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
7633
if (this.type.isAssign) {
7634
var node = this.startNodeAt(startPos, startLoc);
7635
node.operator = this.value;
7636
node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
7637
if (!ownDestructuringErrors) {
7638
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
7639
}
7640
if (refDestructuringErrors.shorthandAssign >= node.left.start)
7641
{ refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
7642
this.checkLVal(left);
7643
this.next();
7644
node.right = this.parseMaybeAssign(noIn);
7645
return this.finishNode(node, "AssignmentExpression")
7646
} else {
7647
if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
7648
}
7649
if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
7650
if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
7651
return left
7652
};
7653
7654
// Parse a ternary conditional (`?:`) operator.
7655
7656
pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
7657
var startPos = this.start, startLoc = this.startLoc;
7658
var expr = this.parseExprOps(noIn, refDestructuringErrors);
7659
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
7660
if (this.eat(types.question)) {
7661
var node = this.startNodeAt(startPos, startLoc);
7662
node.test = expr;
7663
node.consequent = this.parseMaybeAssign();
7664
this.expect(types.colon);
7665
node.alternate = this.parseMaybeAssign(noIn);
7666
return this.finishNode(node, "ConditionalExpression")
7667
}
7668
return expr
7669
};
7670
7671
// Start the precedence parser.
7672
7673
pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
7674
var startPos = this.start, startLoc = this.startLoc;
7675
var expr = this.parseMaybeUnary(refDestructuringErrors, false);
7676
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
7677
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
7678
};
7679
7680
// Parse binary operators with the operator precedence parsing
7681
// algorithm. `left` is the left-hand side of the operator.
7682
// `minPrec` provides context that allows the function to stop and
7683
// defer further parser to one of its callers when it encounters an
7684
// operator that has a lower precedence than the set it is parsing.
7685
7686
pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
7687
var prec = this.type.binop;
7688
if (prec != null && (!noIn || this.type !== types._in)) {
7689
if (prec > minPrec) {
7690
var logical = this.type === types.logicalOR || this.type === types.logicalAND;
7691
var coalesce = this.type === types.coalesce;
7692
if (coalesce) {
7693
// Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
7694
// In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
7695
prec = types.logicalAND.binop;
7696
}
7697
var op = this.value;
7698
this.next();
7699
var startPos = this.start, startLoc = this.startLoc;
7700
var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
7701
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
7702
if ((logical && this.type === types.coalesce) || (coalesce && (this.type === types.logicalOR || this.type === types.logicalAND))) {
7703
this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
7704
}
7705
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
7706
}
7707
}
7708
return left
7709
};
7710
7711
pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
7712
var node = this.startNodeAt(startPos, startLoc);
7713
node.left = left;
7714
node.operator = op;
7715
node.right = right;
7716
return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
7717
};
7718
7719
// Parse unary operators, both prefix and postfix.
7720
7721
pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
7722
var startPos = this.start, startLoc = this.startLoc, expr;
7723
if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
7724
expr = this.parseAwait();
7725
sawUnary = true;
7726
} else if (this.type.prefix) {
7727
var node = this.startNode(), update = this.type === types.incDec;
7728
node.operator = this.value;
7729
node.prefix = true;
7730
this.next();
7731
node.argument = this.parseMaybeUnary(null, true);
7732
this.checkExpressionErrors(refDestructuringErrors, true);
7733
if (update) { this.checkLVal(node.argument); }
7734
else if (this.strict && node.operator === "delete" &&
7735
node.argument.type === "Identifier")
7736
{ this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
7737
else { sawUnary = true; }
7738
expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
7739
} else {
7740
expr = this.parseExprSubscripts(refDestructuringErrors);
7741
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
7742
while (this.type.postfix && !this.canInsertSemicolon()) {
7743
var node$1 = this.startNodeAt(startPos, startLoc);
7744
node$1.operator = this.value;
7745
node$1.prefix = false;
7746
node$1.argument = expr;
7747
this.checkLVal(expr);
7748
this.next();
7749
expr = this.finishNode(node$1, "UpdateExpression");
7750
}
7751
}
7752
7753
if (!sawUnary && this.eat(types.starstar))
7754
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
7755
else
7756
{ return expr }
7757
};
7758
7759
// Parse call, dot, and `[]`-subscript expressions.
7760
7761
pp$3.parseExprSubscripts = function(refDestructuringErrors) {
7762
var startPos = this.start, startLoc = this.startLoc;
7763
var expr = this.parseExprAtom(refDestructuringErrors);
7764
if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
7765
{ return expr }
7766
var result = this.parseSubscripts(expr, startPos, startLoc);
7767
if (refDestructuringErrors && result.type === "MemberExpression") {
7768
if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
7769
if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
7770
}
7771
return result
7772
};
7773
7774
pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
7775
var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
7776
this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
7777
this.potentialArrowAt === base.start;
7778
var optionalChained = false;
7779
7780
while (true) {
7781
var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained);
7782
7783
if (element.optional) { optionalChained = true; }
7784
if (element === base || element.type === "ArrowFunctionExpression") {
7785
if (optionalChained) {
7786
var chainNode = this.startNodeAt(startPos, startLoc);
7787
chainNode.expression = element;
7788
element = this.finishNode(chainNode, "ChainExpression");
7789
}
7790
return element
7791
}
7792
7793
base = element;
7794
}
7795
};
7796
7797
pp$3.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained) {
7798
var optionalSupported = this.options.ecmaVersion >= 11;
7799
var optional = optionalSupported && this.eat(types.questionDot);
7800
if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
7801
7802
var computed = this.eat(types.bracketL);
7803
if (computed || (optional && this.type !== types.parenL && this.type !== types.backQuote) || this.eat(types.dot)) {
7804
var node = this.startNodeAt(startPos, startLoc);
7805
node.object = base;
7806
node.property = computed ? this.parseExpression() : this.parseIdent(this.options.allowReserved !== "never");
7807
node.computed = !!computed;
7808
if (computed) { this.expect(types.bracketR); }
7809
if (optionalSupported) {
7810
node.optional = optional;
7811
}
7812
base = this.finishNode(node, "MemberExpression");
7813
} else if (!noCalls && this.eat(types.parenL)) {
7814
var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
7815
this.yieldPos = 0;
7816
this.awaitPos = 0;
7817
this.awaitIdentPos = 0;
7818
var exprList = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
7819
if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types.arrow)) {
7820
this.checkPatternErrors(refDestructuringErrors, false);
7821
this.checkYieldAwaitInDefaultParams();
7822
if (this.awaitIdentPos > 0)
7823
{ this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
7824
this.yieldPos = oldYieldPos;
7825
this.awaitPos = oldAwaitPos;
7826
this.awaitIdentPos = oldAwaitIdentPos;
7827
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true)
7828
}
7829
this.checkExpressionErrors(refDestructuringErrors, true);
7830
this.yieldPos = oldYieldPos || this.yieldPos;
7831
this.awaitPos = oldAwaitPos || this.awaitPos;
7832
this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
7833
var node$1 = this.startNodeAt(startPos, startLoc);
7834
node$1.callee = base;
7835
node$1.arguments = exprList;
7836
if (optionalSupported) {
7837
node$1.optional = optional;
7838
}
7839
base = this.finishNode(node$1, "CallExpression");
7840
} else if (this.type === types.backQuote) {
7841
if (optional || optionalChained) {
7842
this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
7843
}
7844
var node$2 = this.startNodeAt(startPos, startLoc);
7845
node$2.tag = base;
7846
node$2.quasi = this.parseTemplate({isTagged: true});
7847
base = this.finishNode(node$2, "TaggedTemplateExpression");
7848
}
7849
return base
7850
};
7851
7852
// Parse an atomic expression — either a single token that is an
7853
// expression, an expression started by a keyword like `function` or
7854
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
7855
// or `{}`.
7856
7857
pp$3.parseExprAtom = function(refDestructuringErrors) {
7858
// If a division operator appears in an expression position, the
7859
// tokenizer got confused, and we force it to read a regexp instead.
7860
if (this.type === types.slash) { this.readRegexp(); }
7861
7862
var node, canBeArrow = this.potentialArrowAt === this.start;
7863
switch (this.type) {
7864
case types._super:
7865
if (!this.allowSuper)
7866
{ this.raise(this.start, "'super' keyword outside a method"); }
7867
node = this.startNode();
7868
this.next();
7869
if (this.type === types.parenL && !this.allowDirectSuper)
7870
{ this.raise(node.start, "super() call outside constructor of a subclass"); }
7871
// The `super` keyword can appear at below:
7872
// SuperProperty:
7873
// super [ Expression ]
7874
// super . IdentifierName
7875
// SuperCall:
7876
// super ( Arguments )
7877
if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
7878
{ this.unexpected(); }
7879
return this.finishNode(node, "Super")
7880
7881
case types._this:
7882
node = this.startNode();
7883
this.next();
7884
return this.finishNode(node, "ThisExpression")
7885
7886
case types.name:
7887
var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
7888
var id = this.parseIdent(false);
7889
if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
7890
{ return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true) }
7891
if (canBeArrow && !this.canInsertSemicolon()) {
7892
if (this.eat(types.arrow))
7893
{ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
7894
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
7895
id = this.parseIdent(false);
7896
if (this.canInsertSemicolon() || !this.eat(types.arrow))
7897
{ this.unexpected(); }
7898
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
7899
}
7900
}
7901
return id
7902
7903
case types.regexp:
7904
var value = this.value;
7905
node = this.parseLiteral(value.value);
7906
node.regex = {pattern: value.pattern, flags: value.flags};
7907
return node
7908
7909
case types.num: case types.string:
7910
return this.parseLiteral(this.value)
7911
7912
case types._null: case types._true: case types._false:
7913
node = this.startNode();
7914
node.value = this.type === types._null ? null : this.type === types._true;
7915
node.raw = this.type.keyword;
7916
this.next();
7917
return this.finishNode(node, "Literal")
7918
7919
case types.parenL:
7920
var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
7921
if (refDestructuringErrors) {
7922
if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
7923
{ refDestructuringErrors.parenthesizedAssign = start; }
7924
if (refDestructuringErrors.parenthesizedBind < 0)
7925
{ refDestructuringErrors.parenthesizedBind = start; }
7926
}
7927
return expr
7928
7929
case types.bracketL:
7930
node = this.startNode();
7931
this.next();
7932
node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
7933
return this.finishNode(node, "ArrayExpression")
7934
7935
case types.braceL:
7936
return this.parseObj(false, refDestructuringErrors)
7937
7938
case types._function:
7939
node = this.startNode();
7940
this.next();
7941
return this.parseFunction(node, 0)
7942
7943
case types._class:
7944
return this.parseClass(this.startNode(), false)
7945
7946
case types._new:
7947
return this.parseNew()
7948
7949
case types.backQuote:
7950
return this.parseTemplate()
7951
7952
case types._import:
7953
if (this.options.ecmaVersion >= 11) {
7954
return this.parseExprImport()
7955
} else {
7956
return this.unexpected()
7957
}
7958
7959
default:
7960
this.unexpected();
7961
}
7962
};
7963
7964
pp$3.parseExprImport = function() {
7965
var node = this.startNode();
7966
7967
// Consume `import` as an identifier for `import.meta`.
7968
// Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
7969
if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
7970
var meta = this.parseIdent(true);
7971
7972
switch (this.type) {
7973
case types.parenL:
7974
return this.parseDynamicImport(node)
7975
case types.dot:
7976
node.meta = meta;
7977
return this.parseImportMeta(node)
7978
default:
7979
this.unexpected();
7980
}
7981
};
7982
7983
pp$3.parseDynamicImport = function(node) {
7984
this.next(); // skip `(`
7985
7986
// Parse node.source.
7987
node.source = this.parseMaybeAssign();
7988
7989
// Verify ending.
7990
if (!this.eat(types.parenR)) {
7991
var errorPos = this.start;
7992
if (this.eat(types.comma) && this.eat(types.parenR)) {
7993
this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
7994
} else {
7995
this.unexpected(errorPos);
7996
}
7997
}
7998
7999
return this.finishNode(node, "ImportExpression")
8000
};
8001
8002
pp$3.parseImportMeta = function(node) {
8003
this.next(); // skip `.`
8004
8005
var containsEsc = this.containsEsc;
8006
node.property = this.parseIdent(true);
8007
8008
if (node.property.name !== "meta")
8009
{ this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
8010
if (containsEsc)
8011
{ this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
8012
if (this.options.sourceType !== "module")
8013
{ this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
8014
8015
return this.finishNode(node, "MetaProperty")
8016
};
8017
8018
pp$3.parseLiteral = function(value) {
8019
var node = this.startNode();
8020
node.value = value;
8021
node.raw = this.input.slice(this.start, this.end);
8022
if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); }
8023
this.next();
8024
return this.finishNode(node, "Literal")
8025
};
8026
8027
pp$3.parseParenExpression = function() {
8028
this.expect(types.parenL);
8029
var val = this.parseExpression();
8030
this.expect(types.parenR);
8031
return val
8032
};
8033
8034
pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
8035
var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
8036
if (this.options.ecmaVersion >= 6) {
8037
this.next();
8038
8039
var innerStartPos = this.start, innerStartLoc = this.startLoc;
8040
var exprList = [], first = true, lastIsComma = false;
8041
var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
8042
this.yieldPos = 0;
8043
this.awaitPos = 0;
8044
// Do not save awaitIdentPos to allow checking awaits nested in parameters
8045
while (this.type !== types.parenR) {
8046
first ? first = false : this.expect(types.comma);
8047
if (allowTrailingComma && this.afterTrailingComma(types.parenR, true)) {
8048
lastIsComma = true;
8049
break
8050
} else if (this.type === types.ellipsis) {
8051
spreadStart = this.start;
8052
exprList.push(this.parseParenItem(this.parseRestBinding()));
8053
if (this.type === types.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
8054
break
8055
} else {
8056
exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
8057
}
8058
}
8059
var innerEndPos = this.start, innerEndLoc = this.startLoc;
8060
this.expect(types.parenR);
8061
8062
if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
8063
this.checkPatternErrors(refDestructuringErrors, false);
8064
this.checkYieldAwaitInDefaultParams();
8065
this.yieldPos = oldYieldPos;
8066
this.awaitPos = oldAwaitPos;
8067
return this.parseParenArrowList(startPos, startLoc, exprList)
8068
}
8069
8070
if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
8071
if (spreadStart) { this.unexpected(spreadStart); }
8072
this.checkExpressionErrors(refDestructuringErrors, true);
8073
this.yieldPos = oldYieldPos || this.yieldPos;
8074
this.awaitPos = oldAwaitPos || this.awaitPos;
8075
8076
if (exprList.length > 1) {
8077
val = this.startNodeAt(innerStartPos, innerStartLoc);
8078
val.expressions = exprList;
8079
this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
8080
} else {
8081
val = exprList[0];
8082
}
8083
} else {
8084
val = this.parseParenExpression();
8085
}
8086
8087
if (this.options.preserveParens) {
8088
var par = this.startNodeAt(startPos, startLoc);
8089
par.expression = val;
8090
return this.finishNode(par, "ParenthesizedExpression")
8091
} else {
8092
return val
8093
}
8094
};
8095
8096
pp$3.parseParenItem = function(item) {
8097
return item
8098
};
8099
8100
pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
8101
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
8102
};
8103
8104
// New's precedence is slightly tricky. It must allow its argument to
8105
// be a `[]` or dot subscript expression, but not a call — at least,
8106
// not without wrapping it in parentheses. Thus, it uses the noCalls
8107
// argument to parseSubscripts to prevent it from consuming the
8108
// argument list.
8109
8110
var empty$1 = [];
8111
8112
pp$3.parseNew = function() {
8113
if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
8114
var node = this.startNode();
8115
var meta = this.parseIdent(true);
8116
if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
8117
node.meta = meta;
8118
var containsEsc = this.containsEsc;
8119
node.property = this.parseIdent(true);
8120
if (node.property.name !== "target")
8121
{ this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
8122
if (containsEsc)
8123
{ this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
8124
if (!this.inNonArrowFunction())
8125
{ this.raiseRecoverable(node.start, "'new.target' can only be used in functions"); }
8126
return this.finishNode(node, "MetaProperty")
8127
}
8128
var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types._import;
8129
node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
8130
if (isImport && node.callee.type === "ImportExpression") {
8131
this.raise(startPos, "Cannot use new with import()");
8132
}
8133
if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
8134
else { node.arguments = empty$1; }
8135
return this.finishNode(node, "NewExpression")
8136
};
8137
8138
// Parse template expression.
8139
8140
pp$3.parseTemplateElement = function(ref) {
8141
var isTagged = ref.isTagged;
8142
8143
var elem = this.startNode();
8144
if (this.type === types.invalidTemplate) {
8145
if (!isTagged) {
8146
this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
8147
}
8148
elem.value = {
8149
raw: this.value,
8150
cooked: null
8151
};
8152
} else {
8153
elem.value = {
8154
raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
8155
cooked: this.value
8156
};
8157
}
8158
this.next();
8159
elem.tail = this.type === types.backQuote;
8160
return this.finishNode(elem, "TemplateElement")
8161
};
8162
8163
pp$3.parseTemplate = function(ref) {
8164
if ( ref === void 0 ) ref = {};
8165
var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
8166
8167
var node = this.startNode();
8168
this.next();
8169
node.expressions = [];
8170
var curElt = this.parseTemplateElement({isTagged: isTagged});
8171
node.quasis = [curElt];
8172
while (!curElt.tail) {
8173
if (this.type === types.eof) { this.raise(this.pos, "Unterminated template literal"); }
8174
this.expect(types.dollarBraceL);
8175
node.expressions.push(this.parseExpression());
8176
this.expect(types.braceR);
8177
node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
8178
}
8179
this.next();
8180
return this.finishNode(node, "TemplateLiteral")
8181
};
8182
8183
pp$3.isAsyncProp = function(prop) {
8184
return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
8185
(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)) &&
8186
!lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
8187
};
8188
8189
// Parse an object literal or binding pattern.
8190
8191
pp$3.parseObj = function(isPattern, refDestructuringErrors) {
8192
var node = this.startNode(), first = true, propHash = {};
8193
node.properties = [];
8194
this.next();
8195
while (!this.eat(types.braceR)) {
8196
if (!first) {
8197
this.expect(types.comma);
8198
if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types.braceR)) { break }
8199
} else { first = false; }
8200
8201
var prop = this.parseProperty(isPattern, refDestructuringErrors);
8202
if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
8203
node.properties.push(prop);
8204
}
8205
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
8206
};
8207
8208
pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
8209
var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
8210
if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {
8211
if (isPattern) {
8212
prop.argument = this.parseIdent(false);
8213
if (this.type === types.comma) {
8214
this.raise(this.start, "Comma is not permitted after the rest element");
8215
}
8216
return this.finishNode(prop, "RestElement")
8217
}
8218
// To disallow parenthesized identifier via `this.toAssignable()`.
8219
if (this.type === types.parenL && refDestructuringErrors) {
8220
if (refDestructuringErrors.parenthesizedAssign < 0) {
8221
refDestructuringErrors.parenthesizedAssign = this.start;
8222
}
8223
if (refDestructuringErrors.parenthesizedBind < 0) {
8224
refDestructuringErrors.parenthesizedBind = this.start;
8225
}
8226
}
8227
// Parse argument.
8228
prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
8229
// To disallow trailing comma via `this.toAssignable()`.
8230
if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
8231
refDestructuringErrors.trailingComma = this.start;
8232
}
8233
// Finish
8234
return this.finishNode(prop, "SpreadElement")
8235
}
8236
if (this.options.ecmaVersion >= 6) {
8237
prop.method = false;
8238
prop.shorthand = false;
8239
if (isPattern || refDestructuringErrors) {
8240
startPos = this.start;
8241
startLoc = this.startLoc;
8242
}
8243
if (!isPattern)
8244
{ isGenerator = this.eat(types.star); }
8245
}
8246
var containsEsc = this.containsEsc;
8247
this.parsePropertyName(prop);
8248
if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
8249
isAsync = true;
8250
isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
8251
this.parsePropertyName(prop, refDestructuringErrors);
8252
} else {
8253
isAsync = false;
8254
}
8255
this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
8256
return this.finishNode(prop, "Property")
8257
};
8258
8259
pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
8260
if ((isGenerator || isAsync) && this.type === types.colon)
8261
{ this.unexpected(); }
8262
8263
if (this.eat(types.colon)) {
8264
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
8265
prop.kind = "init";
8266
} else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
8267
if (isPattern) { this.unexpected(); }
8268
prop.kind = "init";
8269
prop.method = true;
8270
prop.value = this.parseMethod(isGenerator, isAsync);
8271
} else if (!isPattern && !containsEsc &&
8272
this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
8273
(prop.key.name === "get" || prop.key.name === "set") &&
8274
(this.type !== types.comma && this.type !== types.braceR && this.type !== types.eq)) {
8275
if (isGenerator || isAsync) { this.unexpected(); }
8276
prop.kind = prop.key.name;
8277
this.parsePropertyName(prop);
8278
prop.value = this.parseMethod(false);
8279
var paramCount = prop.kind === "get" ? 0 : 1;
8280
if (prop.value.params.length !== paramCount) {
8281
var start = prop.value.start;
8282
if (prop.kind === "get")
8283
{ this.raiseRecoverable(start, "getter should have no params"); }
8284
else
8285
{ this.raiseRecoverable(start, "setter should have exactly one param"); }
8286
} else {
8287
if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
8288
{ this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
8289
}
8290
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
8291
if (isGenerator || isAsync) { this.unexpected(); }
8292
this.checkUnreserved(prop.key);
8293
if (prop.key.name === "await" && !this.awaitIdentPos)
8294
{ this.awaitIdentPos = startPos; }
8295
prop.kind = "init";
8296
if (isPattern) {
8297
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
8298
} else if (this.type === types.eq && refDestructuringErrors) {
8299
if (refDestructuringErrors.shorthandAssign < 0)
8300
{ refDestructuringErrors.shorthandAssign = this.start; }
8301
prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
8302
} else {
8303
prop.value = prop.key;
8304
}
8305
prop.shorthand = true;
8306
} else { this.unexpected(); }
8307
};
8308
8309
pp$3.parsePropertyName = function(prop) {
8310
if (this.options.ecmaVersion >= 6) {
8311
if (this.eat(types.bracketL)) {
8312
prop.computed = true;
8313
prop.key = this.parseMaybeAssign();
8314
this.expect(types.bracketR);
8315
return prop.key
8316
} else {
8317
prop.computed = false;
8318
}
8319
}
8320
return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
8321
};
8322
8323
// Initialize empty function node.
8324
8325
pp$3.initFunction = function(node) {
8326
node.id = null;
8327
if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
8328
if (this.options.ecmaVersion >= 8) { node.async = false; }
8329
};
8330
8331
// Parse object or class method.
8332
8333
pp$3.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
8334
var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
8335
8336
this.initFunction(node);
8337
if (this.options.ecmaVersion >= 6)
8338
{ node.generator = isGenerator; }
8339
if (this.options.ecmaVersion >= 8)
8340
{ node.async = !!isAsync; }
8341
8342
this.yieldPos = 0;
8343
this.awaitPos = 0;
8344
this.awaitIdentPos = 0;
8345
this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
8346
8347
this.expect(types.parenL);
8348
node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
8349
this.checkYieldAwaitInDefaultParams();
8350
this.parseFunctionBody(node, false, true);
8351
8352
this.yieldPos = oldYieldPos;
8353
this.awaitPos = oldAwaitPos;
8354
this.awaitIdentPos = oldAwaitIdentPos;
8355
return this.finishNode(node, "FunctionExpression")
8356
};
8357
8358
// Parse arrow function expression with given parameters.
8359
8360
pp$3.parseArrowExpression = function(node, params, isAsync) {
8361
var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
8362
8363
this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
8364
this.initFunction(node);
8365
if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
8366
8367
this.yieldPos = 0;
8368
this.awaitPos = 0;
8369
this.awaitIdentPos = 0;
8370
8371
node.params = this.toAssignableList(params, true);
8372
this.parseFunctionBody(node, true, false);
8373
8374
this.yieldPos = oldYieldPos;
8375
this.awaitPos = oldAwaitPos;
8376
this.awaitIdentPos = oldAwaitIdentPos;
8377
return this.finishNode(node, "ArrowFunctionExpression")
8378
};
8379
8380
// Parse function body and check parameters.
8381
8382
pp$3.parseFunctionBody = function(node, isArrowFunction, isMethod) {
8383
var isExpression = isArrowFunction && this.type !== types.braceL;
8384
var oldStrict = this.strict, useStrict = false;
8385
8386
if (isExpression) {
8387
node.body = this.parseMaybeAssign();
8388
node.expression = true;
8389
this.checkParams(node, false);
8390
} else {
8391
var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
8392
if (!oldStrict || nonSimple) {
8393
useStrict = this.strictDirective(this.end);
8394
// If this is a strict mode function, verify that argument names
8395
// are not repeated, and it does not try to bind the words `eval`
8396
// or `arguments`.
8397
if (useStrict && nonSimple)
8398
{ this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
8399
}
8400
// Start a new scope with regard to labels and the `inFunction`
8401
// flag (restore them to their old value afterwards).
8402
var oldLabels = this.labels;
8403
this.labels = [];
8404
if (useStrict) { this.strict = true; }
8405
8406
// Add the params to varDeclaredNames to ensure that an error is thrown
8407
// if a let/const declaration in the function clashes with one of the params.
8408
this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
8409
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
8410
if (this.strict && node.id) { this.checkLVal(node.id, BIND_OUTSIDE); }
8411
node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
8412
node.expression = false;
8413
this.adaptDirectivePrologue(node.body.body);
8414
this.labels = oldLabels;
8415
}
8416
this.exitScope();
8417
};
8418
8419
pp$3.isSimpleParamList = function(params) {
8420
for (var i = 0, list = params; i < list.length; i += 1)
8421
{
8422
var param = list[i];
8423
8424
if (param.type !== "Identifier") { return false
8425
} }
8426
return true
8427
};
8428
8429
// Checks function params for various disallowed patterns such as using "eval"
8430
// or "arguments" and duplicate parameters.
8431
8432
pp$3.checkParams = function(node, allowDuplicates) {
8433
var nameHash = {};
8434
for (var i = 0, list = node.params; i < list.length; i += 1)
8435
{
8436
var param = list[i];
8437
8438
this.checkLVal(param, BIND_VAR, allowDuplicates ? null : nameHash);
8439
}
8440
};
8441
8442
// Parses a comma-separated list of expressions, and returns them as
8443
// an array. `close` is the token type that ends the list, and
8444
// `allowEmpty` can be turned on to allow subsequent commas with
8445
// nothing in between them to be parsed as `null` (which is needed
8446
// for array literals).
8447
8448
pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
8449
var elts = [], first = true;
8450
while (!this.eat(close)) {
8451
if (!first) {
8452
this.expect(types.comma);
8453
if (allowTrailingComma && this.afterTrailingComma(close)) { break }
8454
} else { first = false; }
8455
8456
var elt = (void 0);
8457
if (allowEmpty && this.type === types.comma)
8458
{ elt = null; }
8459
else if (this.type === types.ellipsis) {
8460
elt = this.parseSpread(refDestructuringErrors);
8461
if (refDestructuringErrors && this.type === types.comma && refDestructuringErrors.trailingComma < 0)
8462
{ refDestructuringErrors.trailingComma = this.start; }
8463
} else {
8464
elt = this.parseMaybeAssign(false, refDestructuringErrors);
8465
}
8466
elts.push(elt);
8467
}
8468
return elts
8469
};
8470
8471
pp$3.checkUnreserved = function(ref) {
8472
var start = ref.start;
8473
var end = ref.end;
8474
var name = ref.name;
8475
8476
if (this.inGenerator && name === "yield")
8477
{ this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
8478
if (this.inAsync && name === "await")
8479
{ this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
8480
if (this.keywords.test(name))
8481
{ this.raise(start, ("Unexpected keyword '" + name + "'")); }
8482
if (this.options.ecmaVersion < 6 &&
8483
this.input.slice(start, end).indexOf("\\") !== -1) { return }
8484
var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
8485
if (re.test(name)) {
8486
if (!this.inAsync && name === "await")
8487
{ this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
8488
this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
8489
}
8490
};
8491
8492
// Parse the next token as an identifier. If `liberal` is true (used
8493
// when parsing properties), it will also convert keywords into
8494
// identifiers.
8495
8496
pp$3.parseIdent = function(liberal, isBinding) {
8497
var node = this.startNode();
8498
if (this.type === types.name) {
8499
node.name = this.value;
8500
} else if (this.type.keyword) {
8501
node.name = this.type.keyword;
8502
8503
// To fix https://github.com/acornjs/acorn/issues/575
8504
// `class` and `function` keywords push new context into this.context.
8505
// But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
8506
// If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
8507
if ((node.name === "class" || node.name === "function") &&
8508
(this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
8509
this.context.pop();
8510
}
8511
} else {
8512
this.unexpected();
8513
}
8514
this.next(!!liberal);
8515
this.finishNode(node, "Identifier");
8516
if (!liberal) {
8517
this.checkUnreserved(node);
8518
if (node.name === "await" && !this.awaitIdentPos)
8519
{ this.awaitIdentPos = node.start; }
8520
}
8521
return node
8522
};
8523
8524
// Parses yield expression inside generator.
8525
8526
pp$3.parseYield = function(noIn) {
8527
if (!this.yieldPos) { this.yieldPos = this.start; }
8528
8529
var node = this.startNode();
8530
this.next();
8531
if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {
8532
node.delegate = false;
8533
node.argument = null;
8534
} else {
8535
node.delegate = this.eat(types.star);
8536
node.argument = this.parseMaybeAssign(noIn);
8537
}
8538
return this.finishNode(node, "YieldExpression")
8539
};
8540
8541
pp$3.parseAwait = function() {
8542
if (!this.awaitPos) { this.awaitPos = this.start; }
8543
8544
var node = this.startNode();
8545
this.next();
8546
node.argument = this.parseMaybeUnary(null, false);
8547
return this.finishNode(node, "AwaitExpression")
8548
};
8549
8550
var pp$4 = Parser.prototype;
8551
8552
// This function is used to raise exceptions on parse errors. It
8553
// takes an offset integer (into the current `input`) to indicate
8554
// the location of the error, attaches the position to the end
8555
// of the error message, and then raises a `SyntaxError` with that
8556
// message.
8557
8558
pp$4.raise = function(pos, message) {
8559
var loc = getLineInfo(this.input, pos);
8560
message += " (" + loc.line + ":" + loc.column + ")";
8561
var err = new SyntaxError(message);
8562
err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
8563
throw err
8564
};
8565
8566
pp$4.raiseRecoverable = pp$4.raise;
8567
8568
pp$4.curPosition = function() {
8569
if (this.options.locations) {
8570
return new Position(this.curLine, this.pos - this.lineStart)
8571
}
8572
};
8573
8574
var pp$5 = Parser.prototype;
8575
8576
var Scope = function Scope(flags) {
8577
this.flags = flags;
8578
// A list of var-declared names in the current lexical scope
8579
this.var = [];
8580
// A list of lexically-declared names in the current lexical scope
8581
this.lexical = [];
8582
// A list of lexically-declared FunctionDeclaration names in the current lexical scope
8583
this.functions = [];
8584
};
8585
8586
// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
8587
8588
pp$5.enterScope = function(flags) {
8589
this.scopeStack.push(new Scope(flags));
8590
};
8591
8592
pp$5.exitScope = function() {
8593
this.scopeStack.pop();
8594
};
8595
8596
// The spec says:
8597
// > At the top level of a function, or script, function declarations are
8598
// > treated like var declarations rather than like lexical declarations.
8599
pp$5.treatFunctionsAsVarInScope = function(scope) {
8600
return (scope.flags & SCOPE_FUNCTION) || !this.inModule && (scope.flags & SCOPE_TOP)
8601
};
8602
8603
pp$5.declareName = function(name, bindingType, pos) {
8604
var redeclared = false;
8605
if (bindingType === BIND_LEXICAL) {
8606
var scope = this.currentScope();
8607
redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
8608
scope.lexical.push(name);
8609
if (this.inModule && (scope.flags & SCOPE_TOP))
8610
{ delete this.undefinedExports[name]; }
8611
} else if (bindingType === BIND_SIMPLE_CATCH) {
8612
var scope$1 = this.currentScope();
8613
scope$1.lexical.push(name);
8614
} else if (bindingType === BIND_FUNCTION) {
8615
var scope$2 = this.currentScope();
8616
if (this.treatFunctionsAsVar)
8617
{ redeclared = scope$2.lexical.indexOf(name) > -1; }
8618
else
8619
{ redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
8620
scope$2.functions.push(name);
8621
} else {
8622
for (var i = this.scopeStack.length - 1; i >= 0; --i) {
8623
var scope$3 = this.scopeStack[i];
8624
if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
8625
!this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
8626
redeclared = true;
8627
break
8628
}
8629
scope$3.var.push(name);
8630
if (this.inModule && (scope$3.flags & SCOPE_TOP))
8631
{ delete this.undefinedExports[name]; }
8632
if (scope$3.flags & SCOPE_VAR) { break }
8633
}
8634
}
8635
if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
8636
};
8637
8638
pp$5.checkLocalExport = function(id) {
8639
// scope.functions must be empty as Module code is always strict.
8640
if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
8641
this.scopeStack[0].var.indexOf(id.name) === -1) {
8642
this.undefinedExports[id.name] = id;
8643
}
8644
};
8645
8646
pp$5.currentScope = function() {
8647
return this.scopeStack[this.scopeStack.length - 1]
8648
};
8649
8650
pp$5.currentVarScope = function() {
8651
for (var i = this.scopeStack.length - 1;; i--) {
8652
var scope = this.scopeStack[i];
8653
if (scope.flags & SCOPE_VAR) { return scope }
8654
}
8655
};
8656
8657
// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
8658
pp$5.currentThisScope = function() {
8659
for (var i = this.scopeStack.length - 1;; i--) {
8660
var scope = this.scopeStack[i];
8661
if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
8662
}
8663
};
8664
8665
var Node = function Node(parser, pos, loc) {
8666
this.type = "";
8667
this.start = pos;
8668
this.end = 0;
8669
if (parser.options.locations)
8670
{ this.loc = new SourceLocation(parser, loc); }
8671
if (parser.options.directSourceFile)
8672
{ this.sourceFile = parser.options.directSourceFile; }
8673
if (parser.options.ranges)
8674
{ this.range = [pos, 0]; }
8675
};
8676
8677
// Start an AST node, attaching a start offset.
8678
8679
var pp$6 = Parser.prototype;
8680
8681
pp$6.startNode = function() {
8682
return new Node(this, this.start, this.startLoc)
8683
};
8684
8685
pp$6.startNodeAt = function(pos, loc) {
8686
return new Node(this, pos, loc)
8687
};
8688
8689
// Finish an AST node, adding `type` and `end` properties.
8690
8691
function finishNodeAt(node, type, pos, loc) {
8692
node.type = type;
8693
node.end = pos;
8694
if (this.options.locations)
8695
{ node.loc.end = loc; }
8696
if (this.options.ranges)
8697
{ node.range[1] = pos; }
8698
return node
8699
}
8700
8701
pp$6.finishNode = function(node, type) {
8702
return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
8703
};
8704
8705
// Finish node at given position
8706
8707
pp$6.finishNodeAt = function(node, type, pos, loc) {
8708
return finishNodeAt.call(this, node, type, pos, loc)
8709
};
8710
8711
// The algorithm used to determine whether a regexp can appear at a
8712
8713
var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
8714
this.token = token;
8715
this.isExpr = !!isExpr;
8716
this.preserveSpace = !!preserveSpace;
8717
this.override = override;
8718
this.generator = !!generator;
8719
};
8720
8721
var types$1 = {
8722
b_stat: new TokContext("{", false),
8723
b_expr: new TokContext("{", true),
8724
b_tmpl: new TokContext("${", false),
8725
p_stat: new TokContext("(", false),
8726
p_expr: new TokContext("(", true),
8727
q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
8728
f_stat: new TokContext("function", false),
8729
f_expr: new TokContext("function", true),
8730
f_expr_gen: new TokContext("function", true, false, null, true),
8731
f_gen: new TokContext("function", false, false, null, true)
8732
};
8733
8734
var pp$7 = Parser.prototype;
8735
8736
pp$7.initialContext = function() {
8737
return [types$1.b_stat]
8738
};
8739
8740
pp$7.braceIsBlock = function(prevType) {
8741
var parent = this.curContext();
8742
if (parent === types$1.f_expr || parent === types$1.f_stat)
8743
{ return true }
8744
if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
8745
{ return !parent.isExpr }
8746
8747
// The check for `tt.name && exprAllowed` detects whether we are
8748
// after a `yield` or `of` construct. See the `updateContext` for
8749
// `tt.name`.
8750
if (prevType === types._return || prevType === types.name && this.exprAllowed)
8751
{ return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
8752
if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)
8753
{ return true }
8754
if (prevType === types.braceL)
8755
{ return parent === types$1.b_stat }
8756
if (prevType === types._var || prevType === types._const || prevType === types.name)
8757
{ return false }
8758
return !this.exprAllowed
8759
};
8760
8761
pp$7.inGeneratorContext = function() {
8762
for (var i = this.context.length - 1; i >= 1; i--) {
8763
var context = this.context[i];
8764
if (context.token === "function")
8765
{ return context.generator }
8766
}
8767
return false
8768
};
8769
8770
pp$7.updateContext = function(prevType) {
8771
var update, type = this.type;
8772
if (type.keyword && prevType === types.dot)
8773
{ this.exprAllowed = false; }
8774
else if (update = type.updateContext)
8775
{ update.call(this, prevType); }
8776
else
8777
{ this.exprAllowed = type.beforeExpr; }
8778
};
8779
8780
// Token-specific context update code
8781
8782
types.parenR.updateContext = types.braceR.updateContext = function() {
8783
if (this.context.length === 1) {
8784
this.exprAllowed = true;
8785
return
8786
}
8787
var out = this.context.pop();
8788
if (out === types$1.b_stat && this.curContext().token === "function") {
8789
out = this.context.pop();
8790
}
8791
this.exprAllowed = !out.isExpr;
8792
};
8793
8794
types.braceL.updateContext = function(prevType) {
8795
this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
8796
this.exprAllowed = true;
8797
};
8798
8799
types.dollarBraceL.updateContext = function() {
8800
this.context.push(types$1.b_tmpl);
8801
this.exprAllowed = true;
8802
};
8803
8804
types.parenL.updateContext = function(prevType) {
8805
var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
8806
this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
8807
this.exprAllowed = true;
8808
};
8809
8810
types.incDec.updateContext = function() {
8811
// tokExprAllowed stays unchanged
8812
};
8813
8814
types._function.updateContext = types._class.updateContext = function(prevType) {
8815
if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
8816
!(prevType === types._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
8817
!((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
8818
{ this.context.push(types$1.f_expr); }
8819
else
8820
{ this.context.push(types$1.f_stat); }
8821
this.exprAllowed = false;
8822
};
8823
8824
types.backQuote.updateContext = function() {
8825
if (this.curContext() === types$1.q_tmpl)
8826
{ this.context.pop(); }
8827
else
8828
{ this.context.push(types$1.q_tmpl); }
8829
this.exprAllowed = false;
8830
};
8831
8832
types.star.updateContext = function(prevType) {
8833
if (prevType === types._function) {
8834
var index = this.context.length - 1;
8835
if (this.context[index] === types$1.f_expr)
8836
{ this.context[index] = types$1.f_expr_gen; }
8837
else
8838
{ this.context[index] = types$1.f_gen; }
8839
}
8840
this.exprAllowed = true;
8841
};
8842
8843
types.name.updateContext = function(prevType) {
8844
var allowed = false;
8845
if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {
8846
if (this.value === "of" && !this.exprAllowed ||
8847
this.value === "yield" && this.inGeneratorContext())
8848
{ allowed = true; }
8849
}
8850
this.exprAllowed = allowed;
8851
};
8852
8853
// This file contains Unicode properties extracted from the ECMAScript
8854
// specification. The lists are extracted like so:
8855
// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
8856
8857
// #table-binary-unicode-properties
8858
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";
8859
var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
8860
var ecma11BinaryProperties = ecma10BinaryProperties;
8861
var unicodeBinaryProperties = {
8862
9: ecma9BinaryProperties,
8863
10: ecma10BinaryProperties,
8864
11: ecma11BinaryProperties
8865
};
8866
8867
// #table-unicode-general-category-values
8868
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";
8869
8870
// #table-unicode-script-values
8871
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";
8872
var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
8873
var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
8874
var unicodeScriptValues = {
8875
9: ecma9ScriptValues,
8876
10: ecma10ScriptValues,
8877
11: ecma11ScriptValues
8878
};
8879
8880
var data = {};
8881
function buildUnicodeData(ecmaVersion) {
8882
var d = data[ecmaVersion] = {
8883
binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
8884
nonBinary: {
8885
General_Category: wordsRegexp(unicodeGeneralCategoryValues),
8886
Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
8887
}
8888
};
8889
d.nonBinary.Script_Extensions = d.nonBinary.Script;
8890
8891
d.nonBinary.gc = d.nonBinary.General_Category;
8892
d.nonBinary.sc = d.nonBinary.Script;
8893
d.nonBinary.scx = d.nonBinary.Script_Extensions;
8894
}
8895
buildUnicodeData(9);
8896
buildUnicodeData(10);
8897
buildUnicodeData(11);
8898
8899
var pp$8 = Parser.prototype;
8900
8901
var RegExpValidationState = function RegExpValidationState(parser) {
8902
this.parser = parser;
8903
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
8904
this.unicodeProperties = data[parser.options.ecmaVersion >= 11 ? 11 : parser.options.ecmaVersion];
8905
this.source = "";
8906
this.flags = "";
8907
this.start = 0;
8908
this.switchU = false;
8909
this.switchN = false;
8910
this.pos = 0;
8911
this.lastIntValue = 0;
8912
this.lastStringValue = "";
8913
this.lastAssertionIsQuantifiable = false;
8914
this.numCapturingParens = 0;
8915
this.maxBackReference = 0;
8916
this.groupNames = [];
8917
this.backReferenceNames = [];
8918
};
8919
8920
RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
8921
var unicode = flags.indexOf("u") !== -1;
8922
this.start = start | 0;
8923
this.source = pattern + "";
8924
this.flags = flags;
8925
this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
8926
this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
8927
};
8928
8929
RegExpValidationState.prototype.raise = function raise (message) {
8930
this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
8931
};
8932
8933
// If u flag is given, this returns the code point at the index (it combines a surrogate pair).
8934
// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
8935
RegExpValidationState.prototype.at = function at (i, forceU) {
8936
if ( forceU === void 0 ) forceU = false;
8937
8938
var s = this.source;
8939
var l = s.length;
8940
if (i >= l) {
8941
return -1
8942
}
8943
var c = s.charCodeAt(i);
8944
if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
8945
return c
8946
}
8947
var next = s.charCodeAt(i + 1);
8948
return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
8949
};
8950
8951
RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
8952
if ( forceU === void 0 ) forceU = false;
8953
8954
var s = this.source;
8955
var l = s.length;
8956
if (i >= l) {
8957
return l
8958
}
8959
var c = s.charCodeAt(i), next;
8960
if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
8961
(next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
8962
return i + 1
8963
}
8964
return i + 2
8965
};
8966
8967
RegExpValidationState.prototype.current = function current (forceU) {
8968
if ( forceU === void 0 ) forceU = false;
8969
8970
return this.at(this.pos, forceU)
8971
};
8972
8973
RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
8974
if ( forceU === void 0 ) forceU = false;
8975
8976
return this.at(this.nextIndex(this.pos, forceU), forceU)
8977
};
8978
8979
RegExpValidationState.prototype.advance = function advance (forceU) {
8980
if ( forceU === void 0 ) forceU = false;
8981
8982
this.pos = this.nextIndex(this.pos, forceU);
8983
};
8984
8985
RegExpValidationState.prototype.eat = function eat (ch, forceU) {
8986
if ( forceU === void 0 ) forceU = false;
8987
8988
if (this.current(forceU) === ch) {
8989
this.advance(forceU);
8990
return true
8991
}
8992
return false
8993
};
8994
8995
function codePointToString(ch) {
8996
if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
8997
ch -= 0x10000;
8998
return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
8999
}
9000
9001
/**
9002
* Validate the flags part of a given RegExpLiteral.
9003
*
9004
* @param {RegExpValidationState} state The state to validate RegExp.
9005
* @returns {void}
9006
*/
9007
pp$8.validateRegExpFlags = function(state) {
9008
var validFlags = state.validFlags;
9009
var flags = state.flags;
9010
9011
for (var i = 0; i < flags.length; i++) {
9012
var flag = flags.charAt(i);
9013
if (validFlags.indexOf(flag) === -1) {
9014
this.raise(state.start, "Invalid regular expression flag");
9015
}
9016
if (flags.indexOf(flag, i + 1) > -1) {
9017
this.raise(state.start, "Duplicate regular expression flag");
9018
}
9019
}
9020
};
9021
9022
/**
9023
* Validate the pattern part of a given RegExpLiteral.
9024
*
9025
* @param {RegExpValidationState} state The state to validate RegExp.
9026
* @returns {void}
9027
*/
9028
pp$8.validateRegExpPattern = function(state) {
9029
this.regexp_pattern(state);
9030
9031
// The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
9032
// parsing contains a |GroupName|, reparse with the goal symbol
9033
// |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
9034
// exception if _P_ did not conform to the grammar, if any elements of _P_
9035
// were not matched by the parse, or if any Early Error conditions exist.
9036
if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
9037
state.switchN = true;
9038
this.regexp_pattern(state);
9039
}
9040
};
9041
9042
// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
9043
pp$8.regexp_pattern = function(state) {
9044
state.pos = 0;
9045
state.lastIntValue = 0;
9046
state.lastStringValue = "";
9047
state.lastAssertionIsQuantifiable = false;
9048
state.numCapturingParens = 0;
9049
state.maxBackReference = 0;
9050
state.groupNames.length = 0;
9051
state.backReferenceNames.length = 0;
9052
9053
this.regexp_disjunction(state);
9054
9055
if (state.pos !== state.source.length) {
9056
// Make the same messages as V8.
9057
if (state.eat(0x29 /* ) */)) {
9058
state.raise("Unmatched ')'");
9059
}
9060
if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
9061
state.raise("Lone quantifier brackets");
9062
}
9063
}
9064
if (state.maxBackReference > state.numCapturingParens) {
9065
state.raise("Invalid escape");
9066
}
9067
for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
9068
var name = list[i];
9069
9070
if (state.groupNames.indexOf(name) === -1) {
9071
state.raise("Invalid named capture referenced");
9072
}
9073
}
9074
};
9075
9076
// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
9077
pp$8.regexp_disjunction = function(state) {
9078
this.regexp_alternative(state);
9079
while (state.eat(0x7C /* | */)) {
9080
this.regexp_alternative(state);
9081
}
9082
9083
// Make the same message as V8.
9084
if (this.regexp_eatQuantifier(state, true)) {
9085
state.raise("Nothing to repeat");
9086
}
9087
if (state.eat(0x7B /* { */)) {
9088
state.raise("Lone quantifier brackets");
9089
}
9090
};
9091
9092
// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
9093
pp$8.regexp_alternative = function(state) {
9094
while (state.pos < state.source.length && this.regexp_eatTerm(state))
9095
{ }
9096
};
9097
9098
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
9099
pp$8.regexp_eatTerm = function(state) {
9100
if (this.regexp_eatAssertion(state)) {
9101
// Handle `QuantifiableAssertion Quantifier` alternative.
9102
// `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
9103
// is a QuantifiableAssertion.
9104
if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
9105
// Make the same message as V8.
9106
if (state.switchU) {
9107
state.raise("Invalid quantifier");
9108
}
9109
}
9110
return true
9111
}
9112
9113
if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
9114
this.regexp_eatQuantifier(state);
9115
return true
9116
}
9117
9118
return false
9119
};
9120
9121
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
9122
pp$8.regexp_eatAssertion = function(state) {
9123
var start = state.pos;
9124
state.lastAssertionIsQuantifiable = false;
9125
9126
// ^, $
9127
if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
9128
return true
9129
}
9130
9131
// \b \B
9132
if (state.eat(0x5C /* \ */)) {
9133
if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
9134
return true
9135
}
9136
state.pos = start;
9137
}
9138
9139
// Lookahead / Lookbehind
9140
if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
9141
var lookbehind = false;
9142
if (this.options.ecmaVersion >= 9) {
9143
lookbehind = state.eat(0x3C /* < */);
9144
}
9145
if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
9146
this.regexp_disjunction(state);
9147
if (!state.eat(0x29 /* ) */)) {
9148
state.raise("Unterminated group");
9149
}
9150
state.lastAssertionIsQuantifiable = !lookbehind;
9151
return true
9152
}
9153
}
9154
9155
state.pos = start;
9156
return false
9157
};
9158
9159
// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
9160
pp$8.regexp_eatQuantifier = function(state, noError) {
9161
if ( noError === void 0 ) noError = false;
9162
9163
if (this.regexp_eatQuantifierPrefix(state, noError)) {
9164
state.eat(0x3F /* ? */);
9165
return true
9166
}
9167
return false
9168
};
9169
9170
// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
9171
pp$8.regexp_eatQuantifierPrefix = function(state, noError) {
9172
return (
9173
state.eat(0x2A /* * */) ||
9174
state.eat(0x2B /* + */) ||
9175
state.eat(0x3F /* ? */) ||
9176
this.regexp_eatBracedQuantifier(state, noError)
9177
)
9178
};
9179
pp$8.regexp_eatBracedQuantifier = function(state, noError) {
9180
var start = state.pos;
9181
if (state.eat(0x7B /* { */)) {
9182
var min = 0, max = -1;
9183
if (this.regexp_eatDecimalDigits(state)) {
9184
min = state.lastIntValue;
9185
if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
9186
max = state.lastIntValue;
9187
}
9188
if (state.eat(0x7D /* } */)) {
9189
// SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
9190
if (max !== -1 && max < min && !noError) {
9191
state.raise("numbers out of order in {} quantifier");
9192
}
9193
return true
9194
}
9195
}
9196
if (state.switchU && !noError) {
9197
state.raise("Incomplete quantifier");
9198
}
9199
state.pos = start;
9200
}
9201
return false
9202
};
9203
9204
// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
9205
pp$8.regexp_eatAtom = function(state) {
9206
return (
9207
this.regexp_eatPatternCharacters(state) ||
9208
state.eat(0x2E /* . */) ||
9209
this.regexp_eatReverseSolidusAtomEscape(state) ||
9210
this.regexp_eatCharacterClass(state) ||
9211
this.regexp_eatUncapturingGroup(state) ||
9212
this.regexp_eatCapturingGroup(state)
9213
)
9214
};
9215
pp$8.regexp_eatReverseSolidusAtomEscape = function(state) {
9216
var start = state.pos;
9217
if (state.eat(0x5C /* \ */)) {
9218
if (this.regexp_eatAtomEscape(state)) {
9219
return true
9220
}
9221
state.pos = start;
9222
}
9223
return false
9224
};
9225
pp$8.regexp_eatUncapturingGroup = function(state) {
9226
var start = state.pos;
9227
if (state.eat(0x28 /* ( */)) {
9228
if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
9229
this.regexp_disjunction(state);
9230
if (state.eat(0x29 /* ) */)) {
9231
return true
9232
}
9233
state.raise("Unterminated group");
9234
}
9235
state.pos = start;
9236
}
9237
return false
9238
};
9239
pp$8.regexp_eatCapturingGroup = function(state) {
9240
if (state.eat(0x28 /* ( */)) {
9241
if (this.options.ecmaVersion >= 9) {
9242
this.regexp_groupSpecifier(state);
9243
} else if (state.current() === 0x3F /* ? */) {
9244
state.raise("Invalid group");
9245
}
9246
this.regexp_disjunction(state);
9247
if (state.eat(0x29 /* ) */)) {
9248
state.numCapturingParens += 1;
9249
return true
9250
}
9251
state.raise("Unterminated group");
9252
}
9253
return false
9254
};
9255
9256
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
9257
pp$8.regexp_eatExtendedAtom = function(state) {
9258
return (
9259
state.eat(0x2E /* . */) ||
9260
this.regexp_eatReverseSolidusAtomEscape(state) ||
9261
this.regexp_eatCharacterClass(state) ||
9262
this.regexp_eatUncapturingGroup(state) ||
9263
this.regexp_eatCapturingGroup(state) ||
9264
this.regexp_eatInvalidBracedQuantifier(state) ||
9265
this.regexp_eatExtendedPatternCharacter(state)
9266
)
9267
};
9268
9269
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
9270
pp$8.regexp_eatInvalidBracedQuantifier = function(state) {
9271
if (this.regexp_eatBracedQuantifier(state, true)) {
9272
state.raise("Nothing to repeat");
9273
}
9274
return false
9275
};
9276
9277
// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
9278
pp$8.regexp_eatSyntaxCharacter = function(state) {
9279
var ch = state.current();
9280
if (isSyntaxCharacter(ch)) {
9281
state.lastIntValue = ch;
9282
state.advance();
9283
return true
9284
}
9285
return false
9286
};
9287
function isSyntaxCharacter(ch) {
9288
return (
9289
ch === 0x24 /* $ */ ||
9290
ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
9291
ch === 0x2E /* . */ ||
9292
ch === 0x3F /* ? */ ||
9293
ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
9294
ch >= 0x7B /* { */ && ch <= 0x7D /* } */
9295
)
9296
}
9297
9298
// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
9299
// But eat eager.
9300
pp$8.regexp_eatPatternCharacters = function(state) {
9301
var start = state.pos;
9302
var ch = 0;
9303
while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
9304
state.advance();
9305
}
9306
return state.pos !== start
9307
};
9308
9309
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
9310
pp$8.regexp_eatExtendedPatternCharacter = function(state) {
9311
var ch = state.current();
9312
if (
9313
ch !== -1 &&
9314
ch !== 0x24 /* $ */ &&
9315
!(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
9316
ch !== 0x2E /* . */ &&
9317
ch !== 0x3F /* ? */ &&
9318
ch !== 0x5B /* [ */ &&
9319
ch !== 0x5E /* ^ */ &&
9320
ch !== 0x7C /* | */
9321
) {
9322
state.advance();
9323
return true
9324
}
9325
return false
9326
};
9327
9328
// GroupSpecifier ::
9329
// [empty]
9330
// `?` GroupName
9331
pp$8.regexp_groupSpecifier = function(state) {
9332
if (state.eat(0x3F /* ? */)) {
9333
if (this.regexp_eatGroupName(state)) {
9334
if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
9335
state.raise("Duplicate capture group name");
9336
}
9337
state.groupNames.push(state.lastStringValue);
9338
return
9339
}
9340
state.raise("Invalid group");
9341
}
9342
};
9343
9344
// GroupName ::
9345
// `<` RegExpIdentifierName `>`
9346
// Note: this updates `state.lastStringValue` property with the eaten name.
9347
pp$8.regexp_eatGroupName = function(state) {
9348
state.lastStringValue = "";
9349
if (state.eat(0x3C /* < */)) {
9350
if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
9351
return true
9352
}
9353
state.raise("Invalid capture group name");
9354
}
9355
return false
9356
};
9357
9358
// RegExpIdentifierName ::
9359
// RegExpIdentifierStart
9360
// RegExpIdentifierName RegExpIdentifierPart
9361
// Note: this updates `state.lastStringValue` property with the eaten name.
9362
pp$8.regexp_eatRegExpIdentifierName = function(state) {
9363
state.lastStringValue = "";
9364
if (this.regexp_eatRegExpIdentifierStart(state)) {
9365
state.lastStringValue += codePointToString(state.lastIntValue);
9366
while (this.regexp_eatRegExpIdentifierPart(state)) {
9367
state.lastStringValue += codePointToString(state.lastIntValue);
9368
}
9369
return true
9370
}
9371
return false
9372
};
9373
9374
// RegExpIdentifierStart ::
9375
// UnicodeIDStart
9376
// `$`
9377
// `_`
9378
// `\` RegExpUnicodeEscapeSequence[+U]
9379
pp$8.regexp_eatRegExpIdentifierStart = function(state) {
9380
var start = state.pos;
9381
var forceU = this.options.ecmaVersion >= 11;
9382
var ch = state.current(forceU);
9383
state.advance(forceU);
9384
9385
if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
9386
ch = state.lastIntValue;
9387
}
9388
if (isRegExpIdentifierStart(ch)) {
9389
state.lastIntValue = ch;
9390
return true
9391
}
9392
9393
state.pos = start;
9394
return false
9395
};
9396
function isRegExpIdentifierStart(ch) {
9397
return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
9398
}
9399
9400
// RegExpIdentifierPart ::
9401
// UnicodeIDContinue
9402
// `$`
9403
// `_`
9404
// `\` RegExpUnicodeEscapeSequence[+U]
9405
// <ZWNJ>
9406
// <ZWJ>
9407
pp$8.regexp_eatRegExpIdentifierPart = function(state) {
9408
var start = state.pos;
9409
var forceU = this.options.ecmaVersion >= 11;
9410
var ch = state.current(forceU);
9411
state.advance(forceU);
9412
9413
if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
9414
ch = state.lastIntValue;
9415
}
9416
if (isRegExpIdentifierPart(ch)) {
9417
state.lastIntValue = ch;
9418
return true
9419
}
9420
9421
state.pos = start;
9422
return false
9423
};
9424
function isRegExpIdentifierPart(ch) {
9425
return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
9426
}
9427
9428
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
9429
pp$8.regexp_eatAtomEscape = function(state) {
9430
if (
9431
this.regexp_eatBackReference(state) ||
9432
this.regexp_eatCharacterClassEscape(state) ||
9433
this.regexp_eatCharacterEscape(state) ||
9434
(state.switchN && this.regexp_eatKGroupName(state))
9435
) {
9436
return true
9437
}
9438
if (state.switchU) {
9439
// Make the same message as V8.
9440
if (state.current() === 0x63 /* c */) {
9441
state.raise("Invalid unicode escape");
9442
}
9443
state.raise("Invalid escape");
9444
}
9445
return false
9446
};
9447
pp$8.regexp_eatBackReference = function(state) {
9448
var start = state.pos;
9449
if (this.regexp_eatDecimalEscape(state)) {
9450
var n = state.lastIntValue;
9451
if (state.switchU) {
9452
// For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
9453
if (n > state.maxBackReference) {
9454
state.maxBackReference = n;
9455
}
9456
return true
9457
}
9458
if (n <= state.numCapturingParens) {
9459
return true
9460
}
9461
state.pos = start;
9462
}
9463
return false
9464
};
9465
pp$8.regexp_eatKGroupName = function(state) {
9466
if (state.eat(0x6B /* k */)) {
9467
if (this.regexp_eatGroupName(state)) {
9468
state.backReferenceNames.push(state.lastStringValue);
9469
return true
9470
}
9471
state.raise("Invalid named reference");
9472
}
9473
return false
9474
};
9475
9476
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
9477
pp$8.regexp_eatCharacterEscape = function(state) {
9478
return (
9479
this.regexp_eatControlEscape(state) ||
9480
this.regexp_eatCControlLetter(state) ||
9481
this.regexp_eatZero(state) ||
9482
this.regexp_eatHexEscapeSequence(state) ||
9483
this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
9484
(!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
9485
this.regexp_eatIdentityEscape(state)
9486
)
9487
};
9488
pp$8.regexp_eatCControlLetter = function(state) {
9489
var start = state.pos;
9490
if (state.eat(0x63 /* c */)) {
9491
if (this.regexp_eatControlLetter(state)) {
9492
return true
9493
}
9494
state.pos = start;
9495
}
9496
return false
9497
};
9498
pp$8.regexp_eatZero = function(state) {
9499
if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
9500
state.lastIntValue = 0;
9501
state.advance();
9502
return true
9503
}
9504
return false
9505
};
9506
9507
// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
9508
pp$8.regexp_eatControlEscape = function(state) {
9509
var ch = state.current();
9510
if (ch === 0x74 /* t */) {
9511
state.lastIntValue = 0x09; /* \t */
9512
state.advance();
9513
return true
9514
}
9515
if (ch === 0x6E /* n */) {
9516
state.lastIntValue = 0x0A; /* \n */
9517
state.advance();
9518
return true
9519
}
9520
if (ch === 0x76 /* v */) {
9521
state.lastIntValue = 0x0B; /* \v */
9522
state.advance();
9523
return true
9524
}
9525
if (ch === 0x66 /* f */) {
9526
state.lastIntValue = 0x0C; /* \f */
9527
state.advance();
9528
return true
9529
}
9530
if (ch === 0x72 /* r */) {
9531
state.lastIntValue = 0x0D; /* \r */
9532
state.advance();
9533
return true
9534
}
9535
return false
9536
};
9537
9538
// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
9539
pp$8.regexp_eatControlLetter = function(state) {
9540
var ch = state.current();
9541
if (isControlLetter(ch)) {
9542
state.lastIntValue = ch % 0x20;
9543
state.advance();
9544
return true
9545
}
9546
return false
9547
};
9548
function isControlLetter(ch) {
9549
return (
9550
(ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
9551
(ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
9552
)
9553
}
9554
9555
// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
9556
pp$8.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
9557
if ( forceU === void 0 ) forceU = false;
9558
9559
var start = state.pos;
9560
var switchU = forceU || state.switchU;
9561
9562
if (state.eat(0x75 /* u */)) {
9563
if (this.regexp_eatFixedHexDigits(state, 4)) {
9564
var lead = state.lastIntValue;
9565
if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
9566
var leadSurrogateEnd = state.pos;
9567
if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
9568
var trail = state.lastIntValue;
9569
if (trail >= 0xDC00 && trail <= 0xDFFF) {
9570
state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
9571
return true
9572
}
9573
}
9574
state.pos = leadSurrogateEnd;
9575
state.lastIntValue = lead;
9576
}
9577
return true
9578
}
9579
if (
9580
switchU &&
9581
state.eat(0x7B /* { */) &&
9582
this.regexp_eatHexDigits(state) &&
9583
state.eat(0x7D /* } */) &&
9584
isValidUnicode(state.lastIntValue)
9585
) {
9586
return true
9587
}
9588
if (switchU) {
9589
state.raise("Invalid unicode escape");
9590
}
9591
state.pos = start;
9592
}
9593
9594
return false
9595
};
9596
function isValidUnicode(ch) {
9597
return ch >= 0 && ch <= 0x10FFFF
9598
}
9599
9600
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
9601
pp$8.regexp_eatIdentityEscape = function(state) {
9602
if (state.switchU) {
9603
if (this.regexp_eatSyntaxCharacter(state)) {
9604
return true
9605
}
9606
if (state.eat(0x2F /* / */)) {
9607
state.lastIntValue = 0x2F; /* / */
9608
return true
9609
}
9610
return false
9611
}
9612
9613
var ch = state.current();
9614
if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
9615
state.lastIntValue = ch;
9616
state.advance();
9617
return true
9618
}
9619
9620
return false
9621
};
9622
9623
// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
9624
pp$8.regexp_eatDecimalEscape = function(state) {
9625
state.lastIntValue = 0;
9626
var ch = state.current();
9627
if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
9628
do {
9629
state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
9630
state.advance();
9631
} while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
9632
return true
9633
}
9634
return false
9635
};
9636
9637
// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
9638
pp$8.regexp_eatCharacterClassEscape = function(state) {
9639
var ch = state.current();
9640
9641
if (isCharacterClassEscape(ch)) {
9642
state.lastIntValue = -1;
9643
state.advance();
9644
return true
9645
}
9646
9647
if (
9648
state.switchU &&
9649
this.options.ecmaVersion >= 9 &&
9650
(ch === 0x50 /* P */ || ch === 0x70 /* p */)
9651
) {
9652
state.lastIntValue = -1;
9653
state.advance();
9654
if (
9655
state.eat(0x7B /* { */) &&
9656
this.regexp_eatUnicodePropertyValueExpression(state) &&
9657
state.eat(0x7D /* } */)
9658
) {
9659
return true
9660
}
9661
state.raise("Invalid property name");
9662
}
9663
9664
return false
9665
};
9666
function isCharacterClassEscape(ch) {
9667
return (
9668
ch === 0x64 /* d */ ||
9669
ch === 0x44 /* D */ ||
9670
ch === 0x73 /* s */ ||
9671
ch === 0x53 /* S */ ||
9672
ch === 0x77 /* w */ ||
9673
ch === 0x57 /* W */
9674
)
9675
}
9676
9677
// UnicodePropertyValueExpression ::
9678
// UnicodePropertyName `=` UnicodePropertyValue
9679
// LoneUnicodePropertyNameOrValue
9680
pp$8.regexp_eatUnicodePropertyValueExpression = function(state) {
9681
var start = state.pos;
9682
9683
// UnicodePropertyName `=` UnicodePropertyValue
9684
if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
9685
var name = state.lastStringValue;
9686
if (this.regexp_eatUnicodePropertyValue(state)) {
9687
var value = state.lastStringValue;
9688
this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
9689
return true
9690
}
9691
}
9692
state.pos = start;
9693
9694
// LoneUnicodePropertyNameOrValue
9695
if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
9696
var nameOrValue = state.lastStringValue;
9697
this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
9698
return true
9699
}
9700
return false
9701
};
9702
pp$8.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
9703
if (!has(state.unicodeProperties.nonBinary, name))
9704
{ state.raise("Invalid property name"); }
9705
if (!state.unicodeProperties.nonBinary[name].test(value))
9706
{ state.raise("Invalid property value"); }
9707
};
9708
pp$8.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
9709
if (!state.unicodeProperties.binary.test(nameOrValue))
9710
{ state.raise("Invalid property name"); }
9711
};
9712
9713
// UnicodePropertyName ::
9714
// UnicodePropertyNameCharacters
9715
pp$8.regexp_eatUnicodePropertyName = function(state) {
9716
var ch = 0;
9717
state.lastStringValue = "";
9718
while (isUnicodePropertyNameCharacter(ch = state.current())) {
9719
state.lastStringValue += codePointToString(ch);
9720
state.advance();
9721
}
9722
return state.lastStringValue !== ""
9723
};
9724
function isUnicodePropertyNameCharacter(ch) {
9725
return isControlLetter(ch) || ch === 0x5F /* _ */
9726
}
9727
9728
// UnicodePropertyValue ::
9729
// UnicodePropertyValueCharacters
9730
pp$8.regexp_eatUnicodePropertyValue = function(state) {
9731
var ch = 0;
9732
state.lastStringValue = "";
9733
while (isUnicodePropertyValueCharacter(ch = state.current())) {
9734
state.lastStringValue += codePointToString(ch);
9735
state.advance();
9736
}
9737
return state.lastStringValue !== ""
9738
};
9739
function isUnicodePropertyValueCharacter(ch) {
9740
return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
9741
}
9742
9743
// LoneUnicodePropertyNameOrValue ::
9744
// UnicodePropertyValueCharacters
9745
pp$8.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
9746
return this.regexp_eatUnicodePropertyValue(state)
9747
};
9748
9749
// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
9750
pp$8.regexp_eatCharacterClass = function(state) {
9751
if (state.eat(0x5B /* [ */)) {
9752
state.eat(0x5E /* ^ */);
9753
this.regexp_classRanges(state);
9754
if (state.eat(0x5D /* ] */)) {
9755
return true
9756
}
9757
// Unreachable since it threw "unterminated regular expression" error before.
9758
state.raise("Unterminated character class");
9759
}
9760
return false
9761
};
9762
9763
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
9764
// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
9765
// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
9766
pp$8.regexp_classRanges = function(state) {
9767
while (this.regexp_eatClassAtom(state)) {
9768
var left = state.lastIntValue;
9769
if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
9770
var right = state.lastIntValue;
9771
if (state.switchU && (left === -1 || right === -1)) {
9772
state.raise("Invalid character class");
9773
}
9774
if (left !== -1 && right !== -1 && left > right) {
9775
state.raise("Range out of order in character class");
9776
}
9777
}
9778
}
9779
};
9780
9781
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
9782
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
9783
pp$8.regexp_eatClassAtom = function(state) {
9784
var start = state.pos;
9785
9786
if (state.eat(0x5C /* \ */)) {
9787
if (this.regexp_eatClassEscape(state)) {
9788
return true
9789
}
9790
if (state.switchU) {
9791
// Make the same message as V8.
9792
var ch$1 = state.current();
9793
if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
9794
state.raise("Invalid class escape");
9795
}
9796
state.raise("Invalid escape");
9797
}
9798
state.pos = start;
9799
}
9800
9801
var ch = state.current();
9802
if (ch !== 0x5D /* ] */) {
9803
state.lastIntValue = ch;
9804
state.advance();
9805
return true
9806
}
9807
9808
return false
9809
};
9810
9811
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
9812
pp$8.regexp_eatClassEscape = function(state) {
9813
var start = state.pos;
9814
9815
if (state.eat(0x62 /* b */)) {
9816
state.lastIntValue = 0x08; /* <BS> */
9817
return true
9818
}
9819
9820
if (state.switchU && state.eat(0x2D /* - */)) {
9821
state.lastIntValue = 0x2D; /* - */
9822
return true
9823
}
9824
9825
if (!state.switchU && state.eat(0x63 /* c */)) {
9826
if (this.regexp_eatClassControlLetter(state)) {
9827
return true
9828
}
9829
state.pos = start;
9830
}
9831
9832
return (
9833
this.regexp_eatCharacterClassEscape(state) ||
9834
this.regexp_eatCharacterEscape(state)
9835
)
9836
};
9837
9838
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
9839
pp$8.regexp_eatClassControlLetter = function(state) {
9840
var ch = state.current();
9841
if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
9842
state.lastIntValue = ch % 0x20;
9843
state.advance();
9844
return true
9845
}
9846
return false
9847
};
9848
9849
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
9850
pp$8.regexp_eatHexEscapeSequence = function(state) {
9851
var start = state.pos;
9852
if (state.eat(0x78 /* x */)) {
9853
if (this.regexp_eatFixedHexDigits(state, 2)) {
9854
return true
9855
}
9856
if (state.switchU) {
9857
state.raise("Invalid escape");
9858
}
9859
state.pos = start;
9860
}
9861
return false
9862
};
9863
9864
// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
9865
pp$8.regexp_eatDecimalDigits = function(state) {
9866
var start = state.pos;
9867
var ch = 0;
9868
state.lastIntValue = 0;
9869
while (isDecimalDigit(ch = state.current())) {
9870
state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
9871
state.advance();
9872
}
9873
return state.pos !== start
9874
};
9875
function isDecimalDigit(ch) {
9876
return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
9877
}
9878
9879
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
9880
pp$8.regexp_eatHexDigits = function(state) {
9881
var start = state.pos;
9882
var ch = 0;
9883
state.lastIntValue = 0;
9884
while (isHexDigit(ch = state.current())) {
9885
state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
9886
state.advance();
9887
}
9888
return state.pos !== start
9889
};
9890
function isHexDigit(ch) {
9891
return (
9892
(ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
9893
(ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
9894
(ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
9895
)
9896
}
9897
function hexToInt(ch) {
9898
if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
9899
return 10 + (ch - 0x41 /* A */)
9900
}
9901
if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
9902
return 10 + (ch - 0x61 /* a */)
9903
}
9904
return ch - 0x30 /* 0 */
9905
}
9906
9907
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
9908
// Allows only 0-377(octal) i.e. 0-255(decimal).
9909
pp$8.regexp_eatLegacyOctalEscapeSequence = function(state) {
9910
if (this.regexp_eatOctalDigit(state)) {
9911
var n1 = state.lastIntValue;
9912
if (this.regexp_eatOctalDigit(state)) {
9913
var n2 = state.lastIntValue;
9914
if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
9915
state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
9916
} else {
9917
state.lastIntValue = n1 * 8 + n2;
9918
}
9919
} else {
9920
state.lastIntValue = n1;
9921
}
9922
return true
9923
}
9924
return false
9925
};
9926
9927
// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
9928
pp$8.regexp_eatOctalDigit = function(state) {
9929
var ch = state.current();
9930
if (isOctalDigit(ch)) {
9931
state.lastIntValue = ch - 0x30; /* 0 */
9932
state.advance();
9933
return true
9934
}
9935
state.lastIntValue = 0;
9936
return false
9937
};
9938
function isOctalDigit(ch) {
9939
return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
9940
}
9941
9942
// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
9943
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
9944
// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
9945
pp$8.regexp_eatFixedHexDigits = function(state, length) {
9946
var start = state.pos;
9947
state.lastIntValue = 0;
9948
for (var i = 0; i < length; ++i) {
9949
var ch = state.current();
9950
if (!isHexDigit(ch)) {
9951
state.pos = start;
9952
return false
9953
}
9954
state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
9955
state.advance();
9956
}
9957
return true
9958
};
9959
9960
// Object type used to represent tokens. Note that normally, tokens
9961
// simply exist as properties on the parser object. This is only
9962
// used for the onToken callback and the external tokenizer.
9963
9964
var Token = function Token(p) {
9965
this.type = p.type;
9966
this.value = p.value;
9967
this.start = p.start;
9968
this.end = p.end;
9969
if (p.options.locations)
9970
{ this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
9971
if (p.options.ranges)
9972
{ this.range = [p.start, p.end]; }
9973
};
9974
9975
// ## Tokenizer
9976
9977
var pp$9 = Parser.prototype;
9978
9979
// Move to the next token
9980
9981
pp$9.next = function(ignoreEscapeSequenceInKeyword) {
9982
if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
9983
{ this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
9984
if (this.options.onToken)
9985
{ this.options.onToken(new Token(this)); }
9986
9987
this.lastTokEnd = this.end;
9988
this.lastTokStart = this.start;
9989
this.lastTokEndLoc = this.endLoc;
9990
this.lastTokStartLoc = this.startLoc;
9991
this.nextToken();
9992
};
9993
9994
pp$9.getToken = function() {
9995
this.next();
9996
return new Token(this)
9997
};
9998
9999
// If we're in an ES6 environment, make parsers iterable
10000
if (typeof Symbol !== "undefined")
10001
{ pp$9[Symbol.iterator] = function() {
10002
var this$1$1 = this;
10003
10004
return {
10005
next: function () {
10006
var token = this$1$1.getToken();
10007
return {
10008
done: token.type === types.eof,
10009
value: token
10010
}
10011
}
10012
}
10013
}; }
10014
10015
// Toggle strict mode. Re-reads the next number or string to please
10016
// pedantic tests (`"use strict"; 010;` should fail).
10017
10018
pp$9.curContext = function() {
10019
return this.context[this.context.length - 1]
10020
};
10021
10022
// Read a single token, updating the parser object's token-related
10023
// properties.
10024
10025
pp$9.nextToken = function() {
10026
var curContext = this.curContext();
10027
if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
10028
10029
this.start = this.pos;
10030
if (this.options.locations) { this.startLoc = this.curPosition(); }
10031
if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
10032
10033
if (curContext.override) { return curContext.override(this) }
10034
else { this.readToken(this.fullCharCodeAtPos()); }
10035
};
10036
10037
pp$9.readToken = function(code) {
10038
// Identifier or keyword. '\uXXXX' sequences are allowed in
10039
// identifiers, so '\' also dispatches to that.
10040
if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
10041
{ return this.readWord() }
10042
10043
return this.getTokenFromCode(code)
10044
};
10045
10046
pp$9.fullCharCodeAtPos = function() {
10047
var code = this.input.charCodeAt(this.pos);
10048
if (code <= 0xd7ff || code >= 0xe000) { return code }
10049
var next = this.input.charCodeAt(this.pos + 1);
10050
return (code << 10) + next - 0x35fdc00
10051
};
10052
10053
pp$9.skipBlockComment = function() {
10054
var startLoc = this.options.onComment && this.curPosition();
10055
var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
10056
if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
10057
this.pos = end + 2;
10058
if (this.options.locations) {
10059
lineBreakG.lastIndex = start;
10060
var match;
10061
while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
10062
++this.curLine;
10063
this.lineStart = match.index + match[0].length;
10064
}
10065
}
10066
if (this.options.onComment)
10067
{ this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
10068
startLoc, this.curPosition()); }
10069
};
10070
10071
pp$9.skipLineComment = function(startSkip) {
10072
var start = this.pos;
10073
var startLoc = this.options.onComment && this.curPosition();
10074
var ch = this.input.charCodeAt(this.pos += startSkip);
10075
while (this.pos < this.input.length && !isNewLine(ch)) {
10076
ch = this.input.charCodeAt(++this.pos);
10077
}
10078
if (this.options.onComment)
10079
{ this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
10080
startLoc, this.curPosition()); }
10081
};
10082
10083
// Called at the start of the parse and after every token. Skips
10084
// whitespace and comments, and.
10085
10086
pp$9.skipSpace = function() {
10087
loop: while (this.pos < this.input.length) {
10088
var ch = this.input.charCodeAt(this.pos);
10089
switch (ch) {
10090
case 32: case 160: // ' '
10091
++this.pos;
10092
break
10093
case 13:
10094
if (this.input.charCodeAt(this.pos + 1) === 10) {
10095
++this.pos;
10096
}
10097
case 10: case 8232: case 8233:
10098
++this.pos;
10099
if (this.options.locations) {
10100
++this.curLine;
10101
this.lineStart = this.pos;
10102
}
10103
break
10104
case 47: // '/'
10105
switch (this.input.charCodeAt(this.pos + 1)) {
10106
case 42: // '*'
10107
this.skipBlockComment();
10108
break
10109
case 47:
10110
this.skipLineComment(2);
10111
break
10112
default:
10113
break loop
10114
}
10115
break
10116
default:
10117
if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
10118
++this.pos;
10119
} else {
10120
break loop
10121
}
10122
}
10123
}
10124
};
10125
10126
// Called at the end of every token. Sets `end`, `val`, and
10127
// maintains `context` and `exprAllowed`, and skips the space after
10128
// the token, so that the next one's `start` will point at the
10129
// right position.
10130
10131
pp$9.finishToken = function(type, val) {
10132
this.end = this.pos;
10133
if (this.options.locations) { this.endLoc = this.curPosition(); }
10134
var prevType = this.type;
10135
this.type = type;
10136
this.value = val;
10137
10138
this.updateContext(prevType);
10139
};
10140
10141
// ### Token reading
10142
10143
// This is the function that is called to fetch the next token. It
10144
// is somewhat obscure, because it works in character codes rather
10145
// than characters, and because operator parsing has been inlined
10146
// into it.
10147
//
10148
// All in the name of speed.
10149
//
10150
pp$9.readToken_dot = function() {
10151
var next = this.input.charCodeAt(this.pos + 1);
10152
if (next >= 48 && next <= 57) { return this.readNumber(true) }
10153
var next2 = this.input.charCodeAt(this.pos + 2);
10154
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
10155
this.pos += 3;
10156
return this.finishToken(types.ellipsis)
10157
} else {
10158
++this.pos;
10159
return this.finishToken(types.dot)
10160
}
10161
};
10162
10163
pp$9.readToken_slash = function() { // '/'
10164
var next = this.input.charCodeAt(this.pos + 1);
10165
if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
10166
if (next === 61) { return this.finishOp(types.assign, 2) }
10167
return this.finishOp(types.slash, 1)
10168
};
10169
10170
pp$9.readToken_mult_modulo_exp = function(code) { // '%*'
10171
var next = this.input.charCodeAt(this.pos + 1);
10172
var size = 1;
10173
var tokentype = code === 42 ? types.star : types.modulo;
10174
10175
// exponentiation operator ** and **=
10176
if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
10177
++size;
10178
tokentype = types.starstar;
10179
next = this.input.charCodeAt(this.pos + 2);
10180
}
10181
10182
if (next === 61) { return this.finishOp(types.assign, size + 1) }
10183
return this.finishOp(tokentype, size)
10184
};
10185
10186
pp$9.readToken_pipe_amp = function(code) { // '|&'
10187
var next = this.input.charCodeAt(this.pos + 1);
10188
if (next === code) {
10189
if (this.options.ecmaVersion >= 12) {
10190
var next2 = this.input.charCodeAt(this.pos + 2);
10191
if (next2 === 61) { return this.finishOp(types.assign, 3) }
10192
}
10193
return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2)
10194
}
10195
if (next === 61) { return this.finishOp(types.assign, 2) }
10196
return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
10197
};
10198
10199
pp$9.readToken_caret = function() { // '^'
10200
var next = this.input.charCodeAt(this.pos + 1);
10201
if (next === 61) { return this.finishOp(types.assign, 2) }
10202
return this.finishOp(types.bitwiseXOR, 1)
10203
};
10204
10205
pp$9.readToken_plus_min = function(code) { // '+-'
10206
var next = this.input.charCodeAt(this.pos + 1);
10207
if (next === code) {
10208
if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
10209
(this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
10210
// A `-->` line comment
10211
this.skipLineComment(3);
10212
this.skipSpace();
10213
return this.nextToken()
10214
}
10215
return this.finishOp(types.incDec, 2)
10216
}
10217
if (next === 61) { return this.finishOp(types.assign, 2) }
10218
return this.finishOp(types.plusMin, 1)
10219
};
10220
10221
pp$9.readToken_lt_gt = function(code) { // '<>'
10222
var next = this.input.charCodeAt(this.pos + 1);
10223
var size = 1;
10224
if (next === code) {
10225
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
10226
if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
10227
return this.finishOp(types.bitShift, size)
10228
}
10229
if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
10230
this.input.charCodeAt(this.pos + 3) === 45) {
10231
// `<!--`, an XML-style comment that should be interpreted as a line comment
10232
this.skipLineComment(4);
10233
this.skipSpace();
10234
return this.nextToken()
10235
}
10236
if (next === 61) { size = 2; }
10237
return this.finishOp(types.relational, size)
10238
};
10239
10240
pp$9.readToken_eq_excl = function(code) { // '=!'
10241
var next = this.input.charCodeAt(this.pos + 1);
10242
if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
10243
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
10244
this.pos += 2;
10245
return this.finishToken(types.arrow)
10246
}
10247
return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
10248
};
10249
10250
pp$9.readToken_question = function() { // '?'
10251
var ecmaVersion = this.options.ecmaVersion;
10252
if (ecmaVersion >= 11) {
10253
var next = this.input.charCodeAt(this.pos + 1);
10254
if (next === 46) {
10255
var next2 = this.input.charCodeAt(this.pos + 2);
10256
if (next2 < 48 || next2 > 57) { return this.finishOp(types.questionDot, 2) }
10257
}
10258
if (next === 63) {
10259
if (ecmaVersion >= 12) {
10260
var next2$1 = this.input.charCodeAt(this.pos + 2);
10261
if (next2$1 === 61) { return this.finishOp(types.assign, 3) }
10262
}
10263
return this.finishOp(types.coalesce, 2)
10264
}
10265
}
10266
return this.finishOp(types.question, 1)
10267
};
10268
10269
pp$9.getTokenFromCode = function(code) {
10270
switch (code) {
10271
// The interpretation of a dot depends on whether it is followed
10272
// by a digit or another two dots.
10273
case 46: // '.'
10274
return this.readToken_dot()
10275
10276
// Punctuation tokens.
10277
case 40: ++this.pos; return this.finishToken(types.parenL)
10278
case 41: ++this.pos; return this.finishToken(types.parenR)
10279
case 59: ++this.pos; return this.finishToken(types.semi)
10280
case 44: ++this.pos; return this.finishToken(types.comma)
10281
case 91: ++this.pos; return this.finishToken(types.bracketL)
10282
case 93: ++this.pos; return this.finishToken(types.bracketR)
10283
case 123: ++this.pos; return this.finishToken(types.braceL)
10284
case 125: ++this.pos; return this.finishToken(types.braceR)
10285
case 58: ++this.pos; return this.finishToken(types.colon)
10286
10287
case 96: // '`'
10288
if (this.options.ecmaVersion < 6) { break }
10289
++this.pos;
10290
return this.finishToken(types.backQuote)
10291
10292
case 48: // '0'
10293
var next = this.input.charCodeAt(this.pos + 1);
10294
if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
10295
if (this.options.ecmaVersion >= 6) {
10296
if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
10297
if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
10298
}
10299
10300
// Anything else beginning with a digit is an integer, octal
10301
// number, or float.
10302
case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
10303
return this.readNumber(false)
10304
10305
// Quotes produce strings.
10306
case 34: case 39: // '"', "'"
10307
return this.readString(code)
10308
10309
// Operators are parsed inline in tiny state machines. '=' (61) is
10310
// often referred to. `finishOp` simply skips the amount of
10311
// characters it is given as second argument, and returns a token
10312
// of the type given by its first argument.
10313
10314
case 47: // '/'
10315
return this.readToken_slash()
10316
10317
case 37: case 42: // '%*'
10318
return this.readToken_mult_modulo_exp(code)
10319
10320
case 124: case 38: // '|&'
10321
return this.readToken_pipe_amp(code)
10322
10323
case 94: // '^'
10324
return this.readToken_caret()
10325
10326
case 43: case 45: // '+-'
10327
return this.readToken_plus_min(code)
10328
10329
case 60: case 62: // '<>'
10330
return this.readToken_lt_gt(code)
10331
10332
case 61: case 33: // '=!'
10333
return this.readToken_eq_excl(code)
10334
10335
case 63: // '?'
10336
return this.readToken_question()
10337
10338
case 126: // '~'
10339
return this.finishOp(types.prefix, 1)
10340
}
10341
10342
this.raise(this.pos, "Unexpected character '" + codePointToString$1(code) + "'");
10343
};
10344
10345
pp$9.finishOp = function(type, size) {
10346
var str = this.input.slice(this.pos, this.pos + size);
10347
this.pos += size;
10348
return this.finishToken(type, str)
10349
};
10350
10351
pp$9.readRegexp = function() {
10352
var escaped, inClass, start = this.pos;
10353
for (;;) {
10354
if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
10355
var ch = this.input.charAt(this.pos);
10356
if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
10357
if (!escaped) {
10358
if (ch === "[") { inClass = true; }
10359
else if (ch === "]" && inClass) { inClass = false; }
10360
else if (ch === "/" && !inClass) { break }
10361
escaped = ch === "\\";
10362
} else { escaped = false; }
10363
++this.pos;
10364
}
10365
var pattern = this.input.slice(start, this.pos);
10366
++this.pos;
10367
var flagsStart = this.pos;
10368
var flags = this.readWord1();
10369
if (this.containsEsc) { this.unexpected(flagsStart); }
10370
10371
// Validate pattern
10372
var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
10373
state.reset(start, pattern, flags);
10374
this.validateRegExpFlags(state);
10375
this.validateRegExpPattern(state);
10376
10377
// Create Literal#value property value.
10378
var value = null;
10379
try {
10380
value = new RegExp(pattern, flags);
10381
} catch (e) {
10382
// ESTree requires null if it failed to instantiate RegExp object.
10383
// https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
10384
}
10385
10386
return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value})
10387
};
10388
10389
// Read an integer in the given radix. Return null if zero digits
10390
// were read, the integer value otherwise. When `len` is given, this
10391
// will return `null` unless the integer has exactly `len` digits.
10392
10393
pp$9.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
10394
// `len` is used for character escape sequences. In that case, disallow separators.
10395
var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
10396
10397
// `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b)
10398
// and isn't fraction part nor exponent part. In that case, if the first digit
10399
// is zero then disallow separators.
10400
var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
10401
10402
var start = this.pos, total = 0, lastCode = 0;
10403
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
10404
var code = this.input.charCodeAt(this.pos), val = (void 0);
10405
10406
if (allowSeparators && code === 95) {
10407
if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
10408
if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
10409
if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
10410
lastCode = code;
10411
continue
10412
}
10413
10414
if (code >= 97) { val = code - 97 + 10; } // a
10415
else if (code >= 65) { val = code - 65 + 10; } // A
10416
else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
10417
else { val = Infinity; }
10418
if (val >= radix) { break }
10419
lastCode = code;
10420
total = total * radix + val;
10421
}
10422
10423
if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
10424
if (this.pos === start || len != null && this.pos - start !== len) { return null }
10425
10426
return total
10427
};
10428
10429
function stringToNumber(str, isLegacyOctalNumericLiteral) {
10430
if (isLegacyOctalNumericLiteral) {
10431
return parseInt(str, 8)
10432
}
10433
10434
// `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value.
10435
return parseFloat(str.replace(/_/g, ""))
10436
}
10437
10438
function stringToBigInt(str) {
10439
if (typeof BigInt !== "function") {
10440
return null
10441
}
10442
10443
// `BigInt(value)` throws syntax error if the string contains numeric separators.
10444
return BigInt(str.replace(/_/g, ""))
10445
}
10446
10447
pp$9.readRadixNumber = function(radix) {
10448
var start = this.pos;
10449
this.pos += 2; // 0x
10450
var val = this.readInt(radix);
10451
if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
10452
if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
10453
val = stringToBigInt(this.input.slice(start, this.pos));
10454
++this.pos;
10455
} else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
10456
return this.finishToken(types.num, val)
10457
};
10458
10459
// Read an integer, octal integer, or floating-point number.
10460
10461
pp$9.readNumber = function(startsWithDot) {
10462
var start = this.pos;
10463
if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
10464
var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
10465
if (octal && this.strict) { this.raise(start, "Invalid number"); }
10466
var next = this.input.charCodeAt(this.pos);
10467
if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
10468
var val$1 = stringToBigInt(this.input.slice(start, this.pos));
10469
++this.pos;
10470
if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
10471
return this.finishToken(types.num, val$1)
10472
}
10473
if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
10474
if (next === 46 && !octal) { // '.'
10475
++this.pos;
10476
this.readInt(10);
10477
next = this.input.charCodeAt(this.pos);
10478
}
10479
if ((next === 69 || next === 101) && !octal) { // 'eE'
10480
next = this.input.charCodeAt(++this.pos);
10481
if (next === 43 || next === 45) { ++this.pos; } // '+-'
10482
if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
10483
}
10484
if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
10485
10486
var val = stringToNumber(this.input.slice(start, this.pos), octal);
10487
return this.finishToken(types.num, val)
10488
};
10489
10490
// Read a string value, interpreting backslash-escapes.
10491
10492
pp$9.readCodePoint = function() {
10493
var ch = this.input.charCodeAt(this.pos), code;
10494
10495
if (ch === 123) { // '{'
10496
if (this.options.ecmaVersion < 6) { this.unexpected(); }
10497
var codePos = ++this.pos;
10498
code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
10499
++this.pos;
10500
if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
10501
} else {
10502
code = this.readHexChar(4);
10503
}
10504
return code
10505
};
10506
10507
function codePointToString$1(code) {
10508
// UTF-16 Decoding
10509
if (code <= 0xFFFF) { return String.fromCharCode(code) }
10510
code -= 0x10000;
10511
return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
10512
}
10513
10514
pp$9.readString = function(quote) {
10515
var out = "", chunkStart = ++this.pos;
10516
for (;;) {
10517
if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
10518
var ch = this.input.charCodeAt(this.pos);
10519
if (ch === quote) { break }
10520
if (ch === 92) { // '\'
10521
out += this.input.slice(chunkStart, this.pos);
10522
out += this.readEscapedChar(false);
10523
chunkStart = this.pos;
10524
} else {
10525
if (isNewLine(ch, this.options.ecmaVersion >= 10)) { this.raise(this.start, "Unterminated string constant"); }
10526
++this.pos;
10527
}
10528
}
10529
out += this.input.slice(chunkStart, this.pos++);
10530
return this.finishToken(types.string, out)
10531
};
10532
10533
// Reads template string tokens.
10534
10535
var INVALID_TEMPLATE_ESCAPE_ERROR = {};
10536
10537
pp$9.tryReadTemplateToken = function() {
10538
this.inTemplateElement = true;
10539
try {
10540
this.readTmplToken();
10541
} catch (err) {
10542
if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
10543
this.readInvalidTemplateToken();
10544
} else {
10545
throw err
10546
}
10547
}
10548
10549
this.inTemplateElement = false;
10550
};
10551
10552
pp$9.invalidStringToken = function(position, message) {
10553
if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
10554
throw INVALID_TEMPLATE_ESCAPE_ERROR
10555
} else {
10556
this.raise(position, message);
10557
}
10558
};
10559
10560
pp$9.readTmplToken = function() {
10561
var out = "", chunkStart = this.pos;
10562
for (;;) {
10563
if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
10564
var ch = this.input.charCodeAt(this.pos);
10565
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
10566
if (this.pos === this.start && (this.type === types.template || this.type === types.invalidTemplate)) {
10567
if (ch === 36) {
10568
this.pos += 2;
10569
return this.finishToken(types.dollarBraceL)
10570
} else {
10571
++this.pos;
10572
return this.finishToken(types.backQuote)
10573
}
10574
}
10575
out += this.input.slice(chunkStart, this.pos);
10576
return this.finishToken(types.template, out)
10577
}
10578
if (ch === 92) { // '\'
10579
out += this.input.slice(chunkStart, this.pos);
10580
out += this.readEscapedChar(true);
10581
chunkStart = this.pos;
10582
} else if (isNewLine(ch)) {
10583
out += this.input.slice(chunkStart, this.pos);
10584
++this.pos;
10585
switch (ch) {
10586
case 13:
10587
if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
10588
case 10:
10589
out += "\n";
10590
break
10591
default:
10592
out += String.fromCharCode(ch);
10593
break
10594
}
10595
if (this.options.locations) {
10596
++this.curLine;
10597
this.lineStart = this.pos;
10598
}
10599
chunkStart = this.pos;
10600
} else {
10601
++this.pos;
10602
}
10603
}
10604
};
10605
10606
// Reads a template token to search for the end, without validating any escape sequences
10607
pp$9.readInvalidTemplateToken = function() {
10608
for (; this.pos < this.input.length; this.pos++) {
10609
switch (this.input[this.pos]) {
10610
case "\\":
10611
++this.pos;
10612
break
10613
10614
case "$":
10615
if (this.input[this.pos + 1] !== "{") {
10616
break
10617
}
10618
// falls through
10619
10620
case "`":
10621
return this.finishToken(types.invalidTemplate, this.input.slice(this.start, this.pos))
10622
10623
// no default
10624
}
10625
}
10626
this.raise(this.start, "Unterminated template");
10627
};
10628
10629
// Used to read escaped characters
10630
10631
pp$9.readEscapedChar = function(inTemplate) {
10632
var ch = this.input.charCodeAt(++this.pos);
10633
++this.pos;
10634
switch (ch) {
10635
case 110: return "\n" // 'n' -> '\n'
10636
case 114: return "\r" // 'r' -> '\r'
10637
case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
10638
case 117: return codePointToString$1(this.readCodePoint()) // 'u'
10639
case 116: return "\t" // 't' -> '\t'
10640
case 98: return "\b" // 'b' -> '\b'
10641
case 118: return "\u000b" // 'v' -> '\u000b'
10642
case 102: return "\f" // 'f' -> '\f'
10643
case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
10644
case 10: // ' \n'
10645
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
10646
return ""
10647
case 56:
10648
case 57:
10649
if (inTemplate) {
10650
var codePos = this.pos - 1;
10651
10652
this.invalidStringToken(
10653
codePos,
10654
"Invalid escape sequence in template string"
10655
);
10656
10657
return null
10658
}
10659
default:
10660
if (ch >= 48 && ch <= 55) {
10661
var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
10662
var octal = parseInt(octalStr, 8);
10663
if (octal > 255) {
10664
octalStr = octalStr.slice(0, -1);
10665
octal = parseInt(octalStr, 8);
10666
}
10667
this.pos += octalStr.length - 1;
10668
ch = this.input.charCodeAt(this.pos);
10669
if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
10670
this.invalidStringToken(
10671
this.pos - 1 - octalStr.length,
10672
inTemplate
10673
? "Octal literal in template string"
10674
: "Octal literal in strict mode"
10675
);
10676
}
10677
return String.fromCharCode(octal)
10678
}
10679
if (isNewLine(ch)) {
10680
// Unicode new line characters after \ get removed from output in both
10681
// template literals and strings
10682
return ""
10683
}
10684
return String.fromCharCode(ch)
10685
}
10686
};
10687
10688
// Used to read character escape sequences ('\x', '\u', '\U').
10689
10690
pp$9.readHexChar = function(len) {
10691
var codePos = this.pos;
10692
var n = this.readInt(16, len);
10693
if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
10694
return n
10695
};
10696
10697
// Read an identifier, and return it as a string. Sets `this.containsEsc`
10698
// to whether the word contained a '\u' escape.
10699
//
10700
// Incrementally adds only escaped chars, adding other chunks as-is
10701
// as a micro-optimization.
10702
10703
pp$9.readWord1 = function() {
10704
this.containsEsc = false;
10705
var word = "", first = true, chunkStart = this.pos;
10706
var astral = this.options.ecmaVersion >= 6;
10707
while (this.pos < this.input.length) {
10708
var ch = this.fullCharCodeAtPos();
10709
if (isIdentifierChar(ch, astral)) {
10710
this.pos += ch <= 0xffff ? 1 : 2;
10711
} else if (ch === 92) { // "\"
10712
this.containsEsc = true;
10713
word += this.input.slice(chunkStart, this.pos);
10714
var escStart = this.pos;
10715
if (this.input.charCodeAt(++this.pos) !== 117) // "u"
10716
{ this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
10717
++this.pos;
10718
var esc = this.readCodePoint();
10719
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
10720
{ this.invalidStringToken(escStart, "Invalid Unicode escape"); }
10721
word += codePointToString$1(esc);
10722
chunkStart = this.pos;
10723
} else {
10724
break
10725
}
10726
first = false;
10727
}
10728
return word + this.input.slice(chunkStart, this.pos)
10729
};
10730
10731
// Read an identifier or keyword token. Will check for reserved
10732
// words when necessary.
10733
10734
pp$9.readWord = function() {
10735
var word = this.readWord1();
10736
var type = types.name;
10737
if (this.keywords.test(word)) {
10738
type = keywords$1[word];
10739
}
10740
return this.finishToken(type, word)
10741
};
10742
10743
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
10744
10745
var version = "7.4.1";
10746
10747
Parser.acorn = {
10748
Parser: Parser,
10749
version: version,
10750
defaultOptions: defaultOptions,
10751
Position: Position,
10752
SourceLocation: SourceLocation,
10753
getLineInfo: getLineInfo,
10754
Node: Node,
10755
TokenType: TokenType,
10756
tokTypes: types,
10757
keywordTypes: keywords$1,
10758
TokContext: TokContext,
10759
tokContexts: types$1,
10760
isIdentifierChar: isIdentifierChar,
10761
isIdentifierStart: isIdentifierStart,
10762
Token: Token,
10763
isNewLine: isNewLine,
10764
lineBreak: lineBreak,
10765
lineBreakG: lineBreakG,
10766
nonASCIIwhitespace: nonASCIIwhitespace
10767
};var defaultGlobals = new Set([
10768
"Array",
10769
"ArrayBuffer",
10770
"atob",
10771
"AudioContext",
10772
"Blob",
10773
"Boolean",
10774
"BigInt",
10775
"btoa",
10776
"clearInterval",
10777
"clearTimeout",
10778
"console",
10779
"crypto",
10780
"CustomEvent",
10781
"DataView",
10782
"Date",
10783
"decodeURI",
10784
"decodeURIComponent",
10785
"devicePixelRatio",
10786
"document",
10787
"encodeURI",
10788
"encodeURIComponent",
10789
"Error",
10790
"escape",
10791
"eval",
10792
"fetch",
10793
"File",
10794
"FileList",
10795
"FileReader",
10796
"Float32Array",
10797
"Float64Array",
10798
"Function",
10799
"Headers",
10800
"Image",
10801
"ImageData",
10802
"Infinity",
10803
"Int16Array",
10804
"Int32Array",
10805
"Int8Array",
10806
"Intl",
10807
"isFinite",
10808
"isNaN",
10809
"JSON",
10810
"Map",
10811
"Math",
10812
"NaN",
10813
"Number",
10814
"navigator",
10815
"Object",
10816
"parseFloat",
10817
"parseInt",
10818
"performance",
10819
"Path2D",
10820
"Promise",
10821
"Proxy",
10822
"RangeError",
10823
"ReferenceError",
10824
"Reflect",
10825
"RegExp",
10826
"cancelAnimationFrame",
10827
"requestAnimationFrame",
10828
"Set",
10829
"setInterval",
10830
"setTimeout",
10831
"String",
10832
"Symbol",
10833
"SyntaxError",
10834
"TextDecoder",
10835
"TextEncoder",
10836
"this",
10837
"TypeError",
10838
"Uint16Array",
10839
"Uint32Array",
10840
"Uint8Array",
10841
"Uint8ClampedArray",
10842
"undefined",
10843
"unescape",
10844
"URIError",
10845
"URL",
10846
"WeakMap",
10847
"WeakSet",
10848
"WebSocket",
10849
"Worker",
10850
"window"
10851
]);// AST walker module for Mozilla Parser API compatible trees
10852
10853
// A simple walk is one where you simply specify callbacks to be
10854
// called on specific nodes. The last two arguments are optional. A
10855
// simple use would be
10856
//
10857
// walk.simple(myTree, {
10858
// Expression: function(node) { ... }
10859
// });
10860
//
10861
// to do something with all expressions. All Parser API node types
10862
// can be used to identify node types, as well as Expression and
10863
// Statement, which denote categories of nodes.
10864
//
10865
// The base argument can be used to pass a custom (recursive)
10866
// walker, and state can be used to give this walked an initial
10867
// state.
10868
10869
function simple(node, visitors, baseVisitor, state, override) {
10870
if (!baseVisitor) { baseVisitor = base
10871
; }(function c(node, st, override) {
10872
var type = override || node.type, found = visitors[type];
10873
baseVisitor[type](node, st, c);
10874
if (found) { found(node, st); }
10875
})(node, state, override);
10876
}
10877
10878
// An ancestor walk keeps an array of ancestor nodes (including the
10879
// current node) and passes them to the callback as third parameter
10880
// (and also as state parameter when no other state is present).
10881
function ancestor(node, visitors, baseVisitor, state, override) {
10882
var ancestors = [];
10883
if (!baseVisitor) { baseVisitor = base
10884
; }(function c(node, st, override) {
10885
var type = override || node.type, found = visitors[type];
10886
var isNew = node !== ancestors[ancestors.length - 1];
10887
if (isNew) { ancestors.push(node); }
10888
baseVisitor[type](node, st, c);
10889
if (found) { found(node, st || ancestors, ancestors); }
10890
if (isNew) { ancestors.pop(); }
10891
})(node, state, override);
10892
}
10893
10894
// Fallback to an Object.create polyfill for older environments.
10895
var create = Object.create || function(proto) {
10896
function Ctor() {}
10897
Ctor.prototype = proto;
10898
return new Ctor
10899
};
10900
10901
// Used to create a custom walker. Will fill in all missing node
10902
// type properties with the defaults.
10903
function make(funcs, baseVisitor) {
10904
var visitor = create(baseVisitor || base);
10905
for (var type in funcs) { visitor[type] = funcs[type]; }
10906
return visitor
10907
}
10908
10909
function skipThrough(node, st, c) { c(node, st); }
10910
function ignore(_node, _st, _c) {}
10911
10912
// Node walkers.
10913
10914
var base = {};
10915
10916
base.Program = base.BlockStatement = function (node, st, c) {
10917
for (var i = 0, list = node.body; i < list.length; i += 1)
10918
{
10919
var stmt = list[i];
10920
10921
c(stmt, st, "Statement");
10922
}
10923
};
10924
base.Statement = skipThrough;
10925
base.EmptyStatement = ignore;
10926
base.ExpressionStatement = base.ParenthesizedExpression = base.ChainExpression =
10927
function (node, st, c) { return c(node.expression, st, "Expression"); };
10928
base.IfStatement = function (node, st, c) {
10929
c(node.test, st, "Expression");
10930
c(node.consequent, st, "Statement");
10931
if (node.alternate) { c(node.alternate, st, "Statement"); }
10932
};
10933
base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); };
10934
base.BreakStatement = base.ContinueStatement = ignore;
10935
base.WithStatement = function (node, st, c) {
10936
c(node.object, st, "Expression");
10937
c(node.body, st, "Statement");
10938
};
10939
base.SwitchStatement = function (node, st, c) {
10940
c(node.discriminant, st, "Expression");
10941
for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) {
10942
var cs = list$1[i$1];
10943
10944
if (cs.test) { c(cs.test, st, "Expression"); }
10945
for (var i = 0, list = cs.consequent; i < list.length; i += 1)
10946
{
10947
var cons = list[i];
10948
10949
c(cons, st, "Statement");
10950
}
10951
}
10952
};
10953
base.SwitchCase = function (node, st, c) {
10954
if (node.test) { c(node.test, st, "Expression"); }
10955
for (var i = 0, list = node.consequent; i < list.length; i += 1)
10956
{
10957
var cons = list[i];
10958
10959
c(cons, st, "Statement");
10960
}
10961
};
10962
base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) {
10963
if (node.argument) { c(node.argument, st, "Expression"); }
10964
};
10965
base.ThrowStatement = base.SpreadElement =
10966
function (node, st, c) { return c(node.argument, st, "Expression"); };
10967
base.TryStatement = function (node, st, c) {
10968
c(node.block, st, "Statement");
10969
if (node.handler) { c(node.handler, st); }
10970
if (node.finalizer) { c(node.finalizer, st, "Statement"); }
10971
};
10972
base.CatchClause = function (node, st, c) {
10973
if (node.param) { c(node.param, st, "Pattern"); }
10974
c(node.body, st, "Statement");
10975
};
10976
base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
10977
c(node.test, st, "Expression");
10978
c(node.body, st, "Statement");
10979
};
10980
base.ForStatement = function (node, st, c) {
10981
if (node.init) { c(node.init, st, "ForInit"); }
10982
if (node.test) { c(node.test, st, "Expression"); }
10983
if (node.update) { c(node.update, st, "Expression"); }
10984
c(node.body, st, "Statement");
10985
};
10986
base.ForInStatement = base.ForOfStatement = function (node, st, c) {
10987
c(node.left, st, "ForInit");
10988
c(node.right, st, "Expression");
10989
c(node.body, st, "Statement");
10990
};
10991
base.ForInit = function (node, st, c) {
10992
if (node.type === "VariableDeclaration") { c(node, st); }
10993
else { c(node, st, "Expression"); }
10994
};
10995
base.DebuggerStatement = ignore;
10996
10997
base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); };
10998
base.VariableDeclaration = function (node, st, c) {
10999
for (var i = 0, list = node.declarations; i < list.length; i += 1)
11000
{
11001
var decl = list[i];
11002
11003
c(decl, st);
11004
}
11005
};
11006
base.VariableDeclarator = function (node, st, c) {
11007
c(node.id, st, "Pattern");
11008
if (node.init) { c(node.init, st, "Expression"); }
11009
};
11010
11011
base.Function = function (node, st, c) {
11012
if (node.id) { c(node.id, st, "Pattern"); }
11013
for (var i = 0, list = node.params; i < list.length; i += 1)
11014
{
11015
var param = list[i];
11016
11017
c(param, st, "Pattern");
11018
}
11019
c(node.body, st, node.expression ? "Expression" : "Statement");
11020
};
11021
11022
base.Pattern = function (node, st, c) {
11023
if (node.type === "Identifier")
11024
{ c(node, st, "VariablePattern"); }
11025
else if (node.type === "MemberExpression")
11026
{ c(node, st, "MemberPattern"); }
11027
else
11028
{ c(node, st); }
11029
};
11030
base.VariablePattern = ignore;
11031
base.MemberPattern = skipThrough;
11032
base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); };
11033
base.ArrayPattern = function (node, st, c) {
11034
for (var i = 0, list = node.elements; i < list.length; i += 1) {
11035
var elt = list[i];
11036
11037
if (elt) { c(elt, st, "Pattern"); }
11038
}
11039
};
11040
base.ObjectPattern = function (node, st, c) {
11041
for (var i = 0, list = node.properties; i < list.length; i += 1) {
11042
var prop = list[i];
11043
11044
if (prop.type === "Property") {
11045
if (prop.computed) { c(prop.key, st, "Expression"); }
11046
c(prop.value, st, "Pattern");
11047
} else if (prop.type === "RestElement") {
11048
c(prop.argument, st, "Pattern");
11049
}
11050
}
11051
};
11052
11053
base.Expression = skipThrough;
11054
base.ThisExpression = base.Super = base.MetaProperty = ignore;
11055
base.ArrayExpression = function (node, st, c) {
11056
for (var i = 0, list = node.elements; i < list.length; i += 1) {
11057
var elt = list[i];
11058
11059
if (elt) { c(elt, st, "Expression"); }
11060
}
11061
};
11062
base.ObjectExpression = function (node, st, c) {
11063
for (var i = 0, list = node.properties; i < list.length; i += 1)
11064
{
11065
var prop = list[i];
11066
11067
c(prop, st);
11068
}
11069
};
11070
base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
11071
base.SequenceExpression = function (node, st, c) {
11072
for (var i = 0, list = node.expressions; i < list.length; i += 1)
11073
{
11074
var expr = list[i];
11075
11076
c(expr, st, "Expression");
11077
}
11078
};
11079
base.TemplateLiteral = function (node, st, c) {
11080
for (var i = 0, list = node.quasis; i < list.length; i += 1)
11081
{
11082
var quasi = list[i];
11083
11084
c(quasi, st);
11085
}
11086
11087
for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1)
11088
{
11089
var expr = list$1[i$1];
11090
11091
c(expr, st, "Expression");
11092
}
11093
};
11094
base.TemplateElement = ignore;
11095
base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
11096
c(node.argument, st, "Expression");
11097
};
11098
base.BinaryExpression = base.LogicalExpression = function (node, st, c) {
11099
c(node.left, st, "Expression");
11100
c(node.right, st, "Expression");
11101
};
11102
base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) {
11103
c(node.left, st, "Pattern");
11104
c(node.right, st, "Expression");
11105
};
11106
base.ConditionalExpression = function (node, st, c) {
11107
c(node.test, st, "Expression");
11108
c(node.consequent, st, "Expression");
11109
c(node.alternate, st, "Expression");
11110
};
11111
base.NewExpression = base.CallExpression = function (node, st, c) {
11112
c(node.callee, st, "Expression");
11113
if (node.arguments)
11114
{ for (var i = 0, list = node.arguments; i < list.length; i += 1)
11115
{
11116
var arg = list[i];
11117
11118
c(arg, st, "Expression");
11119
} }
11120
};
11121
base.MemberExpression = function (node, st, c) {
11122
c(node.object, st, "Expression");
11123
if (node.computed) { c(node.property, st, "Expression"); }
11124
};
11125
base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
11126
if (node.declaration)
11127
{ c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); }
11128
if (node.source) { c(node.source, st, "Expression"); }
11129
};
11130
base.ExportAllDeclaration = function (node, st, c) {
11131
if (node.exported)
11132
{ c(node.exported, st); }
11133
c(node.source, st, "Expression");
11134
};
11135
base.ImportDeclaration = function (node, st, c) {
11136
for (var i = 0, list = node.specifiers; i < list.length; i += 1)
11137
{
11138
var spec = list[i];
11139
11140
c(spec, st);
11141
}
11142
c(node.source, st, "Expression");
11143
};
11144
base.ImportExpression = function (node, st, c) {
11145
c(node.source, st, "Expression");
11146
};
11147
base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
11148
11149
base.TaggedTemplateExpression = function (node, st, c) {
11150
c(node.tag, st, "Expression");
11151
c(node.quasi, st, "Expression");
11152
};
11153
base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); };
11154
base.Class = function (node, st, c) {
11155
if (node.id) { c(node.id, st, "Pattern"); }
11156
if (node.superClass) { c(node.superClass, st, "Expression"); }
11157
c(node.body, st);
11158
};
11159
base.ClassBody = function (node, st, c) {
11160
for (var i = 0, list = node.body; i < list.length; i += 1)
11161
{
11162
var elt = list[i];
11163
11164
c(elt, st);
11165
}
11166
};
11167
base.MethodDefinition = base.Property = function (node, st, c) {
11168
if (node.computed) { c(node.key, st, "Expression"); }
11169
c(node.value, st, "Expression");
11170
};var walk = make({
11171
Import() {},
11172
ViewExpression(node, st, c) {
11173
c(node.id, st, "Identifier");
11174
},
11175
MutableExpression(node, st, c) {
11176
c(node.id, st, "Identifier");
11177
}
11178
});// Based on https://github.com/ForbesLindesay/acorn-globals
11179
11180
function isScope(node) {
11181
return node.type === "FunctionExpression"
11182
|| node.type === "FunctionDeclaration"
11183
|| node.type === "ArrowFunctionExpression"
11184
|| node.type === "Program";
11185
}
11186
11187
function isBlockScope(node) {
11188
return node.type === "BlockStatement"
11189
|| node.type === "ForInStatement"
11190
|| node.type === "ForOfStatement"
11191
|| node.type === "ForStatement"
11192
|| isScope(node);
11193
}
11194
11195
function declaresArguments(node) {
11196
return node.type === "FunctionExpression"
11197
|| node.type === "FunctionDeclaration";
11198
}
11199
11200
function findReferences(cell, globals) {
11201
const ast = {type: "Program", body: [cell.body]};
11202
const locals = new Map;
11203
const globalSet = new Set(globals);
11204
const references = [];
11205
11206
function hasLocal(node, name) {
11207
const l = locals.get(node);
11208
return l ? l.has(name) : false;
11209
}
11210
11211
function declareLocal(node, id) {
11212
const l = locals.get(node);
11213
if (l) l.add(id.name);
11214
else locals.set(node, new Set([id.name]));
11215
}
11216
11217
function declareClass(node) {
11218
if (node.id) declareLocal(node, node.id);
11219
}
11220
11221
function declareFunction(node) {
11222
node.params.forEach(param => declarePattern(param, node));
11223
if (node.id) declareLocal(node, node.id);
11224
}
11225
11226
function declareCatchClause(node) {
11227
if (node.param) declarePattern(node.param, node);
11228
}
11229
11230
function declarePattern(node, parent) {
11231
switch (node.type) {
11232
case "Identifier":
11233
declareLocal(parent, node);
11234
break;
11235
case "ObjectPattern":
11236
node.properties.forEach(node => declarePattern(node, parent));
11237
break;
11238
case "ArrayPattern":
11239
node.elements.forEach(node => node && declarePattern(node, parent));
11240
break;
11241
case "Property":
11242
declarePattern(node.value, parent);
11243
break;
11244
case "RestElement":
11245
declarePattern(node.argument, parent);
11246
break;
11247
case "AssignmentPattern":
11248
declarePattern(node.left, parent);
11249
break;
11250
default:
11251
throw new Error("Unrecognized pattern type: " + node.type);
11252
}
11253
}
11254
11255
function declareModuleSpecifier(node) {
11256
declareLocal(ast, node.local);
11257
}
11258
11259
ancestor(
11260
ast,
11261
{
11262
VariableDeclaration: (node, parents) => {
11263
let parent = null;
11264
for (let i = parents.length - 1; i >= 0 && parent === null; --i) {
11265
if (node.kind === "var" ? isScope(parents[i]) : isBlockScope(parents[i])) {
11266
parent = parents[i];
11267
}
11268
}
11269
node.declarations.forEach(declaration => declarePattern(declaration.id, parent));
11270
},
11271
FunctionDeclaration: (node, parents) => {
11272
let parent = null;
11273
for (let i = parents.length - 2; i >= 0 && parent === null; --i) {
11274
if (isScope(parents[i])) {
11275
parent = parents[i];
11276
}
11277
}
11278
declareLocal(parent, node.id);
11279
declareFunction(node);
11280
},
11281
Function: declareFunction,
11282
ClassDeclaration: (node, parents) => {
11283
let parent = null;
11284
for (let i = parents.length - 2; i >= 0 && parent === null; i--) {
11285
if (isScope(parents[i])) {
11286
parent = parents[i];
11287
}
11288
}
11289
declareLocal(parent, node.id);
11290
},
11291
Class: declareClass,
11292
CatchClause: declareCatchClause,
11293
ImportDefaultSpecifier: declareModuleSpecifier,
11294
ImportSpecifier: declareModuleSpecifier,
11295
ImportNamespaceSpecifier: declareModuleSpecifier
11296
},
11297
walk
11298
);
11299
11300
function identifier(node, parents) {
11301
let name = node.name;
11302
if (name === "undefined") return;
11303
for (let i = parents.length - 2; i >= 0; --i) {
11304
if (name === "arguments") {
11305
if (declaresArguments(parents[i])) {
11306
return;
11307
}
11308
}
11309
if (hasLocal(parents[i], name)) {
11310
return;
11311
}
11312
if (parents[i].type === "ViewExpression") {
11313
node = parents[i];
11314
name = `viewof ${node.id.name}`;
11315
}
11316
if (parents[i].type === "MutableExpression") {
11317
node = parents[i];
11318
name = `mutable ${node.id.name}`;
11319
}
11320
}
11321
if (!globalSet.has(name)) {
11322
if (name === "arguments") {
11323
throw Object.assign(new SyntaxError(`arguments is not allowed`), {node});
11324
}
11325
references.push(node);
11326
}
11327
}
11328
11329
ancestor(
11330
ast,
11331
{
11332
VariablePattern: identifier,
11333
Identifier: identifier
11334
},
11335
walk
11336
);
11337
11338
function checkConst(node, parents) {
11339
switch (node.type) {
11340
case "Identifier":
11341
case "VariablePattern": {
11342
identifier(node, parents);
11343
break;
11344
}
11345
case "ArrayPattern":
11346
case "ObjectPattern": {
11347
ancestor(
11348
node,
11349
{
11350
Identifier: identifier,
11351
VariablePattern: identifier
11352
},
11353
walk
11354
);
11355
break;
11356
}
11357
}
11358
function identifier(node, nodeParents) {
11359
for (const parent of parents) {
11360
if (hasLocal(parent, node.name)) {
11361
return;
11362
}
11363
}
11364
if (nodeParents[nodeParents.length - 2].type === "MutableExpression") {
11365
return;
11366
}
11367
throw Object.assign(new SyntaxError(`Assignment to constant variable ${node.name}`), {node});
11368
}
11369
}
11370
11371
function checkConstArgument(node, parents) {
11372
checkConst(node.argument, parents);
11373
}
11374
11375
function checkConstLeft(node, parents) {
11376
checkConst(node.left, parents);
11377
}
11378
11379
ancestor(
11380
ast,
11381
{
11382
AssignmentExpression: checkConstLeft,
11383
UpdateExpression: checkConstArgument,
11384
ForOfStatement: checkConstLeft,
11385
ForInStatement: checkConstLeft
11386
},
11387
walk
11388
);
11389
11390
return references;
11391
}function findFeatures(cell, featureName) {
11392
const ast = {type: "Program", body: [cell.body]};
11393
const features = new Map();
11394
const {references} = cell;
11395
11396
simple(
11397
ast,
11398
{
11399
CallExpression: node => {
11400
const {callee, arguments: args} = node;
11401
11402
// Ignore function calls that are not references to the feature.
11403
if (
11404
callee.type !== "Identifier" ||
11405
callee.name !== featureName ||
11406
references.indexOf(callee) < 0
11407
) return;
11408
11409
// Forbid dynamic calls.
11410
if (
11411
args.length !== 1 ||
11412
!((args[0].type === "Literal" && /^['"]/.test(args[0].raw)) ||
11413
(args[0].type === "TemplateLiteral" && args[0].expressions.length === 0))
11414
) {
11415
throw Object.assign(new SyntaxError(`${featureName} requires a single literal string argument`), {node});
11416
}
11417
11418
const [arg] = args;
11419
const name = arg.type === "Literal" ? arg.value : arg.quasis[0].value.cooked;
11420
const location = {start: arg.start, end: arg.end};
11421
if (features.has(name)) features.get(name).push(location);
11422
else features.set(name, [location]);
11423
}
11424
},
11425
walk
11426
);
11427
11428
return features;
11429
}const SCOPE_FUNCTION$1 = 2;
11430
const SCOPE_ASYNC$1 = 4;
11431
const SCOPE_GENERATOR$1 = 8;
11432
11433
const STATE_START = Symbol("start");
11434
const STATE_MODIFIER = Symbol("modifier");
11435
const STATE_FUNCTION = Symbol("function");
11436
const STATE_NAME = Symbol("name");
11437
11438
function parseCell(input, {globals} = {}) {
11439
const cell = CellParser.parse(input);
11440
parseReferences(cell, input, globals);
11441
parseFeatures(cell);
11442
return cell;
11443
}
11444
11445
/*
11446
┌─────┐
11447
┌───────────│START│─function|class
11448
│ └─────┘ │
11449
viewof|mutable|async │ ▼
11450
│ │ ┌────────┐ ┌─┐
11451
▼ │ │FUNCTION│◀───▶│*│
11452
┌────────┐ │ └────────┘ └─┘
11453
│MODIFIER│ │ │
11454
└────────┘ name name
11455
│ │ │
11456
└──name─┐ │ ▼
11457
▼ │ ┌─────────────┐
11458
┌────────┐ │ │FUNCTION_NAME│
11459
│ NAME │◀─┘ └─────────────┘
11460
└────────┘
11461
11462
=
11463
11464
┌────────┐
11465
│ EQ │
11466
└────────┘
11467
*/
11468
11469
function peekId(input) {
11470
let state = STATE_START;
11471
let name;
11472
try {
11473
for (const token of Parser.tokenizer(input, {ecmaVersion: 11})) {
11474
switch (state) {
11475
case STATE_START:
11476
case STATE_MODIFIER: {
11477
if (token.type === types.name) {
11478
if (
11479
state === STATE_START &&
11480
(token.value === "viewof" ||
11481
token.value === "mutable" ||
11482
token.value === "async")
11483
) {
11484
state = STATE_MODIFIER;
11485
continue;
11486
}
11487
state = STATE_NAME;
11488
name = token;
11489
continue;
11490
}
11491
if (token.type === types._function || token.type === types._class) {
11492
state = STATE_FUNCTION;
11493
continue;
11494
}
11495
break;
11496
}
11497
case STATE_NAME: {
11498
if (token.type === types.eq) return name.value;
11499
break;
11500
}
11501
case STATE_FUNCTION: {
11502
if (token.type === types.star) continue;
11503
if (token.type === types.name && token.end < input.length)
11504
return token.value;
11505
break;
11506
}
11507
}
11508
return;
11509
}
11510
} catch (ignore) {
11511
return;
11512
}
11513
}
11514
11515
class CellParser extends Parser {
11516
constructor(options, ...args) {
11517
super(Object.assign({ecmaVersion: 12}, options), ...args);
11518
}
11519
enterScope(flags) {
11520
if (flags & SCOPE_FUNCTION$1) ++this.O_function;
11521
return super.enterScope(flags);
11522
}
11523
exitScope() {
11524
if (this.currentScope().flags & SCOPE_FUNCTION$1) --this.O_function;
11525
return super.exitScope();
11526
}
11527
parseForIn(node, init) {
11528
if (this.O_function === 1 && node.await) this.O_async = true;
11529
return super.parseForIn(node, init);
11530
}
11531
parseAwait() {
11532
if (this.O_function === 1) this.O_async = true;
11533
return super.parseAwait();
11534
}
11535
parseYield(noIn) {
11536
if (this.O_function === 1) this.O_generator = true;
11537
return super.parseYield(noIn);
11538
}
11539
parseImport(node) {
11540
this.next();
11541
node.specifiers = this.parseImportSpecifiers();
11542
if (this.type === types._with) {
11543
this.next();
11544
node.injections = this.parseImportSpecifiers();
11545
}
11546
this.expectContextual("from");
11547
node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
11548
return this.finishNode(node, "ImportDeclaration");
11549
}
11550
parseImportSpecifiers() {
11551
const nodes = [];
11552
const identifiers = new Set;
11553
let first = true;
11554
this.expect(types.braceL);
11555
while (!this.eat(types.braceR)) {
11556
if (first) {
11557
first = false;
11558
} else {
11559
this.expect(types.comma);
11560
if (this.afterTrailingComma(types.braceR)) break;
11561
}
11562
const node = this.startNode();
11563
node.view = this.eatContextual("viewof");
11564
node.mutable = node.view ? false : this.eatContextual("mutable");
11565
node.imported = this.parseIdent();
11566
this.checkUnreserved(node.imported);
11567
this.checkLocal(node.imported);
11568
if (this.eatContextual("as")) {
11569
node.local = this.parseIdent();
11570
this.checkUnreserved(node.local);
11571
this.checkLocal(node.local);
11572
} else {
11573
node.local = node.imported;
11574
}
11575
this.checkLVal(node.local, "let");
11576
if (identifiers.has(node.local.name)) {
11577
this.raise(node.local.start, `Identifier '${node.local.name}' has already been declared`);
11578
}
11579
identifiers.add(node.local.name);
11580
nodes.push(this.finishNode(node, "ImportSpecifier"));
11581
}
11582
return nodes;
11583
}
11584
parseExprAtom(refDestructuringErrors) {
11585
return (
11586
this.parseMaybeKeywordExpression("viewof", "ViewExpression") ||
11587
this.parseMaybeKeywordExpression("mutable", "MutableExpression") ||
11588
super.parseExprAtom(refDestructuringErrors)
11589
);
11590
}
11591
parseCell(node, eof) {
11592
const lookahead = new CellParser({}, this.input, this.start);
11593
let token = lookahead.getToken();
11594
let body = null;
11595
let id = null;
11596
11597
this.O_function = 0;
11598
this.O_async = false;
11599
this.O_generator = false;
11600
this.strict = true;
11601
this.enterScope(SCOPE_FUNCTION$1 | SCOPE_ASYNC$1 | SCOPE_GENERATOR$1);
11602
11603
// An import?
11604
if (token.type === types._import && lookahead.getToken().type !== types.parenL) {
11605
body = this.parseImport(this.startNode());
11606
}
11607
11608
// A non-empty cell?
11609
else if (token.type !== types.eof && token.type !== types.semi) {
11610
// A named cell?
11611
if (token.type === types.name) {
11612
if (token.value === "viewof" || token.value === "mutable") {
11613
token = lookahead.getToken();
11614
if (token.type !== types.name) {
11615
lookahead.unexpected();
11616
}
11617
}
11618
token = lookahead.getToken();
11619
if (token.type === types.eq) {
11620
id =
11621
this.parseMaybeKeywordExpression("viewof", "ViewExpression") ||
11622
this.parseMaybeKeywordExpression("mutable", "MutableExpression") ||
11623
this.parseIdent();
11624
token = lookahead.getToken();
11625
this.expect(types.eq);
11626
}
11627
}
11628
11629
// A block?
11630
if (token.type === types.braceL) {
11631
body = this.parseBlock();
11632
}
11633
11634
// An expression?
11635
// Possibly a function or class declaration?
11636
else {
11637
body = this.parseExpression();
11638
if (
11639
id === null &&
11640
(body.type === "FunctionExpression" ||
11641
body.type === "ClassExpression")
11642
) {
11643
id = body.id;
11644
}
11645
}
11646
}
11647
11648
this.semicolon();
11649
if (eof) this.expect(types.eof); // TODO
11650
11651
if (id) this.checkLocal(id);
11652
node.id = id;
11653
node.async = this.O_async;
11654
node.generator = this.O_generator;
11655
node.body = body;
11656
this.exitScope();
11657
return this.finishNode(node, "Cell");
11658
}
11659
parseTopLevel(node) {
11660
return this.parseCell(node, true);
11661
}
11662
toAssignable(node, isBinding, refDestructuringErrors) {
11663
return node.type === "MutableExpression"
11664
? node
11665
: super.toAssignable(node, isBinding, refDestructuringErrors);
11666
}
11667
checkLocal(id) {
11668
const node = id.id || id;
11669
if (defaultGlobals.has(node.name) || node.name === "arguments") {
11670
this.raise(node.start, `Identifier '${node.name}' is reserved`);
11671
}
11672
}
11673
checkUnreserved(node) {
11674
if (node.name === "viewof" || node.name === "mutable") {
11675
this.raise(node.start, `Unexpected keyword '${node.name}'`);
11676
}
11677
return super.checkUnreserved(node);
11678
}
11679
checkLVal(expr, bindingType, checkClashes) {
11680
return super.checkLVal(
11681
expr.type === "MutableExpression" ? expr.id : expr,
11682
bindingType,
11683
checkClashes
11684
);
11685
}
11686
unexpected(pos) {
11687
this.raise(
11688
pos != null ? pos : this.start,
11689
this.type === types.eof ? "Unexpected end of input" : "Unexpected token"
11690
);
11691
}
11692
parseMaybeKeywordExpression(keyword, type) {
11693
if (this.isContextual(keyword)) {
11694
const node = this.startNode();
11695
this.next();
11696
node.id = this.parseIdent();
11697
return this.finishNode(node, type);
11698
}
11699
}
11700
}
11701
11702
function parseModule(input, {globals} = {}) {
11703
const program = ModuleParser.parse(input);
11704
for (const cell of program.cells) {
11705
parseReferences(cell, input, globals);
11706
parseFeatures(cell, input);
11707
}
11708
return program;
11709
}
11710
11711
class ModuleParser extends CellParser {
11712
parseTopLevel(node) {
11713
if (!node.cells) node.cells = [];
11714
while (this.type !== types.eof) {
11715
const cell = this.parseCell(this.startNode());
11716
cell.input = this.input;
11717
node.cells.push(cell);
11718
}
11719
this.next();
11720
return this.finishNode(node, "Program");
11721
}
11722
}
11723
11724
// Find references.
11725
// Check for illegal references to arguments.
11726
// Check for illegal assignments to global references.
11727
function parseReferences(cell, input, globals = defaultGlobals) {
11728
if (cell.body && cell.body.type !== "ImportDeclaration") {
11729
try {
11730
cell.references = findReferences(cell, globals);
11731
} catch (error) {
11732
if (error.node) {
11733
const loc = getLineInfo(input, error.node.start);
11734
error.message += ` (${loc.line}:${loc.column})`;
11735
error.pos = error.node.start;
11736
error.loc = loc;
11737
delete error.node;
11738
}
11739
throw error;
11740
}
11741
}
11742
return cell;
11743
}
11744
11745
// Find features: file attachments, secrets, database clients.
11746
// Check for illegal references to arguments.
11747
// Check for illegal assignments to global references.
11748
function parseFeatures(cell, input) {
11749
if (cell.body && cell.body.type !== "ImportDeclaration") {
11750
try {
11751
cell.fileAttachments = findFeatures(cell, "FileAttachment");
11752
cell.databaseClients = findFeatures(cell, "DatabaseClient");
11753
cell.secrets = findFeatures(cell, "Secret");
11754
} catch (error) {
11755
if (error.node) {
11756
const loc = getLineInfo(input, error.node.start);
11757
error.message += ` (${loc.line}:${loc.column})`;
11758
error.pos = error.node.start;
11759
error.loc = loc;
11760
delete error.node;
11761
}
11762
throw error;
11763
}
11764
} else {
11765
cell.fileAttachments = new Map();
11766
cell.databaseClients = new Map();
11767
cell.secrets = new Map();
11768
}
11769
return cell;
11770
}var index=/*#__PURE__*/Object.freeze({__proto__:null,parseCell: parseCell,peekId: peekId,CellParser: CellParser,parseModule: parseModule,ModuleParser: ModuleParser,walk: walk});// AST walker module for Mozilla Parser API compatible trees
11771
11772
// A full walk triggers the callback on each node
11773
function full(node, callback, baseVisitor, state, override) {
11774
if (!baseVisitor) { baseVisitor = base$1
11775
; }(function c(node, st, override) {
11776
var type = override || node.type;
11777
baseVisitor[type](node, st, c);
11778
if (!override) { callback(node, st, type); }
11779
})(node, state, override);
11780
}
11781
11782
function skipThrough$1(node, st, c) { c(node, st); }
11783
function ignore$1(_node, _st, _c) {}
11784
11785
// Node walkers.
11786
11787
var base$1 = {};
11788
11789
base$1.Program = base$1.BlockStatement = function (node, st, c) {
11790
for (var i = 0, list = node.body; i < list.length; i += 1)
11791
{
11792
var stmt = list[i];
11793
11794
c(stmt, st, "Statement");
11795
}
11796
};
11797
base$1.Statement = skipThrough$1;
11798
base$1.EmptyStatement = ignore$1;
11799
base$1.ExpressionStatement = base$1.ParenthesizedExpression = base$1.ChainExpression =
11800
function (node, st, c) { return c(node.expression, st, "Expression"); };
11801
base$1.IfStatement = function (node, st, c) {
11802
c(node.test, st, "Expression");
11803
c(node.consequent, st, "Statement");
11804
if (node.alternate) { c(node.alternate, st, "Statement"); }
11805
};
11806
base$1.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); };
11807
base$1.BreakStatement = base$1.ContinueStatement = ignore$1;
11808
base$1.WithStatement = function (node, st, c) {
11809
c(node.object, st, "Expression");
11810
c(node.body, st, "Statement");
11811
};
11812
base$1.SwitchStatement = function (node, st, c) {
11813
c(node.discriminant, st, "Expression");
11814
for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) {
11815
var cs = list$1[i$1];
11816
11817
if (cs.test) { c(cs.test, st, "Expression"); }
11818
for (var i = 0, list = cs.consequent; i < list.length; i += 1)
11819
{
11820
var cons = list[i];
11821
11822
c(cons, st, "Statement");
11823
}
11824
}
11825
};
11826
base$1.SwitchCase = function (node, st, c) {
11827
if (node.test) { c(node.test, st, "Expression"); }
11828
for (var i = 0, list = node.consequent; i < list.length; i += 1)
11829
{
11830
var cons = list[i];
11831
11832
c(cons, st, "Statement");
11833
}
11834
};
11835
base$1.ReturnStatement = base$1.YieldExpression = base$1.AwaitExpression = function (node, st, c) {
11836
if (node.argument) { c(node.argument, st, "Expression"); }
11837
};
11838
base$1.ThrowStatement = base$1.SpreadElement =
11839
function (node, st, c) { return c(node.argument, st, "Expression"); };
11840
base$1.TryStatement = function (node, st, c) {
11841
c(node.block, st, "Statement");
11842
if (node.handler) { c(node.handler, st); }
11843
if (node.finalizer) { c(node.finalizer, st, "Statement"); }
11844
};
11845
base$1.CatchClause = function (node, st, c) {
11846
if (node.param) { c(node.param, st, "Pattern"); }
11847
c(node.body, st, "Statement");
11848
};
11849
base$1.WhileStatement = base$1.DoWhileStatement = function (node, st, c) {
11850
c(node.test, st, "Expression");
11851
c(node.body, st, "Statement");
11852
};
11853
base$1.ForStatement = function (node, st, c) {
11854
if (node.init) { c(node.init, st, "ForInit"); }
11855
if (node.test) { c(node.test, st, "Expression"); }
11856
if (node.update) { c(node.update, st, "Expression"); }
11857
c(node.body, st, "Statement");
11858
};
11859
base$1.ForInStatement = base$1.ForOfStatement = function (node, st, c) {
11860
c(node.left, st, "ForInit");
11861
c(node.right, st, "Expression");
11862
c(node.body, st, "Statement");
11863
};
11864
base$1.ForInit = function (node, st, c) {
11865
if (node.type === "VariableDeclaration") { c(node, st); }
11866
else { c(node, st, "Expression"); }
11867
};
11868
base$1.DebuggerStatement = ignore$1;
11869
11870
base$1.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); };
11871
base$1.VariableDeclaration = function (node, st, c) {
11872
for (var i = 0, list = node.declarations; i < list.length; i += 1)
11873
{
11874
var decl = list[i];
11875
11876
c(decl, st);
11877
}
11878
};
11879
base$1.VariableDeclarator = function (node, st, c) {
11880
c(node.id, st, "Pattern");
11881
if (node.init) { c(node.init, st, "Expression"); }
11882
};
11883
11884
base$1.Function = function (node, st, c) {
11885
if (node.id) { c(node.id, st, "Pattern"); }
11886
for (var i = 0, list = node.params; i < list.length; i += 1)
11887
{
11888
var param = list[i];
11889
11890
c(param, st, "Pattern");
11891
}
11892
c(node.body, st, node.expression ? "Expression" : "Statement");
11893
};
11894
11895
base$1.Pattern = function (node, st, c) {
11896
if (node.type === "Identifier")
11897
{ c(node, st, "VariablePattern"); }
11898
else if (node.type === "MemberExpression")
11899
{ c(node, st, "MemberPattern"); }
11900
else
11901
{ c(node, st); }
11902
};
11903
base$1.VariablePattern = ignore$1;
11904
base$1.MemberPattern = skipThrough$1;
11905
base$1.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); };
11906
base$1.ArrayPattern = function (node, st, c) {
11907
for (var i = 0, list = node.elements; i < list.length; i += 1) {
11908
var elt = list[i];
11909
11910
if (elt) { c(elt, st, "Pattern"); }
11911
}
11912
};
11913
base$1.ObjectPattern = function (node, st, c) {
11914
for (var i = 0, list = node.properties; i < list.length; i += 1) {
11915
var prop = list[i];
11916
11917
if (prop.type === "Property") {
11918
if (prop.computed) { c(prop.key, st, "Expression"); }
11919
c(prop.value, st, "Pattern");
11920
} else if (prop.type === "RestElement") {
11921
c(prop.argument, st, "Pattern");
11922
}
11923
}
11924
};
11925
11926
base$1.Expression = skipThrough$1;
11927
base$1.ThisExpression = base$1.Super = base$1.MetaProperty = ignore$1;
11928
base$1.ArrayExpression = function (node, st, c) {
11929
for (var i = 0, list = node.elements; i < list.length; i += 1) {
11930
var elt = list[i];
11931
11932
if (elt) { c(elt, st, "Expression"); }
11933
}
11934
};
11935
base$1.ObjectExpression = function (node, st, c) {
11936
for (var i = 0, list = node.properties; i < list.length; i += 1)
11937
{
11938
var prop = list[i];
11939
11940
c(prop, st);
11941
}
11942
};
11943
base$1.FunctionExpression = base$1.ArrowFunctionExpression = base$1.FunctionDeclaration;
11944
base$1.SequenceExpression = function (node, st, c) {
11945
for (var i = 0, list = node.expressions; i < list.length; i += 1)
11946
{
11947
var expr = list[i];
11948
11949
c(expr, st, "Expression");
11950
}
11951
};
11952
base$1.TemplateLiteral = function (node, st, c) {
11953
for (var i = 0, list = node.quasis; i < list.length; i += 1)
11954
{
11955
var quasi = list[i];
11956
11957
c(quasi, st);
11958
}
11959
11960
for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1)
11961
{
11962
var expr = list$1[i$1];
11963
11964
c(expr, st, "Expression");
11965
}
11966
};
11967
base$1.TemplateElement = ignore$1;
11968
base$1.UnaryExpression = base$1.UpdateExpression = function (node, st, c) {
11969
c(node.argument, st, "Expression");
11970
};
11971
base$1.BinaryExpression = base$1.LogicalExpression = function (node, st, c) {
11972
c(node.left, st, "Expression");
11973
c(node.right, st, "Expression");
11974
};
11975
base$1.AssignmentExpression = base$1.AssignmentPattern = function (node, st, c) {
11976
c(node.left, st, "Pattern");
11977
c(node.right, st, "Expression");
11978
};
11979
base$1.ConditionalExpression = function (node, st, c) {
11980
c(node.test, st, "Expression");
11981
c(node.consequent, st, "Expression");
11982
c(node.alternate, st, "Expression");
11983
};
11984
base$1.NewExpression = base$1.CallExpression = function (node, st, c) {
11985
c(node.callee, st, "Expression");
11986
if (node.arguments)
11987
{ for (var i = 0, list = node.arguments; i < list.length; i += 1)
11988
{
11989
var arg = list[i];
11990
11991
c(arg, st, "Expression");
11992
} }
11993
};
11994
base$1.MemberExpression = function (node, st, c) {
11995
c(node.object, st, "Expression");
11996
if (node.computed) { c(node.property, st, "Expression"); }
11997
};
11998
base$1.ExportNamedDeclaration = base$1.ExportDefaultDeclaration = function (node, st, c) {
11999
if (node.declaration)
12000
{ c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); }
12001
if (node.source) { c(node.source, st, "Expression"); }
12002
};
12003
base$1.ExportAllDeclaration = function (node, st, c) {
12004
if (node.exported)
12005
{ c(node.exported, st); }
12006
c(node.source, st, "Expression");
12007
};
12008
base$1.ImportDeclaration = function (node, st, c) {
12009
for (var i = 0, list = node.specifiers; i < list.length; i += 1)
12010
{
12011
var spec = list[i];
12012
12013
c(spec, st);
12014
}
12015
c(node.source, st, "Expression");
12016
};
12017
base$1.ImportExpression = function (node, st, c) {
12018
c(node.source, st, "Expression");
12019
};
12020
base$1.ImportSpecifier = base$1.ImportDefaultSpecifier = base$1.ImportNamespaceSpecifier = base$1.Identifier = base$1.Literal = ignore$1;
12021
12022
base$1.TaggedTemplateExpression = function (node, st, c) {
12023
c(node.tag, st, "Expression");
12024
c(node.quasi, st, "Expression");
12025
};
12026
base$1.ClassDeclaration = base$1.ClassExpression = function (node, st, c) { return c(node, st, "Class"); };
12027
base$1.Class = function (node, st, c) {
12028
if (node.id) { c(node.id, st, "Pattern"); }
12029
if (node.superClass) { c(node.superClass, st, "Expression"); }
12030
c(node.body, st);
12031
};
12032
base$1.ClassBody = function (node, st, c) {
12033
for (var i = 0, list = node.body; i < list.length; i += 1)
12034
{
12035
var elt = list[i];
12036
12037
c(elt, st);
12038
}
12039
};
12040
base$1.MethodDefinition = base$1.Property = function (node, st, c) {
12041
if (node.computed) { c(node.key, st, "Expression"); }
12042
c(node.value, st, "Expression");
12043
};/**
12044
* FINISH REPLACING THE SIMPLE WALKER WITH A FULL WALKER THAT DOES SUBSTITUTION ALL AT ONCE.
12045
*
12046
*/
12047
12048
const extractPath = path => {
12049
let source = path;
12050
let m;
12051
12052
// "https://api.observablehq.com/@jashkenas/inputs.js?v=3" => strip off ".js"
12053
if ((m = /\.js(\?|$)/i.exec(source))) source = source.slice(0, m.index);
12054
12055
// "74f872c4fde62e35" => "d/..."
12056
if ((m = /^[0-9a-f]{16}$/i.test(source))) source = `d/${source}`;
12057
12058
// link of notebook
12059
if ((m = /^https:\/\/(api\.|beta\.|)observablehq\.com\//i.exec(source)))
12060
source = source.slice(m[0].length);
12061
return source;
12062
};
12063
12064
function setupImportCell(cell) {
12065
const specifiers = [];
12066
12067
if (cell.body.specifiers)
12068
for (const specifier of cell.body.specifiers) {
12069
if (specifier.view) {
12070
specifiers.push({
12071
name: "viewof " + specifier.imported.name,
12072
alias: "viewof " + specifier.local.name
12073
});
12074
} else if (specifier.mutable) {
12075
specifiers.push({
12076
name: "mutable " + specifier.imported.name,
12077
alias: "mutable " + specifier.local.name
12078
});
12079
}
12080
specifiers.push({
12081
name: specifier.imported.name,
12082
alias: specifier.local.name
12083
});
12084
}
12085
// If injections is undefined, do not derive!
12086
const hasInjections = cell.body.injections !== undefined;
12087
const injections = [];
12088
if (hasInjections)
12089
for (const injection of cell.body.injections) {
12090
// This currently behaves like notebooks on observablehq.com
12091
// Commenting out the if & else if blocks result in behavior like Example 3 here: https://observablehq.com/d/7ccad009e4d89969
12092
if (injection.view) {
12093
injections.push({
12094
name: "viewof " + injection.imported.name,
12095
alias: "viewof " + injection.local.name
12096
});
12097
} else if (injection.mutable) {
12098
injections.push({
12099
name: "mutable " + injection.imported.name,
12100
alias: "mutable " + injection.local.name
12101
});
12102
}
12103
injections.push({
12104
name: injection.imported.name,
12105
alias: injection.local.name
12106
});
12107
}
12108
const importString = `import {${specifiers
12109
.map(specifier => `${specifier.name} as ${specifier.alias}`)
12110
.join(", ")}} ${
12111
hasInjections
12112
? `with {${injections
12113
.map(injection => `${injection.name} as ${injection.alias}`)
12114
.join(", ")}} `
12115
: ``
12116
}from "${cell.body.source.value}"`;
12117
12118
return { specifiers, hasInjections, injections, importString };
12119
}
12120
12121
function setupRegularCell(cell) {
12122
let name = null;
12123
if (cell.id && cell.id.name) name = cell.id.name;
12124
else if (cell.id && cell.id.id && cell.id.id.name) name = cell.id.id.name;
12125
let bodyText = cell.input.substring(cell.body.start, cell.body.end);
12126
let expressionMap = {};
12127
let references = [];
12128
let counter = 0;
12129
const cellReferences = Array.from(new Set((cell.references || []).map(ref => {
12130
if (ref.type === "ViewExpression") {
12131
if (expressionMap[ref.id.name] === undefined) {
12132
const newName = `$${counter++}`;
12133
expressionMap[ref.id.name] = newName;
12134
references.push(newName);
12135
}
12136
return "viewof " + ref.id.name;
12137
} else if (ref.type === "MutableExpression") {
12138
if (expressionMap[ref.id.name] === undefined) {
12139
const newName = `$${counter++}`;
12140
expressionMap[ref.id.name] = newName;
12141
references.push(newName);
12142
}
12143
return "mutable " + ref.id.name;
12144
} else {
12145
references.push(ref.name);
12146
return ref.name;
12147
}
12148
})));
12149
const uniq = (lst) => {
12150
const result = [];
12151
const s = new Set();
12152
for (const v of lst) {
12153
if (s.has(v)) continue;
12154
s.add(v);
12155
result.push(v);
12156
}
12157
return result;
12158
};
12159
const patches = [];
12160
let latestPatch = { newStr: "", span: [cell.body.start, cell.body.start] };
12161
full(cell.body, node => {
12162
if (node.type === "ViewExpression" || node.type === "MutableExpression") {
12163
// cover previous ground?
12164
if (node.start !== latestPatch.span[1]) {
12165
patches.push({ newStr: cell.input.substring(latestPatch.span[1], node.start)});
12166
}
12167
const suffix = node.type === "MutableExpression" ? ".value" : "";
12168
const newStr = `${expressionMap[node.id.name]}${suffix}`;
12169
const patch = {
12170
newStr,
12171
span: [node.start, node.end]
12172
};
12173
latestPatch = patch;
12174
patches.push(patch);
12175
}
12176
}, walk);
12177
patches.push({newStr: cell.input.substring(latestPatch.span[1], cell.body.end), span: [latestPatch.span[1], cell.body.end]});
12178
bodyText = patches.map(x => x.newStr).join("");
12179
12180
return {
12181
cellName: name,
12182
references: uniq(references),
12183
bodyText,
12184
cellReferences: uniq(cellReferences)
12185
};
12186
}function names(cell) {
12187
if (cell.body && cell.body.specifiers)
12188
return cell.body.specifiers.map(
12189
d => `${d.view ? "viewof " : d.mutable ? "mutable " : ""}${d.local.name}`
12190
);
12191
12192
if (cell.id && cell.id.type && cell.id) {
12193
if (cell.id.type === "ViewExpression") return [`viewof ${cell.id.id.name}`];
12194
if (cell.id.type === "MutableExpression")
12195
return [`mutable ${cell.id.id.name}`];
12196
if (cell.id.name) return [cell.id.name];
12197
}
12198
12199
return [];
12200
}
12201
12202
function references(cell) {
12203
if (cell.references)
12204
return cell.references.map(d => {
12205
if (d.name) return d.name;
12206
if (d.type === "ViewExpression") return `viewof ${d.id.name}`;
12207
if (d.type === "MutableExpression") return `mutable ${d.id.name}`;
12208
return null;
12209
});
12210
12211
if (cell.body && cell.body.injections)
12212
return cell.body.injections.map(
12213
d =>
12214
`${d.view ? "viewof " : d.mutable ? "mutable " : ""}${d.imported.name}`
12215
);
12216
12217
return [];
12218
}
12219
12220
function getCellRefs(module) {
12221
const cells = [];
12222
for (const cell of module.cells) {
12223
const ns = names(cell);
12224
const refs = references(cell);
12225
if (!ns || !ns.length) continue;
12226
for (const name of ns) {
12227
cells.push([name, refs]);
12228
if (name.startsWith("viewof "))
12229
cells.push([name.substring("viewof ".length), [name]]);
12230
}
12231
}
12232
return new Map(cells);
12233
}
12234
12235
function treeShakeModule(module, targets) {
12236
const cellRefs = getCellRefs(module);
12237
12238
const embed = new Set();
12239
const todo = targets.slice();
12240
while (todo.length) {
12241
const d = todo.pop();
12242
embed.add(d);
12243
// happens when 1) d is an stdlib cell, 2) d doesnt have a defintion,
12244
// or 3) d is in the window/global object. Let's be forgiving
12245
// and let it happen
12246
if (!cellRefs.has(d)) continue;
12247
const refs = cellRefs.get(d);
12248
for (const ref of refs) if (!embed.has(ref)) todo.push(ref);
12249
}
12250
return {
12251
cells: module.cells.filter(
12252
cell => names(cell).filter(name => embed.has(name)).length
12253
)
12254
};
12255
}function ESMImports(moduleObject, resolveImportPath) {
12256
const importMap = new Map();
12257
let importSrc = "";
12258
let j = 0;
12259
12260
for (const { body } of moduleObject.cells) {
12261
if (body.type !== "ImportDeclaration" || importMap.has(body.source.value))
12262
continue;
12263
12264
const defineName = `define${++j}`;
12265
// TODO get cell specififiers here and pass in as 2nd param to resolveImportPath
12266
// need to use same logic as tree-shake name()s
12267
const specifiers = body.specifiers.map(d => {
12268
const prefix = d.view ? "viewof " : d.mutable ? "mutable " : "";
12269
return `${prefix}${d.imported.name}`;
12270
});
12271
const fromPath = resolveImportPath(body.source.value, specifiers);
12272
importMap.set(body.source.value, { defineName, fromPath });
12273
importSrc += `import ${defineName} from "${fromPath}";\n`;
12274
}
12275
12276
if (importSrc.length) importSrc += "\n";
12277
return { importSrc, importMap };
12278
}
12279
12280
// by default, file attachments get resolved like:
12281
// [ ["a", "https://example.com/files/a"] ]
12282
// but sometimes, you'll want to write JS code when resolving
12283
// instead of being limiting by strings. The third param
12284
// enables that, allowing for resolving like:
12285
// [ ["a", new URL("./files/a", import.meta.url)] ]
12286
function ESMAttachments(
12287
moduleObject,
12288
resolveFileAttachments,
12289
UNSAFE_allowJavascriptFileAttachments = false
12290
) {
12291
let mapValue;
12292
if (UNSAFE_allowJavascriptFileAttachments) {
12293
const attachmentMapEntries = [];
12294
for (const cell of moduleObject.cells) {
12295
if (cell.fileAttachments.size === 0) continue;
12296
for (const file of cell.fileAttachments.keys())
12297
attachmentMapEntries.push([file, resolveFileAttachments(file)]);
12298
}
12299
if (attachmentMapEntries.length)
12300
mapValue = `[${attachmentMapEntries
12301
.map(([key, value]) => `[${JSON.stringify(key)}, ${value}]`)
12302
.join(",")}]`;
12303
} else {
12304
const attachmentMapEntries = [];
12305
// loop over cells with fileAttachments
12306
for (const cell of moduleObject.cells) {
12307
if (cell.fileAttachments.size === 0) continue;
12308
// add filenames and resolved URLs to array
12309
for (const file of cell.fileAttachments.keys())
12310
attachmentMapEntries.push([file, resolveFileAttachments(file)]);
12311
}
12312
if (attachmentMapEntries.length)
12313
mapValue = JSON.stringify(attachmentMapEntries);
12314
}
12315
12316
if (!mapValue) return "";
12317
return ` const fileAttachments = new Map(${mapValue});
12318
main.builtin("FileAttachment", runtime.fileAttachments(name => fileAttachments.get(name)));`;
12319
}
12320
12321
function ESMVariables(moduleObject, importMap, params) {
12322
const {
12323
defineImportMarkdown,
12324
observeViewofValues,
12325
observeMutableValues
12326
} = params;
12327
12328
let childJ = 0;
12329
return moduleObject.cells
12330
.map(cell => {
12331
let src = "";
12332
12333
if (cell.body.type === "ImportDeclaration") {
12334
const {
12335
specifiers,
12336
hasInjections,
12337
injections,
12338
importString
12339
} = setupImportCell(cell);
12340
12341
if (defineImportMarkdown)
12342
src +=
12343
` main.variable(observer()).define(
12344
null,
12345
["md"],
12346
md => md\`~~~javascript
12347
${importString}
12348
~~~\`
12349
);` + "\n";
12350
12351
// name imported notebook define functions
12352
const childName = `child${++childJ}`;
12353
src += ` const ${childName} = runtime.module(${
12354
importMap.get(cell.body.source.value).defineName
12355
})${
12356
hasInjections ? `.derive(${JSON.stringify(injections)}, main)` : ""
12357
};
12358
${specifiers
12359
.map(
12360
specifier =>
12361
` main.import("${specifier.name}", "${specifier.alias}", ${childName});`
12362
)
12363
.join("\n")}`;
12364
} else {
12365
const {
12366
cellName,
12367
references,
12368
bodyText,
12369
cellReferences
12370
} = setupRegularCell(cell);
12371
12372
const cellNameString = cellName ? `"${cellName}"` : "";
12373
const referenceString = references.join(",");
12374
let code = "";
12375
if (cell.body.type !== "BlockStatement")
12376
code = `{return(
12377
${bodyText}
12378
)}`;
12379
else code = "\n" + bodyText + "\n";
12380
const cellReferencesString = cellReferences.length
12381
? JSON.stringify(cellReferences) + ", "
12382
: "";
12383
let cellFunction = "";
12384
if (cell.generator && cell.async)
12385
cellFunction = `async function*(${referenceString})${code}`;
12386
else if (cell.async)
12387
cellFunction = `async function(${referenceString})${code}`;
12388
else if (cell.generator)
12389
cellFunction = `function*(${referenceString})${code}`;
12390
else cellFunction = `function(${referenceString})${code}`;
12391
12392
if (cell.id && cell.id.type === "ViewExpression") {
12393
const reference = `"viewof ${cellName}"`;
12394
src += ` main.variable(observer(${reference})).define(${reference}, ${cellReferencesString}${cellFunction});
12395
main.variable(${
12396
observeViewofValues ? `observer("${cellName}")` : `null`
12397
}).define("${cellName}", ["Generators", ${reference}], (G, _) => G.input(_));`;
12398
} else if (cell.id && cell.id.type === "MutableExpression") {
12399
const initialName = `"initial ${cellName}"`;
12400
const mutableName = `"mutable ${cellName}"`;
12401
src += ` main.define(${initialName}, ${cellReferencesString}${cellFunction});
12402
main.variable(observer(${mutableName})).define(${mutableName}, ["Mutable", ${initialName}], (M, _) => new M(_));
12403
main.variable(${
12404
observeMutableValues ? `observer("${cellName}")` : `null`
12405
}).define("${cellName}", [${mutableName}], _ => _.generator);`;
12406
} else {
12407
src += ` main.variable(observer(${cellNameString})).define(${
12408
cellName ? cellNameString + ", " : ""
12409
}${cellReferencesString}${cellFunction});`;
12410
}
12411
}
12412
return src;
12413
})
12414
.join("\n");
12415
}
12416
function createESModule(moduleObject, params = {}) {
12417
const {
12418
resolveImportPath,
12419
resolveFileAttachments,
12420
defineImportMarkdown,
12421
observeViewofValues,
12422
observeMutableValues,
12423
UNSAFE_allowJavascriptFileAttachments
12424
} = params;
12425
const { importSrc, importMap } = ESMImports(moduleObject, resolveImportPath);
12426
return `${importSrc}export default function define(runtime, observer) {
12427
const main = runtime.module();
12428
${ESMAttachments(
12429
moduleObject,
12430
resolveFileAttachments,
12431
UNSAFE_allowJavascriptFileAttachments
12432
)}
12433
${ESMVariables(moduleObject, importMap, {
12434
defineImportMarkdown,
12435
observeViewofValues,
12436
observeMutableValues
12437
}) || ""}
12438
return main;
12439
}`;
12440
}
12441
12442
function defaultResolveImportPath(path) {
12443
const source = extractPath(path);
12444
return `https://api.observablehq.com/${source}.js?v=3`;
12445
}
12446
12447
function defaultResolveFileAttachments(name) {
12448
return name;
12449
}
12450
class Compiler {
12451
constructor(params = {}) {
12452
const {
12453
resolveFileAttachments = defaultResolveFileAttachments,
12454
resolveImportPath = defaultResolveImportPath,
12455
defineImportMarkdown = true,
12456
observeViewofValues = true,
12457
observeMutableValues = true,
12458
UNSAFE_allowJavascriptFileAttachments = false
12459
} = params;
12460
this.resolveFileAttachments = resolveFileAttachments;
12461
this.resolveImportPath = resolveImportPath;
12462
this.defineImportMarkdown = defineImportMarkdown;
12463
this.observeViewofValues = observeViewofValues;
12464
this.observeMutableValues = observeMutableValues;
12465
this.UNSAFE_allowJavascriptFileAttachments = UNSAFE_allowJavascriptFileAttachments;
12466
}
12467
module(input, params = {}) {
12468
let m1 = typeof input === "string" ? parseModule(input) : input;
12469
12470
if (params.treeShake) m1 = treeShakeModule(m1, params.treeShake);
12471
12472
return createESModule(m1, {
12473
resolveImportPath: this.resolveImportPath,
12474
resolveFileAttachments: this.resolveFileAttachments,
12475
defineImportMarkdown: this.defineImportMarkdown,
12476
observeViewofValues: this.observeViewofValues,
12477
observeMutableValues: this.observeMutableValues,
12478
UNSAFE_allowJavascriptFileAttachments: this
12479
.UNSAFE_allowJavascriptFileAttachments
12480
});
12481
}
12482
notebook(obj) {
12483
const cells = obj.nodes.map(({ value }) => {
12484
const cell = parseCell(value);
12485
cell.input = value;
12486
return cell;
12487
});
12488
return createESModule(
12489
{ cells },
12490
{
12491
resolveImportPath: this.resolveImportPath,
12492
resolveFileAttachments: this.resolveFileAttachments,
12493
defineImportMarkdown: this.defineImportMarkdown,
12494
observeViewofValues: this.observeViewofValues,
12495
observeMutableValues: this.observeMutableValues
12496
}
12497
);
12498
}
12499
}const AsyncFunction = Object.getPrototypeOf(async function() {}).constructor;
12500
const GeneratorFunction = Object.getPrototypeOf(function*() {}).constructor;
12501
const AsyncGeneratorFunction = Object.getPrototypeOf(async function*() {})
12502
.constructor;
12503
12504
function createRegularCellDefinition(cell) {
12505
const { cellName, references, bodyText, cellReferences } = setupRegularCell(
12506
cell
12507
);
12508
12509
let code;
12510
if (cell.body.type !== "BlockStatement") {
12511
if (cell.async)
12512
code = `return (async function(){ return (${bodyText});})()`;
12513
else code = `return (function(){ return (${bodyText});})()`;
12514
} else code = bodyText;
12515
12516
let f;
12517
if (cell.generator && cell.async)
12518
f = new AsyncGeneratorFunction(...references, code);
12519
else if (cell.async) f = new AsyncFunction(...references, code);
12520
else if (cell.generator) f = new GeneratorFunction(...references, code);
12521
else f = new Function(...references, code);
12522
return {
12523
cellName,
12524
cellFunction: f,
12525
cellReferences
12526
};
12527
}
12528
12529
function defaultResolveImportPath$1(path) {
12530
const source = extractPath(path);
12531
return import(`https://api.observablehq.com/${source}.js?v=3`).then(
12532
m => m.default
12533
);
12534
}
12535
12536
function defaultResolveFileAttachments$1(name) {
12537
return name;
12538
}
12539
12540
class Interpreter {
12541
constructor(params = {}) {
12542
const {
12543
module = null,
12544
observer = null,
12545
resolveImportPath = defaultResolveImportPath$1,
12546
resolveFileAttachments = defaultResolveFileAttachments$1,
12547
defineImportMarkdown = true,
12548
observeViewofValues = true,
12549
observeMutableValues = true
12550
} = params;
12551
12552
// can't be this.module bc of async module().
12553
// so make defaultObserver follow same convention.
12554
this.defaultModule = module;
12555
this.defaultObserver = observer;
12556
12557
this.resolveImportPath = resolveImportPath;
12558
this.resolveFileAttachments = resolveFileAttachments;
12559
this.defineImportMarkdown = defineImportMarkdown;
12560
this.observeViewofValues = observeViewofValues;
12561
this.observeMutableValues = observeMutableValues;
12562
}
12563
12564
async module(input, module, observer) {
12565
module = module || this.defaultModule;
12566
observer = observer || this.defaultObserver;
12567
12568
if (!module) throw Error("No module provided.");
12569
if (!observer) throw Error("No observer provided.");
12570
12571
const parsedModule = parseModule(input);
12572
const cellPromises = [];
12573
for (const cell of parsedModule.cells) {
12574
cell.input = input;
12575
cellPromises.push(this.cell(cell, module, observer));
12576
}
12577
return Promise.all(cellPromises);
12578
}
12579
12580
async cell(input, module, observer) {
12581
module = module || this.defaultModule;
12582
observer = observer || this.defaultObserver;
12583
12584
if (!module) throw Error("No module provided.");
12585
if (!observer) throw Error("No observer provided.");
12586
12587
let cell;
12588
if (typeof input === "string") {
12589
cell = parseCell(input);
12590
cell.input = input;
12591
} else {
12592
cell = input;
12593
}
12594
12595
if (cell.body.type === "ImportDeclaration") {
12596
const path = cell.body.source.value;
12597
const specs = cell.body.specifiers.map(d => {
12598
const prefix = d.view ? "viewof " : d.mutable ? "mutable " : "";
12599
return `${prefix}${d.imported.name}`;
12600
});
12601
const fromModule = await this.resolveImportPath(path, specs);
12602
let mdVariable, vars;
12603
12604
const {
12605
specifiers,
12606
hasInjections,
12607
injections,
12608
importString
12609
} = setupImportCell(cell);
12610
12611
const other = module._runtime.module(fromModule);
12612
12613
if (this.defineImportMarkdown)
12614
mdVariable = module.variable(observer()).define(
12615
null,
12616
["md"],
12617
md => md`~~~javascript
12618
${importString}
12619
~~~`
12620
);
12621
if (hasInjections) {
12622
const child = other.derive(injections, module);
12623
vars = specifiers.map(({ name, alias }) =>
12624
module.import(name, alias, child)
12625
);
12626
} else {
12627
vars = specifiers.map(({ name, alias }) =>
12628
module.import(name, alias, other)
12629
);
12630
}
12631
return mdVariable ? [mdVariable, ...vars] : vars;
12632
} else {
12633
const {
12634
cellName,
12635
cellFunction,
12636
cellReferences
12637
} = createRegularCellDefinition(cell);
12638
if (cell.id && cell.id.type === "ViewExpression") {
12639
const reference = `viewof ${cellName}`;
12640
return [
12641
module
12642
.variable(observer(reference))
12643
.define(reference, cellReferences, cellFunction.bind(this)),
12644
module
12645
.variable(this.observeViewofValues ? observer(cellName) : null)
12646
.define(cellName, ["Generators", reference], (G, _) => G.input(_))
12647
];
12648
} else if (cell.id && cell.id.type === "MutableExpression") {
12649
const initialName = `initial ${cellName}`;
12650
const mutableName = `mutable ${cellName}`;
12651
return [
12652
module
12653
.variable(null)
12654
.define(initialName, cellReferences, cellFunction),
12655
module
12656
.variable(observer(mutableName))
12657
.define(mutableName, ["Mutable", initialName], (M, _) => new M(_)),
12658
module
12659
.variable(this.observeMutableValues ? observer(cellName) : null)
12660
.define(cellName, [mutableName], _ => _.generator)
12661
];
12662
} else {
12663
return [
12664
module
12665
.variable(observer(cellName))
12666
.define(cellName, cellReferences, cellFunction.bind(this))
12667
];
12668
}
12669
}
12670
}
12671
}exports.Compiler=Compiler;exports.Interpreter=Interpreter;exports.parser=index;exports.treeShakeModule=treeShakeModule;Object.defineProperty(exports,'__esModule',{value:true});})));
12672
} (dist, dist.exports));
12673
12674
// This file was generated. Do not modify manually!
12675
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, 370, 1, 154, 10, 50, 3, 123, 2, 54, 14, 32, 10, 3, 1, 11, 3, 46, 10, 8, 0, 46, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 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, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 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, 87, 9, 39, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 4706, 45, 3, 22, 543, 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, 357, 0, 62, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239];
12676
12677
// This file was generated. Do not modify manually!
12678
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, 13, 10, 2, 14, 2, 6, 2, 1, 2, 10, 2, 14, 2, 6, 2, 1, 68, 310, 10, 21, 11, 7, 25, 5, 2, 41, 2, 8, 70, 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, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 43, 17, 47, 20, 28, 22, 13, 52, 58, 1, 3, 0, 14, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 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, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 38, 6, 186, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 19, 72, 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, 190, 0, 80, 921, 103, 110, 18, 195, 2637, 96, 16, 1070, 4050, 582, 8634, 568, 8, 30, 18, 78, 18, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8936, 3, 2, 6, 2, 1, 2, 290, 46, 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, 1845, 30, 482, 44, 11, 6, 17, 0, 322, 29, 19, 43, 1269, 6, 2, 3, 2, 1, 2, 14, 2, 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, 42719, 33, 4152, 8, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938];
12679
12680
// This file was generated. Do not modify manually!
12681
var nonASCIIidentifierChars = "\u200c\u200d\xb7\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\u0898-\u089f\u08ca-\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\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3c\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\u0d81-\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-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u180f-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf-\u1ace\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-\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\ua82c\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";
12682
12683
// This file was generated. Do not modify manually!
12684
var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\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\u0870-\u0887\u0889-\u088e\u08a0-\u08c9\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\u0c5d\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cdd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\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-\u1711\u171f-\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-\u1b4c\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-\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-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7ca\ua7d0\ua7d1\ua7d3\ua7d5-\ua7d9\ua7f2-\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-\uab69\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";
12685
12686
// These are a run-length and offset encoded representation of the
12687
12688
// Reserved word lists for various dialects of the language
12689
12690
var reservedWords = {
12691
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",
12692
5: "class enum extends super const export import",
12693
6: "enum",
12694
strict: "implements interface let package private protected public static yield",
12695
strictBind: "eval arguments"
12696
};
12697
12698
// And the keywords
12699
12700
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";
12701
12702
var keywords$1 = {
12703
5: ecma5AndLessKeywords,
12704
"5module": ecma5AndLessKeywords + " export import",
12705
6: ecma5AndLessKeywords + " const class extends export import super"
12706
};
12707
12708
var keywordRelationalOperator = /^in(stanceof)?$/;
12709
12710
// ## Character categories
12711
12712
var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
12713
var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
12714
12715
// This has a complexity linear to the value of the code. The
12716
// assumption is that looking up astral identifier characters is
12717
// rare.
12718
function isInAstralSet(code, set) {
12719
var pos = 0x10000;
12720
for (var i = 0; i < set.length; i += 2) {
12721
pos += set[i];
12722
if (pos > code) { return false }
12723
pos += set[i + 1];
12724
if (pos >= code) { return true }
12725
}
12726
}
12727
12728
// Test whether a given character code starts an identifier.
12729
12730
function isIdentifierStart(code, astral) {
12731
if (code < 65) { return code === 36 }
12732
if (code < 91) { return true }
12733
if (code < 97) { return code === 95 }
12734
if (code < 123) { return true }
12735
if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
12736
if (astral === false) { return false }
12737
return isInAstralSet(code, astralIdentifierStartCodes)
12738
}
12739
12740
// Test whether a given character is part of an identifier.
12741
12742
function isIdentifierChar(code, astral) {
12743
if (code < 48) { return code === 36 }
12744
if (code < 58) { return true }
12745
if (code < 65) { return false }
12746
if (code < 91) { return true }
12747
if (code < 97) { return code === 95 }
12748
if (code < 123) { return true }
12749
if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
12750
if (astral === false) { return false }
12751
return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
12752
}
12753
12754
// ## Token types
12755
12756
// The assignment of fine-grained, information-carrying type objects
12757
// allows the tokenizer to store the information it has about a
12758
// token in a way that is very cheap for the parser to look up.
12759
12760
// All token type variables start with an underscore, to make them
12761
// easy to recognize.
12762
12763
// The `beforeExpr` property is used to disambiguate between regular
12764
// expressions and divisions. It is set on all token types that can
12765
// be followed by an expression (thus, a slash after them would be a
12766
// regular expression).
12767
//
12768
// The `startsExpr` property is used to check if the token ends a
12769
// `yield` expression. It is set on all token types that either can
12770
// directly start an expression (like a quotation mark) or can
12771
// continue an expression (like the body of a string).
12772
//
12773
// `isLoop` marks a keyword as starting a loop, which is important
12774
// to know when parsing a label, in order to allow or disallow
12775
// continue jumps to that label.
12776
12777
var TokenType = function TokenType(label, conf) {
12778
if ( conf === void 0 ) conf = {};
12779
12780
this.label = label;
12781
this.keyword = conf.keyword;
12782
this.beforeExpr = !!conf.beforeExpr;
12783
this.startsExpr = !!conf.startsExpr;
12784
this.isLoop = !!conf.isLoop;
12785
this.isAssign = !!conf.isAssign;
12786
this.prefix = !!conf.prefix;
12787
this.postfix = !!conf.postfix;
12788
this.binop = conf.binop || null;
12789
this.updateContext = null;
12790
};
12791
12792
function binop(name, prec) {
12793
return new TokenType(name, {beforeExpr: true, binop: prec})
12794
}
12795
var beforeExpr = {beforeExpr: true}, startsExpr = {startsExpr: true};
12796
12797
// Map keyword names to token types.
12798
12799
var keywords = {};
12800
12801
// Succinct definitions of keyword token types
12802
function kw(name, options) {
12803
if ( options === void 0 ) options = {};
12804
12805
options.keyword = name;
12806
return keywords[name] = new TokenType(name, options)
12807
}
12808
12809
var types$1 = {
12810
num: new TokenType("num", startsExpr),
12811
regexp: new TokenType("regexp", startsExpr),
12812
string: new TokenType("string", startsExpr),
12813
name: new TokenType("name", startsExpr),
12814
privateId: new TokenType("privateId", startsExpr),
12815
eof: new TokenType("eof"),
12816
12817
// Punctuation token types.
12818
bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
12819
bracketR: new TokenType("]"),
12820
braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
12821
braceR: new TokenType("}"),
12822
parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
12823
parenR: new TokenType(")"),
12824
comma: new TokenType(",", beforeExpr),
12825
semi: new TokenType(";", beforeExpr),
12826
colon: new TokenType(":", beforeExpr),
12827
dot: new TokenType("."),
12828
question: new TokenType("?", beforeExpr),
12829
questionDot: new TokenType("?."),
12830
arrow: new TokenType("=>", beforeExpr),
12831
template: new TokenType("template"),
12832
invalidTemplate: new TokenType("invalidTemplate"),
12833
ellipsis: new TokenType("...", beforeExpr),
12834
backQuote: new TokenType("`", startsExpr),
12835
dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
12836
12837
// Operators. These carry several kinds of properties to help the
12838
// parser use them properly (the presence of these properties is
12839
// what categorizes them as operators).
12840
//
12841
// `binop`, when present, specifies that this operator is a binary
12842
// operator, and will refer to its precedence.
12843
//
12844
// `prefix` and `postfix` mark the operator as a prefix or postfix
12845
// unary operator.
12846
//
12847
// `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
12848
// binary operators with a very low precedence, that should result
12849
// in AssignmentExpression nodes.
12850
12851
eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
12852
assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
12853
incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
12854
prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
12855
logicalOR: binop("||", 1),
12856
logicalAND: binop("&&", 2),
12857
bitwiseOR: binop("|", 3),
12858
bitwiseXOR: binop("^", 4),
12859
bitwiseAND: binop("&", 5),
12860
equality: binop("==/!=/===/!==", 6),
12861
relational: binop("</>/<=/>=", 7),
12862
bitShift: binop("<</>>/>>>", 8),
12863
plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
12864
modulo: binop("%", 10),
12865
star: binop("*", 10),
12866
slash: binop("/", 10),
12867
starstar: new TokenType("**", {beforeExpr: true}),
12868
coalesce: binop("??", 1),
12869
12870
// Keyword token types.
12871
_break: kw("break"),
12872
_case: kw("case", beforeExpr),
12873
_catch: kw("catch"),
12874
_continue: kw("continue"),
12875
_debugger: kw("debugger"),
12876
_default: kw("default", beforeExpr),
12877
_do: kw("do", {isLoop: true, beforeExpr: true}),
12878
_else: kw("else", beforeExpr),
12879
_finally: kw("finally"),
12880
_for: kw("for", {isLoop: true}),
12881
_function: kw("function", startsExpr),
12882
_if: kw("if"),
12883
_return: kw("return", beforeExpr),
12884
_switch: kw("switch"),
12885
_throw: kw("throw", beforeExpr),
12886
_try: kw("try"),
12887
_var: kw("var"),
12888
_const: kw("const"),
12889
_while: kw("while", {isLoop: true}),
12890
_with: kw("with"),
12891
_new: kw("new", {beforeExpr: true, startsExpr: true}),
12892
_this: kw("this", startsExpr),
12893
_super: kw("super", startsExpr),
12894
_class: kw("class", startsExpr),
12895
_extends: kw("extends", beforeExpr),
12896
_export: kw("export"),
12897
_import: kw("import", startsExpr),
12898
_null: kw("null", startsExpr),
12899
_true: kw("true", startsExpr),
12900
_false: kw("false", startsExpr),
12901
_in: kw("in", {beforeExpr: true, binop: 7}),
12902
_instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
12903
_typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
12904
_void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
12905
_delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
12906
};
12907
12908
// Matches a whole line break (where CRLF is considered a single
12909
// line break). Used to count lines.
12910
12911
var lineBreak = /\r\n?|\n|\u2028|\u2029/;
12912
var lineBreakG = new RegExp(lineBreak.source, "g");
12913
12914
function isNewLine(code) {
12915
return code === 10 || code === 13 || code === 0x2028 || code === 0x2029
12916
}
12917
12918
function nextLineBreak(code, from, end) {
12919
if ( end === void 0 ) end = code.length;
12920
12921
for (var i = from; i < end; i++) {
12922
var next = code.charCodeAt(i);
12923
if (isNewLine(next))
12924
{ return i < end - 1 && next === 13 && code.charCodeAt(i + 1) === 10 ? i + 2 : i + 1 }
12925
}
12926
return -1
12927
}
12928
12929
var nonASCIIwhitespace = /[\u1680\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
12930
12931
var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
12932
12933
var ref = Object.prototype;
12934
var hasOwnProperty = ref.hasOwnProperty;
12935
var toString = ref.toString;
12936
12937
var hasOwn = Object.hasOwn || (function (obj, propName) { return (
12938
hasOwnProperty.call(obj, propName)
12939
); });
12940
12941
var isArray = Array.isArray || (function (obj) { return (
12942
toString.call(obj) === "[object Array]"
12943
); });
12944
12945
function wordsRegexp(words) {
12946
return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
12947
}
12948
12949
function codePointToString(code) {
12950
// UTF-16 Decoding
12951
if (code <= 0xFFFF) { return String.fromCharCode(code) }
12952
code -= 0x10000;
12953
return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
12954
}
12955
12956
var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
12957
12958
// These are used when `options.locations` is on, for the
12959
// `startLoc` and `endLoc` properties.
12960
12961
var Position = function Position(line, col) {
12962
this.line = line;
12963
this.column = col;
12964
};
12965
12966
Position.prototype.offset = function offset (n) {
12967
return new Position(this.line, this.column + n)
12968
};
12969
12970
var SourceLocation = function SourceLocation(p, start, end) {
12971
this.start = start;
12972
this.end = end;
12973
if (p.sourceFile !== null) { this.source = p.sourceFile; }
12974
};
12975
12976
// The `getLineInfo` function is mostly useful when the
12977
// `locations` option is off (for performance reasons) and you
12978
// want to find the line/column position for a given character
12979
// offset. `input` should be the code string that the offset refers
12980
// into.
12981
12982
function getLineInfo(input, offset) {
12983
for (var line = 1, cur = 0;;) {
12984
var nextBreak = nextLineBreak(input, cur, offset);
12985
if (nextBreak < 0) { return new Position(line, offset - cur) }
12986
++line;
12987
cur = nextBreak;
12988
}
12989
}
12990
12991
// A second argument must be given to configure the parser process.
12992
// These options are recognized (only `ecmaVersion` is required):
12993
12994
var defaultOptions = {
12995
// `ecmaVersion` indicates the ECMAScript version to parse. Must be
12996
// either 3, 5, 6 (or 2015), 7 (2016), 8 (2017), 9 (2018), 10
12997
// (2019), 11 (2020), 12 (2021), 13 (2022), 14 (2023), or `"latest"`
12998
// (the latest version the library supports). This influences
12999
// support for strict mode, the set of reserved words, and support
13000
// for new syntax features.
13001
ecmaVersion: null,
13002
// `sourceType` indicates the mode the code should be parsed in.
13003
// Can be either `"script"` or `"module"`. This influences global
13004
// strict mode and parsing of `import` and `export` declarations.
13005
sourceType: "script",
13006
// `onInsertedSemicolon` can be a callback that will be called
13007
// when a semicolon is automatically inserted. It will be passed
13008
// the position of the comma as an offset, and if `locations` is
13009
// enabled, it is given the location as a `{line, column}` object
13010
// as second argument.
13011
onInsertedSemicolon: null,
13012
// `onTrailingComma` is similar to `onInsertedSemicolon`, but for
13013
// trailing commas.
13014
onTrailingComma: null,
13015
// By default, reserved words are only enforced if ecmaVersion >= 5.
13016
// Set `allowReserved` to a boolean value to explicitly turn this on
13017
// an off. When this option has the value "never", reserved words
13018
// and keywords can also not be used as property names.
13019
allowReserved: null,
13020
// When enabled, a return at the top level is not considered an
13021
// error.
13022
allowReturnOutsideFunction: false,
13023
// When enabled, import/export statements are not constrained to
13024
// appearing at the top of the program, and an import.meta expression
13025
// in a script isn't considered an error.
13026
allowImportExportEverywhere: false,
13027
// By default, await identifiers are allowed to appear at the top-level scope only if ecmaVersion >= 2022.
13028
// When enabled, await identifiers are allowed to appear at the top-level scope,
13029
// but they are still not allowed in non-async functions.
13030
allowAwaitOutsideFunction: null,
13031
// When enabled, super identifiers are not constrained to
13032
// appearing in methods and do not raise an error when they appear elsewhere.
13033
allowSuperOutsideMethod: null,
13034
// When enabled, hashbang directive in the beginning of file is
13035
// allowed and treated as a line comment. Enabled by default when
13036
// `ecmaVersion` >= 2023.
13037
allowHashBang: false,
13038
// When `locations` is on, `loc` properties holding objects with
13039
// `start` and `end` properties in `{line, column}` form (with
13040
// line being 1-based and column 0-based) will be attached to the
13041
// nodes.
13042
locations: false,
13043
// A function can be passed as `onToken` option, which will
13044
// cause Acorn to call that function with object in the same
13045
// format as tokens returned from `tokenizer().getToken()`. Note
13046
// that you are not allowed to call the parser from the
13047
// callback—that will corrupt its internal state.
13048
onToken: null,
13049
// A function can be passed as `onComment` option, which will
13050
// cause Acorn to call that function with `(block, text, start,
13051
// end)` parameters whenever a comment is skipped. `block` is a
13052
// boolean indicating whether this is a block (`/* */`) comment,
13053
// `text` is the content of the comment, and `start` and `end` are
13054
// character offsets that denote the start and end of the comment.
13055
// When the `locations` option is on, two more parameters are
13056
// passed, the full `{line, column}` locations of the start and
13057
// end of the comments. Note that you are not allowed to call the
13058
// parser from the callback—that will corrupt its internal state.
13059
onComment: null,
13060
// Nodes have their start and end characters offsets recorded in
13061
// `start` and `end` properties (directly on the node, rather than
13062
// the `loc` object, which holds line/column data. To also add a
13063
// [semi-standardized][range] `range` property holding a `[start,
13064
// end]` array with the same numbers, set the `ranges` option to
13065
// `true`.
13066
//
13067
// [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
13068
ranges: false,
13069
// It is possible to parse multiple files into a single AST by
13070
// passing the tree produced by parsing the first file as
13071
// `program` option in subsequent parses. This will add the
13072
// toplevel forms of the parsed file to the `Program` (top) node
13073
// of an existing parse tree.
13074
program: null,
13075
// When `locations` is on, you can pass this to record the source
13076
// file in every node's `loc` object.
13077
sourceFile: null,
13078
// This value, if given, is stored in every node, whether
13079
// `locations` is on or off.
13080
directSourceFile: null,
13081
// When enabled, parenthesized expressions are represented by
13082
// (non-standard) ParenthesizedExpression nodes
13083
preserveParens: false
13084
};
13085
13086
// Interpret and default an options object
13087
13088
var warnedAboutEcmaVersion = false;
13089
13090
function getOptions(opts) {
13091
var options = {};
13092
13093
for (var opt in defaultOptions)
13094
{ options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt]; }
13095
13096
if (options.ecmaVersion === "latest") {
13097
options.ecmaVersion = 1e8;
13098
} else if (options.ecmaVersion == null) {
13099
if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) {
13100
warnedAboutEcmaVersion = true;
13101
console.warn("Since Acorn 8.0.0, options.ecmaVersion is required.\nDefaulting to 2020, but this will stop working in the future.");
13102
}
13103
options.ecmaVersion = 11;
13104
} else if (options.ecmaVersion >= 2015) {
13105
options.ecmaVersion -= 2009;
13106
}
13107
13108
if (options.allowReserved == null)
13109
{ options.allowReserved = options.ecmaVersion < 5; }
13110
13111
if (opts.allowHashBang == null)
13112
{ options.allowHashBang = options.ecmaVersion >= 14; }
13113
13114
if (isArray(options.onToken)) {
13115
var tokens = options.onToken;
13116
options.onToken = function (token) { return tokens.push(token); };
13117
}
13118
if (isArray(options.onComment))
13119
{ options.onComment = pushComment(options, options.onComment); }
13120
13121
return options
13122
}
13123
13124
function pushComment(options, array) {
13125
return function(block, text, start, end, startLoc, endLoc) {
13126
var comment = {
13127
type: block ? "Block" : "Line",
13128
value: text,
13129
start: start,
13130
end: end
13131
};
13132
if (options.locations)
13133
{ comment.loc = new SourceLocation(this, startLoc, endLoc); }
13134
if (options.ranges)
13135
{ comment.range = [start, end]; }
13136
array.push(comment);
13137
}
13138
}
13139
13140
// Each scope gets a bitset that may contain these flags
13141
var
13142
SCOPE_TOP = 1,
13143
SCOPE_FUNCTION$1 = 2,
13144
SCOPE_ASYNC$1 = 4,
13145
SCOPE_GENERATOR$1 = 8,
13146
SCOPE_ARROW = 16,
13147
SCOPE_SIMPLE_CATCH = 32,
13148
SCOPE_SUPER = 64,
13149
SCOPE_DIRECT_SUPER = 128,
13150
SCOPE_CLASS_STATIC_BLOCK = 256,
13151
SCOPE_VAR = SCOPE_TOP | SCOPE_FUNCTION$1 | SCOPE_CLASS_STATIC_BLOCK;
13152
13153
function functionFlags(async, generator) {
13154
return SCOPE_FUNCTION$1 | (async ? SCOPE_ASYNC$1 : 0) | (generator ? SCOPE_GENERATOR$1 : 0)
13155
}
13156
13157
// Used in checkLVal* and declareName to determine the type of a binding
13158
var
13159
BIND_NONE = 0, // Not a binding
13160
BIND_VAR = 1, // Var-style binding
13161
BIND_LEXICAL = 2, // Let- or const-style binding
13162
BIND_FUNCTION = 3, // Function declaration
13163
BIND_SIMPLE_CATCH = 4, // Simple (identifier pattern) catch binding
13164
BIND_OUTSIDE = 5; // Special case for function names as bound inside the function
13165
13166
var Parser = function Parser(options, input, startPos) {
13167
this.options = options = getOptions(options);
13168
this.sourceFile = options.sourceFile;
13169
this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
13170
var reserved = "";
13171
if (options.allowReserved !== true) {
13172
reserved = reservedWords[options.ecmaVersion >= 6 ? 6 : options.ecmaVersion === 5 ? 5 : 3];
13173
if (options.sourceType === "module") { reserved += " await"; }
13174
}
13175
this.reservedWords = wordsRegexp(reserved);
13176
var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
13177
this.reservedWordsStrict = wordsRegexp(reservedStrict);
13178
this.reservedWordsStrictBind = wordsRegexp(reservedStrict + " " + reservedWords.strictBind);
13179
this.input = String(input);
13180
13181
// Used to signal to callers of `readWord1` whether the word
13182
// contained any escape sequences. This is needed because words with
13183
// escape sequences must not be interpreted as keywords.
13184
this.containsEsc = false;
13185
13186
// Set up token state
13187
13188
// The current position of the tokenizer in the input.
13189
if (startPos) {
13190
this.pos = startPos;
13191
this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
13192
this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
13193
} else {
13194
this.pos = this.lineStart = 0;
13195
this.curLine = 1;
13196
}
13197
13198
// Properties of the current token:
13199
// Its type
13200
this.type = types$1.eof;
13201
// For tokens that include more information than their type, the value
13202
this.value = null;
13203
// Its start and end offset
13204
this.start = this.end = this.pos;
13205
// And, if locations are used, the {line, column} object
13206
// corresponding to those offsets
13207
this.startLoc = this.endLoc = this.curPosition();
13208
13209
// Position information for the previous token
13210
this.lastTokEndLoc = this.lastTokStartLoc = null;
13211
this.lastTokStart = this.lastTokEnd = this.pos;
13212
13213
// The context stack is used to superficially track syntactic
13214
// context to predict whether a regular expression is allowed in a
13215
// given position.
13216
this.context = this.initialContext();
13217
this.exprAllowed = true;
13218
13219
// Figure out if it's a module code.
13220
this.inModule = options.sourceType === "module";
13221
this.strict = this.inModule || this.strictDirective(this.pos);
13222
13223
// Used to signify the start of a potential arrow function
13224
this.potentialArrowAt = -1;
13225
this.potentialArrowInForAwait = false;
13226
13227
// Positions to delayed-check that yield/await does not exist in default parameters.
13228
this.yieldPos = this.awaitPos = this.awaitIdentPos = 0;
13229
// Labels in scope.
13230
this.labels = [];
13231
// Thus-far undefined exports.
13232
this.undefinedExports = Object.create(null);
13233
13234
// If enabled, skip leading hashbang line.
13235
if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
13236
{ this.skipLineComment(2); }
13237
13238
// Scope tracking for duplicate variable names (see scope.js)
13239
this.scopeStack = [];
13240
this.enterScope(SCOPE_TOP);
13241
13242
// For RegExp validation
13243
this.regexpState = null;
13244
13245
// The stack of private names.
13246
// Each element has two properties: 'declared' and 'used'.
13247
// When it exited from the outermost class definition, all used private names must be declared.
13248
this.privateNameStack = [];
13249
};
13250
13251
var prototypeAccessors = { inFunction: { configurable: true },inGenerator: { configurable: true },inAsync: { configurable: true },canAwait: { configurable: true },allowSuper: { configurable: true },allowDirectSuper: { configurable: true },treatFunctionsAsVar: { configurable: true },allowNewDotTarget: { configurable: true },inClassStaticBlock: { configurable: true } };
13252
13253
Parser.prototype.parse = function parse () {
13254
var node = this.options.program || this.startNode();
13255
this.nextToken();
13256
return this.parseTopLevel(node)
13257
};
13258
13259
prototypeAccessors.inFunction.get = function () { return (this.currentVarScope().flags & SCOPE_FUNCTION$1) > 0 };
13260
13261
prototypeAccessors.inGenerator.get = function () { return (this.currentVarScope().flags & SCOPE_GENERATOR$1) > 0 && !this.currentVarScope().inClassFieldInit };
13262
13263
prototypeAccessors.inAsync.get = function () { return (this.currentVarScope().flags & SCOPE_ASYNC$1) > 0 && !this.currentVarScope().inClassFieldInit };
13264
13265
prototypeAccessors.canAwait.get = function () {
13266
for (var i = this.scopeStack.length - 1; i >= 0; i--) {
13267
var scope = this.scopeStack[i];
13268
if (scope.inClassFieldInit || scope.flags & SCOPE_CLASS_STATIC_BLOCK) { return false }
13269
if (scope.flags & SCOPE_FUNCTION$1) { return (scope.flags & SCOPE_ASYNC$1) > 0 }
13270
}
13271
return (this.inModule && this.options.ecmaVersion >= 13) || this.options.allowAwaitOutsideFunction
13272
};
13273
13274
prototypeAccessors.allowSuper.get = function () {
13275
var ref = this.currentThisScope();
13276
var flags = ref.flags;
13277
var inClassFieldInit = ref.inClassFieldInit;
13278
return (flags & SCOPE_SUPER) > 0 || inClassFieldInit || this.options.allowSuperOutsideMethod
13279
};
13280
13281
prototypeAccessors.allowDirectSuper.get = function () { return (this.currentThisScope().flags & SCOPE_DIRECT_SUPER) > 0 };
13282
13283
prototypeAccessors.treatFunctionsAsVar.get = function () { return this.treatFunctionsAsVarInScope(this.currentScope()) };
13284
13285
prototypeAccessors.allowNewDotTarget.get = function () {
13286
var ref = this.currentThisScope();
13287
var flags = ref.flags;
13288
var inClassFieldInit = ref.inClassFieldInit;
13289
return (flags & (SCOPE_FUNCTION$1 | SCOPE_CLASS_STATIC_BLOCK)) > 0 || inClassFieldInit
13290
};
13291
13292
prototypeAccessors.inClassStaticBlock.get = function () {
13293
return (this.currentVarScope().flags & SCOPE_CLASS_STATIC_BLOCK) > 0
13294
};
13295
13296
Parser.extend = function extend () {
13297
var plugins = [], len = arguments.length;
13298
while ( len-- ) plugins[ len ] = arguments[ len ];
13299
13300
var cls = this;
13301
for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
13302
return cls
13303
};
13304
13305
Parser.parse = function parse (input, options) {
13306
return new this(options, input).parse()
13307
};
13308
13309
Parser.parseExpressionAt = function parseExpressionAt (input, pos, options) {
13310
var parser = new this(options, input, pos);
13311
parser.nextToken();
13312
return parser.parseExpression()
13313
};
13314
13315
Parser.tokenizer = function tokenizer (input, options) {
13316
return new this(options, input)
13317
};
13318
13319
Object.defineProperties( Parser.prototype, prototypeAccessors );
13320
13321
var pp$9 = Parser.prototype;
13322
13323
// ## Parser utilities
13324
13325
var literal = /^(?:'((?:\\.|[^'\\])*?)'|"((?:\\.|[^"\\])*?)")/;
13326
pp$9.strictDirective = function(start) {
13327
if (this.options.ecmaVersion < 5) { return false }
13328
for (;;) {
13329
// Try to find string literal.
13330
skipWhiteSpace.lastIndex = start;
13331
start += skipWhiteSpace.exec(this.input)[0].length;
13332
var match = literal.exec(this.input.slice(start));
13333
if (!match) { return false }
13334
if ((match[1] || match[2]) === "use strict") {
13335
skipWhiteSpace.lastIndex = start + match[0].length;
13336
var spaceAfter = skipWhiteSpace.exec(this.input), end = spaceAfter.index + spaceAfter[0].length;
13337
var next = this.input.charAt(end);
13338
return next === ";" || next === "}" ||
13339
(lineBreak.test(spaceAfter[0]) &&
13340
!(/[(`.[+\-/*%<>=,?^&]/.test(next) || next === "!" && this.input.charAt(end + 1) === "="))
13341
}
13342
start += match[0].length;
13343
13344
// Skip semicolon, if any.
13345
skipWhiteSpace.lastIndex = start;
13346
start += skipWhiteSpace.exec(this.input)[0].length;
13347
if (this.input[start] === ";")
13348
{ start++; }
13349
}
13350
};
13351
13352
// Predicate that tests whether the next token is of the given
13353
// type, and if yes, consumes it as a side effect.
13354
13355
pp$9.eat = function(type) {
13356
if (this.type === type) {
13357
this.next();
13358
return true
13359
} else {
13360
return false
13361
}
13362
};
13363
13364
// Tests whether parsed token is a contextual keyword.
13365
13366
pp$9.isContextual = function(name) {
13367
return this.type === types$1.name && this.value === name && !this.containsEsc
13368
};
13369
13370
// Consumes contextual keyword if possible.
13371
13372
pp$9.eatContextual = function(name) {
13373
if (!this.isContextual(name)) { return false }
13374
this.next();
13375
return true
13376
};
13377
13378
// Asserts that following token is given contextual keyword.
13379
13380
pp$9.expectContextual = function(name) {
13381
if (!this.eatContextual(name)) { this.unexpected(); }
13382
};
13383
13384
// Test whether a semicolon can be inserted at the current position.
13385
13386
pp$9.canInsertSemicolon = function() {
13387
return this.type === types$1.eof ||
13388
this.type === types$1.braceR ||
13389
lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
13390
};
13391
13392
pp$9.insertSemicolon = function() {
13393
if (this.canInsertSemicolon()) {
13394
if (this.options.onInsertedSemicolon)
13395
{ this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
13396
return true
13397
}
13398
};
13399
13400
// Consume a semicolon, or, failing that, see if we are allowed to
13401
// pretend that there is a semicolon at this position.
13402
13403
pp$9.semicolon = function() {
13404
if (!this.eat(types$1.semi) && !this.insertSemicolon()) { this.unexpected(); }
13405
};
13406
13407
pp$9.afterTrailingComma = function(tokType, notNext) {
13408
if (this.type === tokType) {
13409
if (this.options.onTrailingComma)
13410
{ this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
13411
if (!notNext)
13412
{ this.next(); }
13413
return true
13414
}
13415
};
13416
13417
// Expect a token of a given type. If found, consume it, otherwise,
13418
// raise an unexpected token error.
13419
13420
pp$9.expect = function(type) {
13421
this.eat(type) || this.unexpected();
13422
};
13423
13424
// Raise an unexpected token error.
13425
13426
pp$9.unexpected = function(pos) {
13427
this.raise(pos != null ? pos : this.start, "Unexpected token");
13428
};
13429
13430
var DestructuringErrors = function DestructuringErrors() {
13431
this.shorthandAssign =
13432
this.trailingComma =
13433
this.parenthesizedAssign =
13434
this.parenthesizedBind =
13435
this.doubleProto =
13436
-1;
13437
};
13438
13439
pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {
13440
if (!refDestructuringErrors) { return }
13441
if (refDestructuringErrors.trailingComma > -1)
13442
{ this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
13443
var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
13444
if (parens > -1) { this.raiseRecoverable(parens, isAssign ? "Assigning to rvalue" : "Parenthesized pattern"); }
13445
};
13446
13447
pp$9.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
13448
if (!refDestructuringErrors) { return false }
13449
var shorthandAssign = refDestructuringErrors.shorthandAssign;
13450
var doubleProto = refDestructuringErrors.doubleProto;
13451
if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
13452
if (shorthandAssign >= 0)
13453
{ this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
13454
if (doubleProto >= 0)
13455
{ this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
13456
};
13457
13458
pp$9.checkYieldAwaitInDefaultParams = function() {
13459
if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
13460
{ this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
13461
if (this.awaitPos)
13462
{ this.raise(this.awaitPos, "Await expression cannot be a default value"); }
13463
};
13464
13465
pp$9.isSimpleAssignTarget = function(expr) {
13466
if (expr.type === "ParenthesizedExpression")
13467
{ return this.isSimpleAssignTarget(expr.expression) }
13468
return expr.type === "Identifier" || expr.type === "MemberExpression"
13469
};
13470
13471
var pp$8 = Parser.prototype;
13472
13473
// ### Statement parsing
13474
13475
// Parse a program. Initializes the parser, reads any number of
13476
// statements, and wraps them in a Program node. Optionally takes a
13477
// `program` argument. If present, the statements will be appended
13478
// to its body instead of creating a new node.
13479
13480
pp$8.parseTopLevel = function(node) {
13481
var exports = Object.create(null);
13482
if (!node.body) { node.body = []; }
13483
while (this.type !== types$1.eof) {
13484
var stmt = this.parseStatement(null, true, exports);
13485
node.body.push(stmt);
13486
}
13487
if (this.inModule)
13488
{ for (var i = 0, list = Object.keys(this.undefinedExports); i < list.length; i += 1)
13489
{
13490
var name = list[i];
13491
13492
this.raiseRecoverable(this.undefinedExports[name].start, ("Export '" + name + "' is not defined"));
13493
} }
13494
this.adaptDirectivePrologue(node.body);
13495
this.next();
13496
node.sourceType = this.options.sourceType;
13497
return this.finishNode(node, "Program")
13498
};
13499
13500
var loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"};
13501
13502
pp$8.isLet = function(context) {
13503
if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
13504
skipWhiteSpace.lastIndex = this.pos;
13505
var skip = skipWhiteSpace.exec(this.input);
13506
var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
13507
// For ambiguous cases, determine if a LexicalDeclaration (or only a
13508
// Statement) is allowed here. If context is not empty then only a Statement
13509
// is allowed. However, `let [` is an explicit negative lookahead for
13510
// ExpressionStatement, so special-case it first.
13511
if (nextCh === 91 || nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true } // '[', '/', astral
13512
if (context) { return false }
13513
13514
if (nextCh === 123) { return true } // '{'
13515
if (isIdentifierStart(nextCh, true)) {
13516
var pos = next + 1;
13517
while (isIdentifierChar(nextCh = this.input.charCodeAt(pos), true)) { ++pos; }
13518
if (nextCh === 92 || nextCh > 0xd7ff && nextCh < 0xdc00) { return true }
13519
var ident = this.input.slice(next, pos);
13520
if (!keywordRelationalOperator.test(ident)) { return true }
13521
}
13522
return false
13523
};
13524
13525
// check 'async [no LineTerminator here] function'
13526
// - 'async /*foo*/ function' is OK.
13527
// - 'async /*\n*/ function' is invalid.
13528
pp$8.isAsyncFunction = function() {
13529
if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
13530
{ return false }
13531
13532
skipWhiteSpace.lastIndex = this.pos;
13533
var skip = skipWhiteSpace.exec(this.input);
13534
var next = this.pos + skip[0].length, after;
13535
return !lineBreak.test(this.input.slice(this.pos, next)) &&
13536
this.input.slice(next, next + 8) === "function" &&
13537
(next + 8 === this.input.length ||
13538
!(isIdentifierChar(after = this.input.charCodeAt(next + 8)) || after > 0xd7ff && after < 0xdc00))
13539
};
13540
13541
// Parse a single statement.
13542
//
13543
// If expecting a statement and finding a slash operator, parse a
13544
// regular expression literal. This is to handle cases like
13545
// `if (foo) /blah/.exec(foo)`, where looking at the previous token
13546
// does not help.
13547
13548
pp$8.parseStatement = function(context, topLevel, exports) {
13549
var starttype = this.type, node = this.startNode(), kind;
13550
13551
if (this.isLet(context)) {
13552
starttype = types$1._var;
13553
kind = "let";
13554
}
13555
13556
// Most types of statements are recognized by the keyword they
13557
// start with. Many are trivial to parse, some require a bit of
13558
// complexity.
13559
13560
switch (starttype) {
13561
case types$1._break: case types$1._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
13562
case types$1._debugger: return this.parseDebuggerStatement(node)
13563
case types$1._do: return this.parseDoStatement(node)
13564
case types$1._for: return this.parseForStatement(node)
13565
case types$1._function:
13566
// Function as sole body of either an if statement or a labeled statement
13567
// works, but not when it is part of a labeled statement that is the sole
13568
// body of an if statement.
13569
if ((context && (this.strict || context !== "if" && context !== "label")) && this.options.ecmaVersion >= 6) { this.unexpected(); }
13570
return this.parseFunctionStatement(node, false, !context)
13571
case types$1._class:
13572
if (context) { this.unexpected(); }
13573
return this.parseClass(node, true)
13574
case types$1._if: return this.parseIfStatement(node)
13575
case types$1._return: return this.parseReturnStatement(node)
13576
case types$1._switch: return this.parseSwitchStatement(node)
13577
case types$1._throw: return this.parseThrowStatement(node)
13578
case types$1._try: return this.parseTryStatement(node)
13579
case types$1._const: case types$1._var:
13580
kind = kind || this.value;
13581
if (context && kind !== "var") { this.unexpected(); }
13582
return this.parseVarStatement(node, kind)
13583
case types$1._while: return this.parseWhileStatement(node)
13584
case types$1._with: return this.parseWithStatement(node)
13585
case types$1.braceL: return this.parseBlock(true, node)
13586
case types$1.semi: return this.parseEmptyStatement(node)
13587
case types$1._export:
13588
case types$1._import:
13589
if (this.options.ecmaVersion > 10 && starttype === types$1._import) {
13590
skipWhiteSpace.lastIndex = this.pos;
13591
var skip = skipWhiteSpace.exec(this.input);
13592
var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
13593
if (nextCh === 40 || nextCh === 46) // '(' or '.'
13594
{ return this.parseExpressionStatement(node, this.parseExpression()) }
13595
}
13596
13597
if (!this.options.allowImportExportEverywhere) {
13598
if (!topLevel)
13599
{ this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
13600
if (!this.inModule)
13601
{ this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
13602
}
13603
return starttype === types$1._import ? this.parseImport(node) : this.parseExport(node, exports)
13604
13605
// If the statement does not start with a statement keyword or a
13606
// brace, it's an ExpressionStatement or LabeledStatement. We
13607
// simply start parsing an expression, and afterwards, if the
13608
// next token is a colon and the expression was a simple
13609
// Identifier node, we switch to interpreting it as a label.
13610
default:
13611
if (this.isAsyncFunction()) {
13612
if (context) { this.unexpected(); }
13613
this.next();
13614
return this.parseFunctionStatement(node, true, !context)
13615
}
13616
13617
var maybeName = this.value, expr = this.parseExpression();
13618
if (starttype === types$1.name && expr.type === "Identifier" && this.eat(types$1.colon))
13619
{ return this.parseLabeledStatement(node, maybeName, expr, context) }
13620
else { return this.parseExpressionStatement(node, expr) }
13621
}
13622
};
13623
13624
pp$8.parseBreakContinueStatement = function(node, keyword) {
13625
var isBreak = keyword === "break";
13626
this.next();
13627
if (this.eat(types$1.semi) || this.insertSemicolon()) { node.label = null; }
13628
else if (this.type !== types$1.name) { this.unexpected(); }
13629
else {
13630
node.label = this.parseIdent();
13631
this.semicolon();
13632
}
13633
13634
// Verify that there is an actual destination to break or
13635
// continue to.
13636
var i = 0;
13637
for (; i < this.labels.length; ++i) {
13638
var lab = this.labels[i];
13639
if (node.label == null || lab.name === node.label.name) {
13640
if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
13641
if (node.label && isBreak) { break }
13642
}
13643
}
13644
if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
13645
return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
13646
};
13647
13648
pp$8.parseDebuggerStatement = function(node) {
13649
this.next();
13650
this.semicolon();
13651
return this.finishNode(node, "DebuggerStatement")
13652
};
13653
13654
pp$8.parseDoStatement = function(node) {
13655
this.next();
13656
this.labels.push(loopLabel);
13657
node.body = this.parseStatement("do");
13658
this.labels.pop();
13659
this.expect(types$1._while);
13660
node.test = this.parseParenExpression();
13661
if (this.options.ecmaVersion >= 6)
13662
{ this.eat(types$1.semi); }
13663
else
13664
{ this.semicolon(); }
13665
return this.finishNode(node, "DoWhileStatement")
13666
};
13667
13668
// Disambiguating between a `for` and a `for`/`in` or `for`/`of`
13669
// loop is non-trivial. Basically, we have to parse the init `var`
13670
// statement or expression, disallowing the `in` operator (see
13671
// the second parameter to `parseExpression`), and then check
13672
// whether the next token is `in` or `of`. When there is no init
13673
// part (semicolon immediately after the opening parenthesis), it
13674
// is a regular `for` loop.
13675
13676
pp$8.parseForStatement = function(node) {
13677
this.next();
13678
var awaitAt = (this.options.ecmaVersion >= 9 && this.canAwait && this.eatContextual("await")) ? this.lastTokStart : -1;
13679
this.labels.push(loopLabel);
13680
this.enterScope(0);
13681
this.expect(types$1.parenL);
13682
if (this.type === types$1.semi) {
13683
if (awaitAt > -1) { this.unexpected(awaitAt); }
13684
return this.parseFor(node, null)
13685
}
13686
var isLet = this.isLet();
13687
if (this.type === types$1._var || this.type === types$1._const || isLet) {
13688
var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
13689
this.next();
13690
this.parseVar(init$1, true, kind);
13691
this.finishNode(init$1, "VariableDeclaration");
13692
if ((this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1) {
13693
if (this.options.ecmaVersion >= 9) {
13694
if (this.type === types$1._in) {
13695
if (awaitAt > -1) { this.unexpected(awaitAt); }
13696
} else { node.await = awaitAt > -1; }
13697
}
13698
return this.parseForIn(node, init$1)
13699
}
13700
if (awaitAt > -1) { this.unexpected(awaitAt); }
13701
return this.parseFor(node, init$1)
13702
}
13703
var startsWithLet = this.isContextual("let"), isForOf = false;
13704
var refDestructuringErrors = new DestructuringErrors;
13705
var init = this.parseExpression(awaitAt > -1 ? "await" : true, refDestructuringErrors);
13706
if (this.type === types$1._in || (isForOf = this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
13707
if (this.options.ecmaVersion >= 9) {
13708
if (this.type === types$1._in) {
13709
if (awaitAt > -1) { this.unexpected(awaitAt); }
13710
} else { node.await = awaitAt > -1; }
13711
}
13712
if (startsWithLet && isForOf) { this.raise(init.start, "The left-hand side of a for-of loop may not start with 'let'."); }
13713
this.toAssignable(init, false, refDestructuringErrors);
13714
this.checkLValPattern(init);
13715
return this.parseForIn(node, init)
13716
} else {
13717
this.checkExpressionErrors(refDestructuringErrors, true);
13718
}
13719
if (awaitAt > -1) { this.unexpected(awaitAt); }
13720
return this.parseFor(node, init)
13721
};
13722
13723
pp$8.parseFunctionStatement = function(node, isAsync, declarationPosition) {
13724
this.next();
13725
return this.parseFunction(node, FUNC_STATEMENT | (declarationPosition ? 0 : FUNC_HANGING_STATEMENT), false, isAsync)
13726
};
13727
13728
pp$8.parseIfStatement = function(node) {
13729
this.next();
13730
node.test = this.parseParenExpression();
13731
// allow function declarations in branches, but only in non-strict mode
13732
node.consequent = this.parseStatement("if");
13733
node.alternate = this.eat(types$1._else) ? this.parseStatement("if") : null;
13734
return this.finishNode(node, "IfStatement")
13735
};
13736
13737
pp$8.parseReturnStatement = function(node) {
13738
if (!this.inFunction && !this.options.allowReturnOutsideFunction)
13739
{ this.raise(this.start, "'return' outside of function"); }
13740
this.next();
13741
13742
// In `return` (and `break`/`continue`), the keywords with
13743
// optional arguments, we eagerly look for a semicolon or the
13744
// possibility to insert one.
13745
13746
if (this.eat(types$1.semi) || this.insertSemicolon()) { node.argument = null; }
13747
else { node.argument = this.parseExpression(); this.semicolon(); }
13748
return this.finishNode(node, "ReturnStatement")
13749
};
13750
13751
pp$8.parseSwitchStatement = function(node) {
13752
this.next();
13753
node.discriminant = this.parseParenExpression();
13754
node.cases = [];
13755
this.expect(types$1.braceL);
13756
this.labels.push(switchLabel);
13757
this.enterScope(0);
13758
13759
// Statements under must be grouped (by label) in SwitchCase
13760
// nodes. `cur` is used to keep the node that we are currently
13761
// adding statements to.
13762
13763
var cur;
13764
for (var sawDefault = false; this.type !== types$1.braceR;) {
13765
if (this.type === types$1._case || this.type === types$1._default) {
13766
var isCase = this.type === types$1._case;
13767
if (cur) { this.finishNode(cur, "SwitchCase"); }
13768
node.cases.push(cur = this.startNode());
13769
cur.consequent = [];
13770
this.next();
13771
if (isCase) {
13772
cur.test = this.parseExpression();
13773
} else {
13774
if (sawDefault) { this.raiseRecoverable(this.lastTokStart, "Multiple default clauses"); }
13775
sawDefault = true;
13776
cur.test = null;
13777
}
13778
this.expect(types$1.colon);
13779
} else {
13780
if (!cur) { this.unexpected(); }
13781
cur.consequent.push(this.parseStatement(null));
13782
}
13783
}
13784
this.exitScope();
13785
if (cur) { this.finishNode(cur, "SwitchCase"); }
13786
this.next(); // Closing brace
13787
this.labels.pop();
13788
return this.finishNode(node, "SwitchStatement")
13789
};
13790
13791
pp$8.parseThrowStatement = function(node) {
13792
this.next();
13793
if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
13794
{ this.raise(this.lastTokEnd, "Illegal newline after throw"); }
13795
node.argument = this.parseExpression();
13796
this.semicolon();
13797
return this.finishNode(node, "ThrowStatement")
13798
};
13799
13800
// Reused empty array added for node fields that are always empty.
13801
13802
var empty$1 = [];
13803
13804
pp$8.parseTryStatement = function(node) {
13805
this.next();
13806
node.block = this.parseBlock();
13807
node.handler = null;
13808
if (this.type === types$1._catch) {
13809
var clause = this.startNode();
13810
this.next();
13811
if (this.eat(types$1.parenL)) {
13812
clause.param = this.parseBindingAtom();
13813
var simple = clause.param.type === "Identifier";
13814
this.enterScope(simple ? SCOPE_SIMPLE_CATCH : 0);
13815
this.checkLValPattern(clause.param, simple ? BIND_SIMPLE_CATCH : BIND_LEXICAL);
13816
this.expect(types$1.parenR);
13817
} else {
13818
if (this.options.ecmaVersion < 10) { this.unexpected(); }
13819
clause.param = null;
13820
this.enterScope(0);
13821
}
13822
clause.body = this.parseBlock(false);
13823
this.exitScope();
13824
node.handler = this.finishNode(clause, "CatchClause");
13825
}
13826
node.finalizer = this.eat(types$1._finally) ? this.parseBlock() : null;
13827
if (!node.handler && !node.finalizer)
13828
{ this.raise(node.start, "Missing catch or finally clause"); }
13829
return this.finishNode(node, "TryStatement")
13830
};
13831
13832
pp$8.parseVarStatement = function(node, kind) {
13833
this.next();
13834
this.parseVar(node, false, kind);
13835
this.semicolon();
13836
return this.finishNode(node, "VariableDeclaration")
13837
};
13838
13839
pp$8.parseWhileStatement = function(node) {
13840
this.next();
13841
node.test = this.parseParenExpression();
13842
this.labels.push(loopLabel);
13843
node.body = this.parseStatement("while");
13844
this.labels.pop();
13845
return this.finishNode(node, "WhileStatement")
13846
};
13847
13848
pp$8.parseWithStatement = function(node) {
13849
if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
13850
this.next();
13851
node.object = this.parseParenExpression();
13852
node.body = this.parseStatement("with");
13853
return this.finishNode(node, "WithStatement")
13854
};
13855
13856
pp$8.parseEmptyStatement = function(node) {
13857
this.next();
13858
return this.finishNode(node, "EmptyStatement")
13859
};
13860
13861
pp$8.parseLabeledStatement = function(node, maybeName, expr, context) {
13862
for (var i$1 = 0, list = this.labels; i$1 < list.length; i$1 += 1)
13863
{
13864
var label = list[i$1];
13865
13866
if (label.name === maybeName)
13867
{ this.raise(expr.start, "Label '" + maybeName + "' is already declared");
13868
} }
13869
var kind = this.type.isLoop ? "loop" : this.type === types$1._switch ? "switch" : null;
13870
for (var i = this.labels.length - 1; i >= 0; i--) {
13871
var label$1 = this.labels[i];
13872
if (label$1.statementStart === node.start) {
13873
// Update information about previous labels on this node
13874
label$1.statementStart = this.start;
13875
label$1.kind = kind;
13876
} else { break }
13877
}
13878
this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
13879
node.body = this.parseStatement(context ? context.indexOf("label") === -1 ? context + "label" : context : "label");
13880
this.labels.pop();
13881
node.label = expr;
13882
return this.finishNode(node, "LabeledStatement")
13883
};
13884
13885
pp$8.parseExpressionStatement = function(node, expr) {
13886
node.expression = expr;
13887
this.semicolon();
13888
return this.finishNode(node, "ExpressionStatement")
13889
};
13890
13891
// Parse a semicolon-enclosed block of statements, handling `"use
13892
// strict"` declarations when `allowStrict` is true (used for
13893
// function bodies).
13894
13895
pp$8.parseBlock = function(createNewLexicalScope, node, exitStrict) {
13896
if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
13897
if ( node === void 0 ) node = this.startNode();
13898
13899
node.body = [];
13900
this.expect(types$1.braceL);
13901
if (createNewLexicalScope) { this.enterScope(0); }
13902
while (this.type !== types$1.braceR) {
13903
var stmt = this.parseStatement(null);
13904
node.body.push(stmt);
13905
}
13906
if (exitStrict) { this.strict = false; }
13907
this.next();
13908
if (createNewLexicalScope) { this.exitScope(); }
13909
return this.finishNode(node, "BlockStatement")
13910
};
13911
13912
// Parse a regular `for` loop. The disambiguation code in
13913
// `parseStatement` will already have parsed the init statement or
13914
// expression.
13915
13916
pp$8.parseFor = function(node, init) {
13917
node.init = init;
13918
this.expect(types$1.semi);
13919
node.test = this.type === types$1.semi ? null : this.parseExpression();
13920
this.expect(types$1.semi);
13921
node.update = this.type === types$1.parenR ? null : this.parseExpression();
13922
this.expect(types$1.parenR);
13923
node.body = this.parseStatement("for");
13924
this.exitScope();
13925
this.labels.pop();
13926
return this.finishNode(node, "ForStatement")
13927
};
13928
13929
// Parse a `for`/`in` and `for`/`of` loop, which are almost
13930
// same from parser's perspective.
13931
13932
pp$8.parseForIn = function(node, init) {
13933
var isForIn = this.type === types$1._in;
13934
this.next();
13935
13936
if (
13937
init.type === "VariableDeclaration" &&
13938
init.declarations[0].init != null &&
13939
(
13940
!isForIn ||
13941
this.options.ecmaVersion < 8 ||
13942
this.strict ||
13943
init.kind !== "var" ||
13944
init.declarations[0].id.type !== "Identifier"
13945
)
13946
) {
13947
this.raise(
13948
init.start,
13949
((isForIn ? "for-in" : "for-of") + " loop variable declaration may not have an initializer")
13950
);
13951
}
13952
node.left = init;
13953
node.right = isForIn ? this.parseExpression() : this.parseMaybeAssign();
13954
this.expect(types$1.parenR);
13955
node.body = this.parseStatement("for");
13956
this.exitScope();
13957
this.labels.pop();
13958
return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement")
13959
};
13960
13961
// Parse a list of variable declarations.
13962
13963
pp$8.parseVar = function(node, isFor, kind) {
13964
node.declarations = [];
13965
node.kind = kind;
13966
for (;;) {
13967
var decl = this.startNode();
13968
this.parseVarId(decl, kind);
13969
if (this.eat(types$1.eq)) {
13970
decl.init = this.parseMaybeAssign(isFor);
13971
} else if (kind === "const" && !(this.type === types$1._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
13972
this.unexpected();
13973
} else if (decl.id.type !== "Identifier" && !(isFor && (this.type === types$1._in || this.isContextual("of")))) {
13974
this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
13975
} else {
13976
decl.init = null;
13977
}
13978
node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
13979
if (!this.eat(types$1.comma)) { break }
13980
}
13981
return node
13982
};
13983
13984
pp$8.parseVarId = function(decl, kind) {
13985
decl.id = this.parseBindingAtom();
13986
this.checkLValPattern(decl.id, kind === "var" ? BIND_VAR : BIND_LEXICAL, false);
13987
};
13988
13989
var FUNC_STATEMENT = 1, FUNC_HANGING_STATEMENT = 2, FUNC_NULLABLE_ID = 4;
13990
13991
// Parse a function declaration or literal (depending on the
13992
// `statement & FUNC_STATEMENT`).
13993
13994
// Remove `allowExpressionBody` for 7.0.0, as it is only called with false
13995
pp$8.parseFunction = function(node, statement, allowExpressionBody, isAsync, forInit) {
13996
this.initFunction(node);
13997
if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync) {
13998
if (this.type === types$1.star && (statement & FUNC_HANGING_STATEMENT))
13999
{ this.unexpected(); }
14000
node.generator = this.eat(types$1.star);
14001
}
14002
if (this.options.ecmaVersion >= 8)
14003
{ node.async = !!isAsync; }
14004
14005
if (statement & FUNC_STATEMENT) {
14006
node.id = (statement & FUNC_NULLABLE_ID) && this.type !== types$1.name ? null : this.parseIdent();
14007
if (node.id && !(statement & FUNC_HANGING_STATEMENT))
14008
// If it is a regular function declaration in sloppy mode, then it is
14009
// subject to Annex B semantics (BIND_FUNCTION). Otherwise, the binding
14010
// mode depends on properties of the current scope (see
14011
// treatFunctionsAsVar).
14012
{ this.checkLValSimple(node.id, (this.strict || node.generator || node.async) ? this.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION); }
14013
}
14014
14015
var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
14016
this.yieldPos = 0;
14017
this.awaitPos = 0;
14018
this.awaitIdentPos = 0;
14019
this.enterScope(functionFlags(node.async, node.generator));
14020
14021
if (!(statement & FUNC_STATEMENT))
14022
{ node.id = this.type === types$1.name ? this.parseIdent() : null; }
14023
14024
this.parseFunctionParams(node);
14025
this.parseFunctionBody(node, allowExpressionBody, false, forInit);
14026
14027
this.yieldPos = oldYieldPos;
14028
this.awaitPos = oldAwaitPos;
14029
this.awaitIdentPos = oldAwaitIdentPos;
14030
return this.finishNode(node, (statement & FUNC_STATEMENT) ? "FunctionDeclaration" : "FunctionExpression")
14031
};
14032
14033
pp$8.parseFunctionParams = function(node) {
14034
this.expect(types$1.parenL);
14035
node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
14036
this.checkYieldAwaitInDefaultParams();
14037
};
14038
14039
// Parse a class declaration or literal (depending on the
14040
// `isStatement` parameter).
14041
14042
pp$8.parseClass = function(node, isStatement) {
14043
this.next();
14044
14045
// ecma-262 14.6 Class Definitions
14046
// A class definition is always strict mode code.
14047
var oldStrict = this.strict;
14048
this.strict = true;
14049
14050
this.parseClassId(node, isStatement);
14051
this.parseClassSuper(node);
14052
var privateNameMap = this.enterClassBody();
14053
var classBody = this.startNode();
14054
var hadConstructor = false;
14055
classBody.body = [];
14056
this.expect(types$1.braceL);
14057
while (this.type !== types$1.braceR) {
14058
var element = this.parseClassElement(node.superClass !== null);
14059
if (element) {
14060
classBody.body.push(element);
14061
if (element.type === "MethodDefinition" && element.kind === "constructor") {
14062
if (hadConstructor) { this.raise(element.start, "Duplicate constructor in the same class"); }
14063
hadConstructor = true;
14064
} else if (element.key && element.key.type === "PrivateIdentifier" && isPrivateNameConflicted(privateNameMap, element)) {
14065
this.raiseRecoverable(element.key.start, ("Identifier '#" + (element.key.name) + "' has already been declared"));
14066
}
14067
}
14068
}
14069
this.strict = oldStrict;
14070
this.next();
14071
node.body = this.finishNode(classBody, "ClassBody");
14072
this.exitClassBody();
14073
return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
14074
};
14075
14076
pp$8.parseClassElement = function(constructorAllowsSuper) {
14077
if (this.eat(types$1.semi)) { return null }
14078
14079
var ecmaVersion = this.options.ecmaVersion;
14080
var node = this.startNode();
14081
var keyName = "";
14082
var isGenerator = false;
14083
var isAsync = false;
14084
var kind = "method";
14085
var isStatic = false;
14086
14087
if (this.eatContextual("static")) {
14088
// Parse static init block
14089
if (ecmaVersion >= 13 && this.eat(types$1.braceL)) {
14090
this.parseClassStaticBlock(node);
14091
return node
14092
}
14093
if (this.isClassElementNameStart() || this.type === types$1.star) {
14094
isStatic = true;
14095
} else {
14096
keyName = "static";
14097
}
14098
}
14099
node.static = isStatic;
14100
if (!keyName && ecmaVersion >= 8 && this.eatContextual("async")) {
14101
if ((this.isClassElementNameStart() || this.type === types$1.star) && !this.canInsertSemicolon()) {
14102
isAsync = true;
14103
} else {
14104
keyName = "async";
14105
}
14106
}
14107
if (!keyName && (ecmaVersion >= 9 || !isAsync) && this.eat(types$1.star)) {
14108
isGenerator = true;
14109
}
14110
if (!keyName && !isAsync && !isGenerator) {
14111
var lastValue = this.value;
14112
if (this.eatContextual("get") || this.eatContextual("set")) {
14113
if (this.isClassElementNameStart()) {
14114
kind = lastValue;
14115
} else {
14116
keyName = lastValue;
14117
}
14118
}
14119
}
14120
14121
// Parse element name
14122
if (keyName) {
14123
// 'async', 'get', 'set', or 'static' were not a keyword contextually.
14124
// The last token is any of those. Make it the element name.
14125
node.computed = false;
14126
node.key = this.startNodeAt(this.lastTokStart, this.lastTokStartLoc);
14127
node.key.name = keyName;
14128
this.finishNode(node.key, "Identifier");
14129
} else {
14130
this.parseClassElementName(node);
14131
}
14132
14133
// Parse element value
14134
if (ecmaVersion < 13 || this.type === types$1.parenL || kind !== "method" || isGenerator || isAsync) {
14135
var isConstructor = !node.static && checkKeyName(node, "constructor");
14136
var allowsDirectSuper = isConstructor && constructorAllowsSuper;
14137
// Couldn't move this check into the 'parseClassMethod' method for backward compatibility.
14138
if (isConstructor && kind !== "method") { this.raise(node.key.start, "Constructor can't have get/set modifier"); }
14139
node.kind = isConstructor ? "constructor" : kind;
14140
this.parseClassMethod(node, isGenerator, isAsync, allowsDirectSuper);
14141
} else {
14142
this.parseClassField(node);
14143
}
14144
14145
return node
14146
};
14147
14148
pp$8.isClassElementNameStart = function() {
14149
return (
14150
this.type === types$1.name ||
14151
this.type === types$1.privateId ||
14152
this.type === types$1.num ||
14153
this.type === types$1.string ||
14154
this.type === types$1.bracketL ||
14155
this.type.keyword
14156
)
14157
};
14158
14159
pp$8.parseClassElementName = function(element) {
14160
if (this.type === types$1.privateId) {
14161
if (this.value === "constructor") {
14162
this.raise(this.start, "Classes can't have an element named '#constructor'");
14163
}
14164
element.computed = false;
14165
element.key = this.parsePrivateIdent();
14166
} else {
14167
this.parsePropertyName(element);
14168
}
14169
};
14170
14171
pp$8.parseClassMethod = function(method, isGenerator, isAsync, allowsDirectSuper) {
14172
// Check key and flags
14173
var key = method.key;
14174
if (method.kind === "constructor") {
14175
if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
14176
if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
14177
} else if (method.static && checkKeyName(method, "prototype")) {
14178
this.raise(key.start, "Classes may not have a static property named prototype");
14179
}
14180
14181
// Parse value
14182
var value = method.value = this.parseMethod(isGenerator, isAsync, allowsDirectSuper);
14183
14184
// Check value
14185
if (method.kind === "get" && value.params.length !== 0)
14186
{ this.raiseRecoverable(value.start, "getter should have no params"); }
14187
if (method.kind === "set" && value.params.length !== 1)
14188
{ this.raiseRecoverable(value.start, "setter should have exactly one param"); }
14189
if (method.kind === "set" && value.params[0].type === "RestElement")
14190
{ this.raiseRecoverable(value.params[0].start, "Setter cannot use rest params"); }
14191
14192
return this.finishNode(method, "MethodDefinition")
14193
};
14194
14195
pp$8.parseClassField = function(field) {
14196
if (checkKeyName(field, "constructor")) {
14197
this.raise(field.key.start, "Classes can't have a field named 'constructor'");
14198
} else if (field.static && checkKeyName(field, "prototype")) {
14199
this.raise(field.key.start, "Classes can't have a static field named 'prototype'");
14200
}
14201
14202
if (this.eat(types$1.eq)) {
14203
// To raise SyntaxError if 'arguments' exists in the initializer.
14204
var scope = this.currentThisScope();
14205
var inClassFieldInit = scope.inClassFieldInit;
14206
scope.inClassFieldInit = true;
14207
field.value = this.parseMaybeAssign();
14208
scope.inClassFieldInit = inClassFieldInit;
14209
} else {
14210
field.value = null;
14211
}
14212
this.semicolon();
14213
14214
return this.finishNode(field, "PropertyDefinition")
14215
};
14216
14217
pp$8.parseClassStaticBlock = function(node) {
14218
node.body = [];
14219
14220
var oldLabels = this.labels;
14221
this.labels = [];
14222
this.enterScope(SCOPE_CLASS_STATIC_BLOCK | SCOPE_SUPER);
14223
while (this.type !== types$1.braceR) {
14224
var stmt = this.parseStatement(null);
14225
node.body.push(stmt);
14226
}
14227
this.next();
14228
this.exitScope();
14229
this.labels = oldLabels;
14230
14231
return this.finishNode(node, "StaticBlock")
14232
};
14233
14234
pp$8.parseClassId = function(node, isStatement) {
14235
if (this.type === types$1.name) {
14236
node.id = this.parseIdent();
14237
if (isStatement)
14238
{ this.checkLValSimple(node.id, BIND_LEXICAL, false); }
14239
} else {
14240
if (isStatement === true)
14241
{ this.unexpected(); }
14242
node.id = null;
14243
}
14244
};
14245
14246
pp$8.parseClassSuper = function(node) {
14247
node.superClass = this.eat(types$1._extends) ? this.parseExprSubscripts(false) : null;
14248
};
14249
14250
pp$8.enterClassBody = function() {
14251
var element = {declared: Object.create(null), used: []};
14252
this.privateNameStack.push(element);
14253
return element.declared
14254
};
14255
14256
pp$8.exitClassBody = function() {
14257
var ref = this.privateNameStack.pop();
14258
var declared = ref.declared;
14259
var used = ref.used;
14260
var len = this.privateNameStack.length;
14261
var parent = len === 0 ? null : this.privateNameStack[len - 1];
14262
for (var i = 0; i < used.length; ++i) {
14263
var id = used[i];
14264
if (!hasOwn(declared, id.name)) {
14265
if (parent) {
14266
parent.used.push(id);
14267
} else {
14268
this.raiseRecoverable(id.start, ("Private field '#" + (id.name) + "' must be declared in an enclosing class"));
14269
}
14270
}
14271
}
14272
};
14273
14274
function isPrivateNameConflicted(privateNameMap, element) {
14275
var name = element.key.name;
14276
var curr = privateNameMap[name];
14277
14278
var next = "true";
14279
if (element.type === "MethodDefinition" && (element.kind === "get" || element.kind === "set")) {
14280
next = (element.static ? "s" : "i") + element.kind;
14281
}
14282
14283
// `class { get #a(){}; static set #a(_){} }` is also conflict.
14284
if (
14285
curr === "iget" && next === "iset" ||
14286
curr === "iset" && next === "iget" ||
14287
curr === "sget" && next === "sset" ||
14288
curr === "sset" && next === "sget"
14289
) {
14290
privateNameMap[name] = "true";
14291
return false
14292
} else if (!curr) {
14293
privateNameMap[name] = next;
14294
return false
14295
} else {
14296
return true
14297
}
14298
}
14299
14300
function checkKeyName(node, name) {
14301
var computed = node.computed;
14302
var key = node.key;
14303
return !computed && (
14304
key.type === "Identifier" && key.name === name ||
14305
key.type === "Literal" && key.value === name
14306
)
14307
}
14308
14309
// Parses module export declaration.
14310
14311
pp$8.parseExport = function(node, exports) {
14312
this.next();
14313
// export * from '...'
14314
if (this.eat(types$1.star)) {
14315
if (this.options.ecmaVersion >= 11) {
14316
if (this.eatContextual("as")) {
14317
node.exported = this.parseModuleExportName();
14318
this.checkExport(exports, node.exported, this.lastTokStart);
14319
} else {
14320
node.exported = null;
14321
}
14322
}
14323
this.expectContextual("from");
14324
if (this.type !== types$1.string) { this.unexpected(); }
14325
node.source = this.parseExprAtom();
14326
this.semicolon();
14327
return this.finishNode(node, "ExportAllDeclaration")
14328
}
14329
if (this.eat(types$1._default)) { // export default ...
14330
this.checkExport(exports, "default", this.lastTokStart);
14331
var isAsync;
14332
if (this.type === types$1._function || (isAsync = this.isAsyncFunction())) {
14333
var fNode = this.startNode();
14334
this.next();
14335
if (isAsync) { this.next(); }
14336
node.declaration = this.parseFunction(fNode, FUNC_STATEMENT | FUNC_NULLABLE_ID, false, isAsync);
14337
} else if (this.type === types$1._class) {
14338
var cNode = this.startNode();
14339
node.declaration = this.parseClass(cNode, "nullableID");
14340
} else {
14341
node.declaration = this.parseMaybeAssign();
14342
this.semicolon();
14343
}
14344
return this.finishNode(node, "ExportDefaultDeclaration")
14345
}
14346
// export var|const|let|function|class ...
14347
if (this.shouldParseExportStatement()) {
14348
node.declaration = this.parseStatement(null);
14349
if (node.declaration.type === "VariableDeclaration")
14350
{ this.checkVariableExport(exports, node.declaration.declarations); }
14351
else
14352
{ this.checkExport(exports, node.declaration.id, node.declaration.id.start); }
14353
node.specifiers = [];
14354
node.source = null;
14355
} else { // export { x, y as z } [from '...']
14356
node.declaration = null;
14357
node.specifiers = this.parseExportSpecifiers(exports);
14358
if (this.eatContextual("from")) {
14359
if (this.type !== types$1.string) { this.unexpected(); }
14360
node.source = this.parseExprAtom();
14361
} else {
14362
for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
14363
// check for keywords used as local names
14364
var spec = list[i];
14365
14366
this.checkUnreserved(spec.local);
14367
// check if export is defined
14368
this.checkLocalExport(spec.local);
14369
14370
if (spec.local.type === "Literal") {
14371
this.raise(spec.local.start, "A string literal cannot be used as an exported binding without `from`.");
14372
}
14373
}
14374
14375
node.source = null;
14376
}
14377
this.semicolon();
14378
}
14379
return this.finishNode(node, "ExportNamedDeclaration")
14380
};
14381
14382
pp$8.checkExport = function(exports, name, pos) {
14383
if (!exports) { return }
14384
if (typeof name !== "string")
14385
{ name = name.type === "Identifier" ? name.name : name.value; }
14386
if (hasOwn(exports, name))
14387
{ this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
14388
exports[name] = true;
14389
};
14390
14391
pp$8.checkPatternExport = function(exports, pat) {
14392
var type = pat.type;
14393
if (type === "Identifier")
14394
{ this.checkExport(exports, pat, pat.start); }
14395
else if (type === "ObjectPattern")
14396
{ for (var i = 0, list = pat.properties; i < list.length; i += 1)
14397
{
14398
var prop = list[i];
14399
14400
this.checkPatternExport(exports, prop);
14401
} }
14402
else if (type === "ArrayPattern")
14403
{ for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
14404
var elt = list$1[i$1];
14405
14406
if (elt) { this.checkPatternExport(exports, elt); }
14407
} }
14408
else if (type === "Property")
14409
{ this.checkPatternExport(exports, pat.value); }
14410
else if (type === "AssignmentPattern")
14411
{ this.checkPatternExport(exports, pat.left); }
14412
else if (type === "RestElement")
14413
{ this.checkPatternExport(exports, pat.argument); }
14414
else if (type === "ParenthesizedExpression")
14415
{ this.checkPatternExport(exports, pat.expression); }
14416
};
14417
14418
pp$8.checkVariableExport = function(exports, decls) {
14419
if (!exports) { return }
14420
for (var i = 0, list = decls; i < list.length; i += 1)
14421
{
14422
var decl = list[i];
14423
14424
this.checkPatternExport(exports, decl.id);
14425
}
14426
};
14427
14428
pp$8.shouldParseExportStatement = function() {
14429
return this.type.keyword === "var" ||
14430
this.type.keyword === "const" ||
14431
this.type.keyword === "class" ||
14432
this.type.keyword === "function" ||
14433
this.isLet() ||
14434
this.isAsyncFunction()
14435
};
14436
14437
// Parses a comma-separated list of module exports.
14438
14439
pp$8.parseExportSpecifiers = function(exports) {
14440
var nodes = [], first = true;
14441
// export { x, y as z } [from '...']
14442
this.expect(types$1.braceL);
14443
while (!this.eat(types$1.braceR)) {
14444
if (!first) {
14445
this.expect(types$1.comma);
14446
if (this.afterTrailingComma(types$1.braceR)) { break }
14447
} else { first = false; }
14448
14449
var node = this.startNode();
14450
node.local = this.parseModuleExportName();
14451
node.exported = this.eatContextual("as") ? this.parseModuleExportName() : node.local;
14452
this.checkExport(
14453
exports,
14454
node.exported,
14455
node.exported.start
14456
);
14457
nodes.push(this.finishNode(node, "ExportSpecifier"));
14458
}
14459
return nodes
14460
};
14461
14462
// Parses import declaration.
14463
14464
pp$8.parseImport = function(node) {
14465
this.next();
14466
// import '...'
14467
if (this.type === types$1.string) {
14468
node.specifiers = empty$1;
14469
node.source = this.parseExprAtom();
14470
} else {
14471
node.specifiers = this.parseImportSpecifiers();
14472
this.expectContextual("from");
14473
node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();
14474
}
14475
this.semicolon();
14476
return this.finishNode(node, "ImportDeclaration")
14477
};
14478
14479
// Parses a comma-separated list of module imports.
14480
14481
pp$8.parseImportSpecifiers = function() {
14482
var nodes = [], first = true;
14483
if (this.type === types$1.name) {
14484
// import defaultObj, { x, y as z } from '...'
14485
var node = this.startNode();
14486
node.local = this.parseIdent();
14487
this.checkLValSimple(node.local, BIND_LEXICAL);
14488
nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
14489
if (!this.eat(types$1.comma)) { return nodes }
14490
}
14491
if (this.type === types$1.star) {
14492
var node$1 = this.startNode();
14493
this.next();
14494
this.expectContextual("as");
14495
node$1.local = this.parseIdent();
14496
this.checkLValSimple(node$1.local, BIND_LEXICAL);
14497
nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
14498
return nodes
14499
}
14500
this.expect(types$1.braceL);
14501
while (!this.eat(types$1.braceR)) {
14502
if (!first) {
14503
this.expect(types$1.comma);
14504
if (this.afterTrailingComma(types$1.braceR)) { break }
14505
} else { first = false; }
14506
14507
var node$2 = this.startNode();
14508
node$2.imported = this.parseModuleExportName();
14509
if (this.eatContextual("as")) {
14510
node$2.local = this.parseIdent();
14511
} else {
14512
this.checkUnreserved(node$2.imported);
14513
node$2.local = node$2.imported;
14514
}
14515
this.checkLValSimple(node$2.local, BIND_LEXICAL);
14516
nodes.push(this.finishNode(node$2, "ImportSpecifier"));
14517
}
14518
return nodes
14519
};
14520
14521
pp$8.parseModuleExportName = function() {
14522
if (this.options.ecmaVersion >= 13 && this.type === types$1.string) {
14523
var stringLiteral = this.parseLiteral(this.value);
14524
if (loneSurrogate.test(stringLiteral.value)) {
14525
this.raise(stringLiteral.start, "An export name cannot include a lone surrogate.");
14526
}
14527
return stringLiteral
14528
}
14529
return this.parseIdent(true)
14530
};
14531
14532
// Set `ExpressionStatement#directive` property for directive prologues.
14533
pp$8.adaptDirectivePrologue = function(statements) {
14534
for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
14535
statements[i].directive = statements[i].expression.raw.slice(1, -1);
14536
}
14537
};
14538
pp$8.isDirectiveCandidate = function(statement) {
14539
return (
14540
this.options.ecmaVersion >= 5 &&
14541
statement.type === "ExpressionStatement" &&
14542
statement.expression.type === "Literal" &&
14543
typeof statement.expression.value === "string" &&
14544
// Reject parenthesized strings.
14545
(this.input[statement.start] === "\"" || this.input[statement.start] === "'")
14546
)
14547
};
14548
14549
var pp$7 = Parser.prototype;
14550
14551
// Convert existing expression atom to assignable pattern
14552
// if possible.
14553
14554
pp$7.toAssignable = function(node, isBinding, refDestructuringErrors) {
14555
if (this.options.ecmaVersion >= 6 && node) {
14556
switch (node.type) {
14557
case "Identifier":
14558
if (this.inAsync && node.name === "await")
14559
{ this.raise(node.start, "Cannot use 'await' as identifier inside an async function"); }
14560
break
14561
14562
case "ObjectPattern":
14563
case "ArrayPattern":
14564
case "AssignmentPattern":
14565
case "RestElement":
14566
break
14567
14568
case "ObjectExpression":
14569
node.type = "ObjectPattern";
14570
if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
14571
for (var i = 0, list = node.properties; i < list.length; i += 1) {
14572
var prop = list[i];
14573
14574
this.toAssignable(prop, isBinding);
14575
// Early error:
14576
// AssignmentRestProperty[Yield, Await] :
14577
// `...` DestructuringAssignmentTarget[Yield, Await]
14578
//
14579
// It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
14580
if (
14581
prop.type === "RestElement" &&
14582
(prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
14583
) {
14584
this.raise(prop.argument.start, "Unexpected token");
14585
}
14586
}
14587
break
14588
14589
case "Property":
14590
// AssignmentProperty has type === "Property"
14591
if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
14592
this.toAssignable(node.value, isBinding);
14593
break
14594
14595
case "ArrayExpression":
14596
node.type = "ArrayPattern";
14597
if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
14598
this.toAssignableList(node.elements, isBinding);
14599
break
14600
14601
case "SpreadElement":
14602
node.type = "RestElement";
14603
this.toAssignable(node.argument, isBinding);
14604
if (node.argument.type === "AssignmentPattern")
14605
{ this.raise(node.argument.start, "Rest elements cannot have a default value"); }
14606
break
14607
14608
case "AssignmentExpression":
14609
if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
14610
node.type = "AssignmentPattern";
14611
delete node.operator;
14612
this.toAssignable(node.left, isBinding);
14613
break
14614
14615
case "ParenthesizedExpression":
14616
this.toAssignable(node.expression, isBinding, refDestructuringErrors);
14617
break
14618
14619
case "ChainExpression":
14620
this.raiseRecoverable(node.start, "Optional chaining cannot appear in left-hand side");
14621
break
14622
14623
case "MemberExpression":
14624
if (!isBinding) { break }
14625
14626
default:
14627
this.raise(node.start, "Assigning to rvalue");
14628
}
14629
} else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
14630
return node
14631
};
14632
14633
// Convert list of expression atoms to binding list.
14634
14635
pp$7.toAssignableList = function(exprList, isBinding) {
14636
var end = exprList.length;
14637
for (var i = 0; i < end; i++) {
14638
var elt = exprList[i];
14639
if (elt) { this.toAssignable(elt, isBinding); }
14640
}
14641
if (end) {
14642
var last = exprList[end - 1];
14643
if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
14644
{ this.unexpected(last.argument.start); }
14645
}
14646
return exprList
14647
};
14648
14649
// Parses spread element.
14650
14651
pp$7.parseSpread = function(refDestructuringErrors) {
14652
var node = this.startNode();
14653
this.next();
14654
node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
14655
return this.finishNode(node, "SpreadElement")
14656
};
14657
14658
pp$7.parseRestBinding = function() {
14659
var node = this.startNode();
14660
this.next();
14661
14662
// RestElement inside of a function parameter must be an identifier
14663
if (this.options.ecmaVersion === 6 && this.type !== types$1.name)
14664
{ this.unexpected(); }
14665
14666
node.argument = this.parseBindingAtom();
14667
14668
return this.finishNode(node, "RestElement")
14669
};
14670
14671
// Parses lvalue (assignable) atom.
14672
14673
pp$7.parseBindingAtom = function() {
14674
if (this.options.ecmaVersion >= 6) {
14675
switch (this.type) {
14676
case types$1.bracketL:
14677
var node = this.startNode();
14678
this.next();
14679
node.elements = this.parseBindingList(types$1.bracketR, true, true);
14680
return this.finishNode(node, "ArrayPattern")
14681
14682
case types$1.braceL:
14683
return this.parseObj(true)
14684
}
14685
}
14686
return this.parseIdent()
14687
};
14688
14689
pp$7.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
14690
var elts = [], first = true;
14691
while (!this.eat(close)) {
14692
if (first) { first = false; }
14693
else { this.expect(types$1.comma); }
14694
if (allowEmpty && this.type === types$1.comma) {
14695
elts.push(null);
14696
} else if (allowTrailingComma && this.afterTrailingComma(close)) {
14697
break
14698
} else if (this.type === types$1.ellipsis) {
14699
var rest = this.parseRestBinding();
14700
this.parseBindingListItem(rest);
14701
elts.push(rest);
14702
if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
14703
this.expect(close);
14704
break
14705
} else {
14706
var elem = this.parseMaybeDefault(this.start, this.startLoc);
14707
this.parseBindingListItem(elem);
14708
elts.push(elem);
14709
}
14710
}
14711
return elts
14712
};
14713
14714
pp$7.parseBindingListItem = function(param) {
14715
return param
14716
};
14717
14718
// Parses assignment pattern around given atom if possible.
14719
14720
pp$7.parseMaybeDefault = function(startPos, startLoc, left) {
14721
left = left || this.parseBindingAtom();
14722
if (this.options.ecmaVersion < 6 || !this.eat(types$1.eq)) { return left }
14723
var node = this.startNodeAt(startPos, startLoc);
14724
node.left = left;
14725
node.right = this.parseMaybeAssign();
14726
return this.finishNode(node, "AssignmentPattern")
14727
};
14728
14729
// The following three functions all verify that a node is an lvalue —
14730
// something that can be bound, or assigned to. In order to do so, they perform
14731
// a variety of checks:
14732
//
14733
// - Check that none of the bound/assigned-to identifiers are reserved words.
14734
// - Record name declarations for bindings in the appropriate scope.
14735
// - Check duplicate argument names, if checkClashes is set.
14736
//
14737
// If a complex binding pattern is encountered (e.g., object and array
14738
// destructuring), the entire pattern is recursively checked.
14739
//
14740
// There are three versions of checkLVal*() appropriate for different
14741
// circumstances:
14742
//
14743
// - checkLValSimple() shall be used if the syntactic construct supports
14744
// nothing other than identifiers and member expressions. Parenthesized
14745
// expressions are also correctly handled. This is generally appropriate for
14746
// constructs for which the spec says
14747
//
14748
// > It is a Syntax Error if AssignmentTargetType of [the production] is not
14749
// > simple.
14750
//
14751
// It is also appropriate for checking if an identifier is valid and not
14752
// defined elsewhere, like import declarations or function/class identifiers.
14753
//
14754
// Examples where this is used include:
14755
// a += …;
14756
// import a from '…';
14757
// where a is the node to be checked.
14758
//
14759
// - checkLValPattern() shall be used if the syntactic construct supports
14760
// anything checkLValSimple() supports, as well as object and array
14761
// destructuring patterns. This is generally appropriate for constructs for
14762
// which the spec says
14763
//
14764
// > It is a Syntax Error if [the production] is neither an ObjectLiteral nor
14765
// > an ArrayLiteral and AssignmentTargetType of [the production] is not
14766
// > simple.
14767
//
14768
// Examples where this is used include:
14769
// (a = …);
14770
// const a = …;
14771
// try { … } catch (a) { … }
14772
// where a is the node to be checked.
14773
//
14774
// - checkLValInnerPattern() shall be used if the syntactic construct supports
14775
// anything checkLValPattern() supports, as well as default assignment
14776
// patterns, rest elements, and other constructs that may appear within an
14777
// object or array destructuring pattern.
14778
//
14779
// As a special case, function parameters also use checkLValInnerPattern(),
14780
// as they also support defaults and rest constructs.
14781
//
14782
// These functions deliberately support both assignment and binding constructs,
14783
// as the logic for both is exceedingly similar. If the node is the target of
14784
// an assignment, then bindingType should be set to BIND_NONE. Otherwise, it
14785
// should be set to the appropriate BIND_* constant, like BIND_VAR or
14786
// BIND_LEXICAL.
14787
//
14788
// If the function is called with a non-BIND_NONE bindingType, then
14789
// additionally a checkClashes object may be specified to allow checking for
14790
// duplicate argument names. checkClashes is ignored if the provided construct
14791
// is an assignment (i.e., bindingType is BIND_NONE).
14792
14793
pp$7.checkLValSimple = function(expr, bindingType, checkClashes) {
14794
if ( bindingType === void 0 ) bindingType = BIND_NONE;
14795
14796
var isBind = bindingType !== BIND_NONE;
14797
14798
switch (expr.type) {
14799
case "Identifier":
14800
if (this.strict && this.reservedWordsStrictBind.test(expr.name))
14801
{ this.raiseRecoverable(expr.start, (isBind ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
14802
if (isBind) {
14803
if (bindingType === BIND_LEXICAL && expr.name === "let")
14804
{ this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name"); }
14805
if (checkClashes) {
14806
if (hasOwn(checkClashes, expr.name))
14807
{ this.raiseRecoverable(expr.start, "Argument name clash"); }
14808
checkClashes[expr.name] = true;
14809
}
14810
if (bindingType !== BIND_OUTSIDE) { this.declareName(expr.name, bindingType, expr.start); }
14811
}
14812
break
14813
14814
case "ChainExpression":
14815
this.raiseRecoverable(expr.start, "Optional chaining cannot appear in left-hand side");
14816
break
14817
14818
case "MemberExpression":
14819
if (isBind) { this.raiseRecoverable(expr.start, "Binding member expression"); }
14820
break
14821
14822
case "ParenthesizedExpression":
14823
if (isBind) { this.raiseRecoverable(expr.start, "Binding parenthesized expression"); }
14824
return this.checkLValSimple(expr.expression, bindingType, checkClashes)
14825
14826
default:
14827
this.raise(expr.start, (isBind ? "Binding" : "Assigning to") + " rvalue");
14828
}
14829
};
14830
14831
pp$7.checkLValPattern = function(expr, bindingType, checkClashes) {
14832
if ( bindingType === void 0 ) bindingType = BIND_NONE;
14833
14834
switch (expr.type) {
14835
case "ObjectPattern":
14836
for (var i = 0, list = expr.properties; i < list.length; i += 1) {
14837
var prop = list[i];
14838
14839
this.checkLValInnerPattern(prop, bindingType, checkClashes);
14840
}
14841
break
14842
14843
case "ArrayPattern":
14844
for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
14845
var elem = list$1[i$1];
14846
14847
if (elem) { this.checkLValInnerPattern(elem, bindingType, checkClashes); }
14848
}
14849
break
14850
14851
default:
14852
this.checkLValSimple(expr, bindingType, checkClashes);
14853
}
14854
};
14855
14856
pp$7.checkLValInnerPattern = function(expr, bindingType, checkClashes) {
14857
if ( bindingType === void 0 ) bindingType = BIND_NONE;
14858
14859
switch (expr.type) {
14860
case "Property":
14861
// AssignmentProperty has type === "Property"
14862
this.checkLValInnerPattern(expr.value, bindingType, checkClashes);
14863
break
14864
14865
case "AssignmentPattern":
14866
this.checkLValPattern(expr.left, bindingType, checkClashes);
14867
break
14868
14869
case "RestElement":
14870
this.checkLValPattern(expr.argument, bindingType, checkClashes);
14871
break
14872
14873
default:
14874
this.checkLValPattern(expr, bindingType, checkClashes);
14875
}
14876
};
14877
14878
// The algorithm used to determine whether a regexp can appear at a
14879
14880
var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
14881
this.token = token;
14882
this.isExpr = !!isExpr;
14883
this.preserveSpace = !!preserveSpace;
14884
this.override = override;
14885
this.generator = !!generator;
14886
};
14887
14888
var types = {
14889
b_stat: new TokContext("{", false),
14890
b_expr: new TokContext("{", true),
14891
b_tmpl: new TokContext("${", false),
14892
p_stat: new TokContext("(", false),
14893
p_expr: new TokContext("(", true),
14894
q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
14895
f_stat: new TokContext("function", false),
14896
f_expr: new TokContext("function", true),
14897
f_expr_gen: new TokContext("function", true, false, null, true),
14898
f_gen: new TokContext("function", false, false, null, true)
14899
};
14900
14901
var pp$6 = Parser.prototype;
14902
14903
pp$6.initialContext = function() {
14904
return [types.b_stat]
14905
};
14906
14907
pp$6.curContext = function() {
14908
return this.context[this.context.length - 1]
14909
};
14910
14911
pp$6.braceIsBlock = function(prevType) {
14912
var parent = this.curContext();
14913
if (parent === types.f_expr || parent === types.f_stat)
14914
{ return true }
14915
if (prevType === types$1.colon && (parent === types.b_stat || parent === types.b_expr))
14916
{ return !parent.isExpr }
14917
14918
// The check for `tt.name && exprAllowed` detects whether we are
14919
// after a `yield` or `of` construct. See the `updateContext` for
14920
// `tt.name`.
14921
if (prevType === types$1._return || prevType === types$1.name && this.exprAllowed)
14922
{ return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
14923
if (prevType === types$1._else || prevType === types$1.semi || prevType === types$1.eof || prevType === types$1.parenR || prevType === types$1.arrow)
14924
{ return true }
14925
if (prevType === types$1.braceL)
14926
{ return parent === types.b_stat }
14927
if (prevType === types$1._var || prevType === types$1._const || prevType === types$1.name)
14928
{ return false }
14929
return !this.exprAllowed
14930
};
14931
14932
pp$6.inGeneratorContext = function() {
14933
for (var i = this.context.length - 1; i >= 1; i--) {
14934
var context = this.context[i];
14935
if (context.token === "function")
14936
{ return context.generator }
14937
}
14938
return false
14939
};
14940
14941
pp$6.updateContext = function(prevType) {
14942
var update, type = this.type;
14943
if (type.keyword && prevType === types$1.dot)
14944
{ this.exprAllowed = false; }
14945
else if (update = type.updateContext)
14946
{ update.call(this, prevType); }
14947
else
14948
{ this.exprAllowed = type.beforeExpr; }
14949
};
14950
14951
// Used to handle egde cases when token context could not be inferred correctly during tokenization phase
14952
14953
pp$6.overrideContext = function(tokenCtx) {
14954
if (this.curContext() !== tokenCtx) {
14955
this.context[this.context.length - 1] = tokenCtx;
14956
}
14957
};
14958
14959
// Token-specific context update code
14960
14961
types$1.parenR.updateContext = types$1.braceR.updateContext = function() {
14962
if (this.context.length === 1) {
14963
this.exprAllowed = true;
14964
return
14965
}
14966
var out = this.context.pop();
14967
if (out === types.b_stat && this.curContext().token === "function") {
14968
out = this.context.pop();
14969
}
14970
this.exprAllowed = !out.isExpr;
14971
};
14972
14973
types$1.braceL.updateContext = function(prevType) {
14974
this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
14975
this.exprAllowed = true;
14976
};
14977
14978
types$1.dollarBraceL.updateContext = function() {
14979
this.context.push(types.b_tmpl);
14980
this.exprAllowed = true;
14981
};
14982
14983
types$1.parenL.updateContext = function(prevType) {
14984
var statementParens = prevType === types$1._if || prevType === types$1._for || prevType === types$1._with || prevType === types$1._while;
14985
this.context.push(statementParens ? types.p_stat : types.p_expr);
14986
this.exprAllowed = true;
14987
};
14988
14989
types$1.incDec.updateContext = function() {
14990
// tokExprAllowed stays unchanged
14991
};
14992
14993
types$1._function.updateContext = types$1._class.updateContext = function(prevType) {
14994
if (prevType.beforeExpr && prevType !== types$1._else &&
14995
!(prevType === types$1.semi && this.curContext() !== types.p_stat) &&
14996
!(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) &&
14997
!((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat))
14998
{ this.context.push(types.f_expr); }
14999
else
15000
{ this.context.push(types.f_stat); }
15001
this.exprAllowed = false;
15002
};
15003
15004
types$1.backQuote.updateContext = function() {
15005
if (this.curContext() === types.q_tmpl)
15006
{ this.context.pop(); }
15007
else
15008
{ this.context.push(types.q_tmpl); }
15009
this.exprAllowed = false;
15010
};
15011
15012
types$1.star.updateContext = function(prevType) {
15013
if (prevType === types$1._function) {
15014
var index = this.context.length - 1;
15015
if (this.context[index] === types.f_expr)
15016
{ this.context[index] = types.f_expr_gen; }
15017
else
15018
{ this.context[index] = types.f_gen; }
15019
}
15020
this.exprAllowed = true;
15021
};
15022
15023
types$1.name.updateContext = function(prevType) {
15024
var allowed = false;
15025
if (this.options.ecmaVersion >= 6 && prevType !== types$1.dot) {
15026
if (this.value === "of" && !this.exprAllowed ||
15027
this.value === "yield" && this.inGeneratorContext())
15028
{ allowed = true; }
15029
}
15030
this.exprAllowed = allowed;
15031
};
15032
15033
// A recursive descent parser operates by defining functions for all
15034
15035
var pp$5 = Parser.prototype;
15036
15037
// Check if property name clashes with already added.
15038
// Object/class getters and setters are not allowed to clash —
15039
// either with each other or with an init property — and in
15040
// strict mode, init properties are also not allowed to be repeated.
15041
15042
pp$5.checkPropClash = function(prop, propHash, refDestructuringErrors) {
15043
if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
15044
{ return }
15045
if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
15046
{ return }
15047
var key = prop.key;
15048
var name;
15049
switch (key.type) {
15050
case "Identifier": name = key.name; break
15051
case "Literal": name = String(key.value); break
15052
default: return
15053
}
15054
var kind = prop.kind;
15055
if (this.options.ecmaVersion >= 6) {
15056
if (name === "__proto__" && kind === "init") {
15057
if (propHash.proto) {
15058
if (refDestructuringErrors) {
15059
if (refDestructuringErrors.doubleProto < 0) {
15060
refDestructuringErrors.doubleProto = key.start;
15061
}
15062
} else {
15063
this.raiseRecoverable(key.start, "Redefinition of __proto__ property");
15064
}
15065
}
15066
propHash.proto = true;
15067
}
15068
return
15069
}
15070
name = "$" + name;
15071
var other = propHash[name];
15072
if (other) {
15073
var redefinition;
15074
if (kind === "init") {
15075
redefinition = this.strict && other.init || other.get || other.set;
15076
} else {
15077
redefinition = other.init || other[kind];
15078
}
15079
if (redefinition)
15080
{ this.raiseRecoverable(key.start, "Redefinition of property"); }
15081
} else {
15082
other = propHash[name] = {
15083
init: false,
15084
get: false,
15085
set: false
15086
};
15087
}
15088
other[kind] = true;
15089
};
15090
15091
// ### Expression parsing
15092
15093
// These nest, from the most general expression type at the top to
15094
// 'atomic', nondivisible expression types at the bottom. Most of
15095
// the functions will simply let the function(s) below them parse,
15096
// and, *if* the syntactic construct they handle is present, wrap
15097
// the AST node that the inner parser gave them in another node.
15098
15099
// Parse a full expression. The optional arguments are used to
15100
// forbid the `in` operator (in for loops initalization expressions)
15101
// and provide reference for storing '=' operator inside shorthand
15102
// property assignment in contexts where both object expression
15103
// and object pattern might appear (so it's possible to raise
15104
// delayed syntax error at correct position).
15105
15106
pp$5.parseExpression = function(forInit, refDestructuringErrors) {
15107
var startPos = this.start, startLoc = this.startLoc;
15108
var expr = this.parseMaybeAssign(forInit, refDestructuringErrors);
15109
if (this.type === types$1.comma) {
15110
var node = this.startNodeAt(startPos, startLoc);
15111
node.expressions = [expr];
15112
while (this.eat(types$1.comma)) { node.expressions.push(this.parseMaybeAssign(forInit, refDestructuringErrors)); }
15113
return this.finishNode(node, "SequenceExpression")
15114
}
15115
return expr
15116
};
15117
15118
// Parse an assignment expression. This includes applications of
15119
// operators like `+=`.
15120
15121
pp$5.parseMaybeAssign = function(forInit, refDestructuringErrors, afterLeftParse) {
15122
if (this.isContextual("yield")) {
15123
if (this.inGenerator) { return this.parseYield(forInit) }
15124
// The tokenizer will assume an expression is allowed after
15125
// `yield`, but this isn't that kind of yield
15126
else { this.exprAllowed = false; }
15127
}
15128
15129
var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1, oldDoubleProto = -1;
15130
if (refDestructuringErrors) {
15131
oldParenAssign = refDestructuringErrors.parenthesizedAssign;
15132
oldTrailingComma = refDestructuringErrors.trailingComma;
15133
oldDoubleProto = refDestructuringErrors.doubleProto;
15134
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
15135
} else {
15136
refDestructuringErrors = new DestructuringErrors;
15137
ownDestructuringErrors = true;
15138
}
15139
15140
var startPos = this.start, startLoc = this.startLoc;
15141
if (this.type === types$1.parenL || this.type === types$1.name) {
15142
this.potentialArrowAt = this.start;
15143
this.potentialArrowInForAwait = forInit === "await";
15144
}
15145
var left = this.parseMaybeConditional(forInit, refDestructuringErrors);
15146
if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
15147
if (this.type.isAssign) {
15148
var node = this.startNodeAt(startPos, startLoc);
15149
node.operator = this.value;
15150
if (this.type === types$1.eq)
15151
{ left = this.toAssignable(left, false, refDestructuringErrors); }
15152
if (!ownDestructuringErrors) {
15153
refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = refDestructuringErrors.doubleProto = -1;
15154
}
15155
if (refDestructuringErrors.shorthandAssign >= left.start)
15156
{ refDestructuringErrors.shorthandAssign = -1; } // reset because shorthand default was used correctly
15157
if (this.type === types$1.eq)
15158
{ this.checkLValPattern(left); }
15159
else
15160
{ this.checkLValSimple(left); }
15161
node.left = left;
15162
this.next();
15163
node.right = this.parseMaybeAssign(forInit);
15164
if (oldDoubleProto > -1) { refDestructuringErrors.doubleProto = oldDoubleProto; }
15165
return this.finishNode(node, "AssignmentExpression")
15166
} else {
15167
if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
15168
}
15169
if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
15170
if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
15171
return left
15172
};
15173
15174
// Parse a ternary conditional (`?:`) operator.
15175
15176
pp$5.parseMaybeConditional = function(forInit, refDestructuringErrors) {
15177
var startPos = this.start, startLoc = this.startLoc;
15178
var expr = this.parseExprOps(forInit, refDestructuringErrors);
15179
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
15180
if (this.eat(types$1.question)) {
15181
var node = this.startNodeAt(startPos, startLoc);
15182
node.test = expr;
15183
node.consequent = this.parseMaybeAssign();
15184
this.expect(types$1.colon);
15185
node.alternate = this.parseMaybeAssign(forInit);
15186
return this.finishNode(node, "ConditionalExpression")
15187
}
15188
return expr
15189
};
15190
15191
// Start the precedence parser.
15192
15193
pp$5.parseExprOps = function(forInit, refDestructuringErrors) {
15194
var startPos = this.start, startLoc = this.startLoc;
15195
var expr = this.parseMaybeUnary(refDestructuringErrors, false, false, forInit);
15196
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
15197
return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, forInit)
15198
};
15199
15200
// Parse binary operators with the operator precedence parsing
15201
// algorithm. `left` is the left-hand side of the operator.
15202
// `minPrec` provides context that allows the function to stop and
15203
// defer further parser to one of its callers when it encounters an
15204
// operator that has a lower precedence than the set it is parsing.
15205
15206
pp$5.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, forInit) {
15207
var prec = this.type.binop;
15208
if (prec != null && (!forInit || this.type !== types$1._in)) {
15209
if (prec > minPrec) {
15210
var logical = this.type === types$1.logicalOR || this.type === types$1.logicalAND;
15211
var coalesce = this.type === types$1.coalesce;
15212
if (coalesce) {
15213
// Handle the precedence of `tt.coalesce` as equal to the range of logical expressions.
15214
// In other words, `node.right` shouldn't contain logical expressions in order to check the mixed error.
15215
prec = types$1.logicalAND.binop;
15216
}
15217
var op = this.value;
15218
this.next();
15219
var startPos = this.start, startLoc = this.startLoc;
15220
var right = this.parseExprOp(this.parseMaybeUnary(null, false, false, forInit), startPos, startLoc, prec, forInit);
15221
var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical || coalesce);
15222
if ((logical && this.type === types$1.coalesce) || (coalesce && (this.type === types$1.logicalOR || this.type === types$1.logicalAND))) {
15223
this.raiseRecoverable(this.start, "Logical expressions and coalesce expressions cannot be mixed. Wrap either by parentheses");
15224
}
15225
return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, forInit)
15226
}
15227
}
15228
return left
15229
};
15230
15231
pp$5.buildBinary = function(startPos, startLoc, left, right, op, logical) {
15232
if (right.type === "PrivateIdentifier") { this.raise(right.start, "Private identifier can only be left side of binary expression"); }
15233
var node = this.startNodeAt(startPos, startLoc);
15234
node.left = left;
15235
node.operator = op;
15236
node.right = right;
15237
return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
15238
};
15239
15240
// Parse unary operators, both prefix and postfix.
15241
15242
pp$5.parseMaybeUnary = function(refDestructuringErrors, sawUnary, incDec, forInit) {
15243
var startPos = this.start, startLoc = this.startLoc, expr;
15244
if (this.isContextual("await") && this.canAwait) {
15245
expr = this.parseAwait(forInit);
15246
sawUnary = true;
15247
} else if (this.type.prefix) {
15248
var node = this.startNode(), update = this.type === types$1.incDec;
15249
node.operator = this.value;
15250
node.prefix = true;
15251
this.next();
15252
node.argument = this.parseMaybeUnary(null, true, update, forInit);
15253
this.checkExpressionErrors(refDestructuringErrors, true);
15254
if (update) { this.checkLValSimple(node.argument); }
15255
else if (this.strict && node.operator === "delete" &&
15256
node.argument.type === "Identifier")
15257
{ this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
15258
else if (node.operator === "delete" && isPrivateFieldAccess(node.argument))
15259
{ this.raiseRecoverable(node.start, "Private fields can not be deleted"); }
15260
else { sawUnary = true; }
15261
expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
15262
} else if (!sawUnary && this.type === types$1.privateId) {
15263
if (forInit || this.privateNameStack.length === 0) { this.unexpected(); }
15264
expr = this.parsePrivateIdent();
15265
// only could be private fields in 'in', such as #x in obj
15266
if (this.type !== types$1._in) { this.unexpected(); }
15267
} else {
15268
expr = this.parseExprSubscripts(refDestructuringErrors, forInit);
15269
if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
15270
while (this.type.postfix && !this.canInsertSemicolon()) {
15271
var node$1 = this.startNodeAt(startPos, startLoc);
15272
node$1.operator = this.value;
15273
node$1.prefix = false;
15274
node$1.argument = expr;
15275
this.checkLValSimple(expr);
15276
this.next();
15277
expr = this.finishNode(node$1, "UpdateExpression");
15278
}
15279
}
15280
15281
if (!incDec && this.eat(types$1.starstar)) {
15282
if (sawUnary)
15283
{ this.unexpected(this.lastTokStart); }
15284
else
15285
{ return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false, false, forInit), "**", false) }
15286
} else {
15287
return expr
15288
}
15289
};
15290
15291
function isPrivateFieldAccess(node) {
15292
return (
15293
node.type === "MemberExpression" && node.property.type === "PrivateIdentifier" ||
15294
node.type === "ChainExpression" && isPrivateFieldAccess(node.expression)
15295
)
15296
}
15297
15298
// Parse call, dot, and `[]`-subscript expressions.
15299
15300
pp$5.parseExprSubscripts = function(refDestructuringErrors, forInit) {
15301
var startPos = this.start, startLoc = this.startLoc;
15302
var expr = this.parseExprAtom(refDestructuringErrors, forInit);
15303
if (expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")")
15304
{ return expr }
15305
var result = this.parseSubscripts(expr, startPos, startLoc, false, forInit);
15306
if (refDestructuringErrors && result.type === "MemberExpression") {
15307
if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
15308
if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
15309
if (refDestructuringErrors.trailingComma >= result.start) { refDestructuringErrors.trailingComma = -1; }
15310
}
15311
return result
15312
};
15313
15314
pp$5.parseSubscripts = function(base, startPos, startLoc, noCalls, forInit) {
15315
var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
15316
this.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 &&
15317
this.potentialArrowAt === base.start;
15318
var optionalChained = false;
15319
15320
while (true) {
15321
var element = this.parseSubscript(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit);
15322
15323
if (element.optional) { optionalChained = true; }
15324
if (element === base || element.type === "ArrowFunctionExpression") {
15325
if (optionalChained) {
15326
var chainNode = this.startNodeAt(startPos, startLoc);
15327
chainNode.expression = element;
15328
element = this.finishNode(chainNode, "ChainExpression");
15329
}
15330
return element
15331
}
15332
15333
base = element;
15334
}
15335
};
15336
15337
pp$5.parseSubscript = function(base, startPos, startLoc, noCalls, maybeAsyncArrow, optionalChained, forInit) {
15338
var optionalSupported = this.options.ecmaVersion >= 11;
15339
var optional = optionalSupported && this.eat(types$1.questionDot);
15340
if (noCalls && optional) { this.raise(this.lastTokStart, "Optional chaining cannot appear in the callee of new expressions"); }
15341
15342
var computed = this.eat(types$1.bracketL);
15343
if (computed || (optional && this.type !== types$1.parenL && this.type !== types$1.backQuote) || this.eat(types$1.dot)) {
15344
var node = this.startNodeAt(startPos, startLoc);
15345
node.object = base;
15346
if (computed) {
15347
node.property = this.parseExpression();
15348
this.expect(types$1.bracketR);
15349
} else if (this.type === types$1.privateId && base.type !== "Super") {
15350
node.property = this.parsePrivateIdent();
15351
} else {
15352
node.property = this.parseIdent(this.options.allowReserved !== "never");
15353
}
15354
node.computed = !!computed;
15355
if (optionalSupported) {
15356
node.optional = optional;
15357
}
15358
base = this.finishNode(node, "MemberExpression");
15359
} else if (!noCalls && this.eat(types$1.parenL)) {
15360
var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
15361
this.yieldPos = 0;
15362
this.awaitPos = 0;
15363
this.awaitIdentPos = 0;
15364
var exprList = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors);
15365
if (maybeAsyncArrow && !optional && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {
15366
this.checkPatternErrors(refDestructuringErrors, false);
15367
this.checkYieldAwaitInDefaultParams();
15368
if (this.awaitIdentPos > 0)
15369
{ this.raise(this.awaitIdentPos, "Cannot use 'await' as identifier inside an async function"); }
15370
this.yieldPos = oldYieldPos;
15371
this.awaitPos = oldAwaitPos;
15372
this.awaitIdentPos = oldAwaitIdentPos;
15373
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true, forInit)
15374
}
15375
this.checkExpressionErrors(refDestructuringErrors, true);
15376
this.yieldPos = oldYieldPos || this.yieldPos;
15377
this.awaitPos = oldAwaitPos || this.awaitPos;
15378
this.awaitIdentPos = oldAwaitIdentPos || this.awaitIdentPos;
15379
var node$1 = this.startNodeAt(startPos, startLoc);
15380
node$1.callee = base;
15381
node$1.arguments = exprList;
15382
if (optionalSupported) {
15383
node$1.optional = optional;
15384
}
15385
base = this.finishNode(node$1, "CallExpression");
15386
} else if (this.type === types$1.backQuote) {
15387
if (optional || optionalChained) {
15388
this.raise(this.start, "Optional chaining cannot appear in the tag of tagged template expressions");
15389
}
15390
var node$2 = this.startNodeAt(startPos, startLoc);
15391
node$2.tag = base;
15392
node$2.quasi = this.parseTemplate({isTagged: true});
15393
base = this.finishNode(node$2, "TaggedTemplateExpression");
15394
}
15395
return base
15396
};
15397
15398
// Parse an atomic expression — either a single token that is an
15399
// expression, an expression started by a keyword like `function` or
15400
// `new`, or an expression wrapped in punctuation like `()`, `[]`,
15401
// or `{}`.
15402
15403
pp$5.parseExprAtom = function(refDestructuringErrors, forInit) {
15404
// If a division operator appears in an expression position, the
15405
// tokenizer got confused, and we force it to read a regexp instead.
15406
if (this.type === types$1.slash) { this.readRegexp(); }
15407
15408
var node, canBeArrow = this.potentialArrowAt === this.start;
15409
switch (this.type) {
15410
case types$1._super:
15411
if (!this.allowSuper)
15412
{ this.raise(this.start, "'super' keyword outside a method"); }
15413
node = this.startNode();
15414
this.next();
15415
if (this.type === types$1.parenL && !this.allowDirectSuper)
15416
{ this.raise(node.start, "super() call outside constructor of a subclass"); }
15417
// The `super` keyword can appear at below:
15418
// SuperProperty:
15419
// super [ Expression ]
15420
// super . IdentifierName
15421
// SuperCall:
15422
// super ( Arguments )
15423
if (this.type !== types$1.dot && this.type !== types$1.bracketL && this.type !== types$1.parenL)
15424
{ this.unexpected(); }
15425
return this.finishNode(node, "Super")
15426
15427
case types$1._this:
15428
node = this.startNode();
15429
this.next();
15430
return this.finishNode(node, "ThisExpression")
15431
15432
case types$1.name:
15433
var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
15434
var id = this.parseIdent(false);
15435
if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types$1._function)) {
15436
this.overrideContext(types.f_expr);
15437
return this.parseFunction(this.startNodeAt(startPos, startLoc), 0, false, true, forInit)
15438
}
15439
if (canBeArrow && !this.canInsertSemicolon()) {
15440
if (this.eat(types$1.arrow))
15441
{ return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false, forInit) }
15442
if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types$1.name && !containsEsc &&
15443
(!this.potentialArrowInForAwait || this.value !== "of" || this.containsEsc)) {
15444
id = this.parseIdent(false);
15445
if (this.canInsertSemicolon() || !this.eat(types$1.arrow))
15446
{ this.unexpected(); }
15447
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true, forInit)
15448
}
15449
}
15450
return id
15451
15452
case types$1.regexp:
15453
var value = this.value;
15454
node = this.parseLiteral(value.value);
15455
node.regex = {pattern: value.pattern, flags: value.flags};
15456
return node
15457
15458
case types$1.num: case types$1.string:
15459
return this.parseLiteral(this.value)
15460
15461
case types$1._null: case types$1._true: case types$1._false:
15462
node = this.startNode();
15463
node.value = this.type === types$1._null ? null : this.type === types$1._true;
15464
node.raw = this.type.keyword;
15465
this.next();
15466
return this.finishNode(node, "Literal")
15467
15468
case types$1.parenL:
15469
var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow, forInit);
15470
if (refDestructuringErrors) {
15471
if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
15472
{ refDestructuringErrors.parenthesizedAssign = start; }
15473
if (refDestructuringErrors.parenthesizedBind < 0)
15474
{ refDestructuringErrors.parenthesizedBind = start; }
15475
}
15476
return expr
15477
15478
case types$1.bracketL:
15479
node = this.startNode();
15480
this.next();
15481
node.elements = this.parseExprList(types$1.bracketR, true, true, refDestructuringErrors);
15482
return this.finishNode(node, "ArrayExpression")
15483
15484
case types$1.braceL:
15485
this.overrideContext(types.b_expr);
15486
return this.parseObj(false, refDestructuringErrors)
15487
15488
case types$1._function:
15489
node = this.startNode();
15490
this.next();
15491
return this.parseFunction(node, 0)
15492
15493
case types$1._class:
15494
return this.parseClass(this.startNode(), false)
15495
15496
case types$1._new:
15497
return this.parseNew()
15498
15499
case types$1.backQuote:
15500
return this.parseTemplate()
15501
15502
case types$1._import:
15503
if (this.options.ecmaVersion >= 11) {
15504
return this.parseExprImport()
15505
} else {
15506
return this.unexpected()
15507
}
15508
15509
default:
15510
this.unexpected();
15511
}
15512
};
15513
15514
pp$5.parseExprImport = function() {
15515
var node = this.startNode();
15516
15517
// Consume `import` as an identifier for `import.meta`.
15518
// Because `this.parseIdent(true)` doesn't check escape sequences, it needs the check of `this.containsEsc`.
15519
if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword import"); }
15520
var meta = this.parseIdent(true);
15521
15522
switch (this.type) {
15523
case types$1.parenL:
15524
return this.parseDynamicImport(node)
15525
case types$1.dot:
15526
node.meta = meta;
15527
return this.parseImportMeta(node)
15528
default:
15529
this.unexpected();
15530
}
15531
};
15532
15533
pp$5.parseDynamicImport = function(node) {
15534
this.next(); // skip `(`
15535
15536
// Parse node.source.
15537
node.source = this.parseMaybeAssign();
15538
15539
// Verify ending.
15540
if (!this.eat(types$1.parenR)) {
15541
var errorPos = this.start;
15542
if (this.eat(types$1.comma) && this.eat(types$1.parenR)) {
15543
this.raiseRecoverable(errorPos, "Trailing comma is not allowed in import()");
15544
} else {
15545
this.unexpected(errorPos);
15546
}
15547
}
15548
15549
return this.finishNode(node, "ImportExpression")
15550
};
15551
15552
pp$5.parseImportMeta = function(node) {
15553
this.next(); // skip `.`
15554
15555
var containsEsc = this.containsEsc;
15556
node.property = this.parseIdent(true);
15557
15558
if (node.property.name !== "meta")
15559
{ this.raiseRecoverable(node.property.start, "The only valid meta property for import is 'import.meta'"); }
15560
if (containsEsc)
15561
{ this.raiseRecoverable(node.start, "'import.meta' must not contain escaped characters"); }
15562
if (this.options.sourceType !== "module" && !this.options.allowImportExportEverywhere)
15563
{ this.raiseRecoverable(node.start, "Cannot use 'import.meta' outside a module"); }
15564
15565
return this.finishNode(node, "MetaProperty")
15566
};
15567
15568
pp$5.parseLiteral = function(value) {
15569
var node = this.startNode();
15570
node.value = value;
15571
node.raw = this.input.slice(this.start, this.end);
15572
if (node.raw.charCodeAt(node.raw.length - 1) === 110) { node.bigint = node.raw.slice(0, -1).replace(/_/g, ""); }
15573
this.next();
15574
return this.finishNode(node, "Literal")
15575
};
15576
15577
pp$5.parseParenExpression = function() {
15578
this.expect(types$1.parenL);
15579
var val = this.parseExpression();
15580
this.expect(types$1.parenR);
15581
return val
15582
};
15583
15584
pp$5.parseParenAndDistinguishExpression = function(canBeArrow, forInit) {
15585
var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
15586
if (this.options.ecmaVersion >= 6) {
15587
this.next();
15588
15589
var innerStartPos = this.start, innerStartLoc = this.startLoc;
15590
var exprList = [], first = true, lastIsComma = false;
15591
var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
15592
this.yieldPos = 0;
15593
this.awaitPos = 0;
15594
// Do not save awaitIdentPos to allow checking awaits nested in parameters
15595
while (this.type !== types$1.parenR) {
15596
first ? first = false : this.expect(types$1.comma);
15597
if (allowTrailingComma && this.afterTrailingComma(types$1.parenR, true)) {
15598
lastIsComma = true;
15599
break
15600
} else if (this.type === types$1.ellipsis) {
15601
spreadStart = this.start;
15602
exprList.push(this.parseParenItem(this.parseRestBinding()));
15603
if (this.type === types$1.comma) { this.raise(this.start, "Comma is not permitted after the rest element"); }
15604
break
15605
} else {
15606
exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem));
15607
}
15608
}
15609
var innerEndPos = this.lastTokEnd, innerEndLoc = this.lastTokEndLoc;
15610
this.expect(types$1.parenR);
15611
15612
if (canBeArrow && !this.canInsertSemicolon() && this.eat(types$1.arrow)) {
15613
this.checkPatternErrors(refDestructuringErrors, false);
15614
this.checkYieldAwaitInDefaultParams();
15615
this.yieldPos = oldYieldPos;
15616
this.awaitPos = oldAwaitPos;
15617
return this.parseParenArrowList(startPos, startLoc, exprList, forInit)
15618
}
15619
15620
if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
15621
if (spreadStart) { this.unexpected(spreadStart); }
15622
this.checkExpressionErrors(refDestructuringErrors, true);
15623
this.yieldPos = oldYieldPos || this.yieldPos;
15624
this.awaitPos = oldAwaitPos || this.awaitPos;
15625
15626
if (exprList.length > 1) {
15627
val = this.startNodeAt(innerStartPos, innerStartLoc);
15628
val.expressions = exprList;
15629
this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
15630
} else {
15631
val = exprList[0];
15632
}
15633
} else {
15634
val = this.parseParenExpression();
15635
}
15636
15637
if (this.options.preserveParens) {
15638
var par = this.startNodeAt(startPos, startLoc);
15639
par.expression = val;
15640
return this.finishNode(par, "ParenthesizedExpression")
15641
} else {
15642
return val
15643
}
15644
};
15645
15646
pp$5.parseParenItem = function(item) {
15647
return item
15648
};
15649
15650
pp$5.parseParenArrowList = function(startPos, startLoc, exprList, forInit) {
15651
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, false, forInit)
15652
};
15653
15654
// New's precedence is slightly tricky. It must allow its argument to
15655
// be a `[]` or dot subscript expression, but not a call — at least,
15656
// not without wrapping it in parentheses. Thus, it uses the noCalls
15657
// argument to parseSubscripts to prevent it from consuming the
15658
// argument list.
15659
15660
var empty = [];
15661
15662
pp$5.parseNew = function() {
15663
if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword new"); }
15664
var node = this.startNode();
15665
var meta = this.parseIdent(true);
15666
if (this.options.ecmaVersion >= 6 && this.eat(types$1.dot)) {
15667
node.meta = meta;
15668
var containsEsc = this.containsEsc;
15669
node.property = this.parseIdent(true);
15670
if (node.property.name !== "target")
15671
{ this.raiseRecoverable(node.property.start, "The only valid meta property for new is 'new.target'"); }
15672
if (containsEsc)
15673
{ this.raiseRecoverable(node.start, "'new.target' must not contain escaped characters"); }
15674
if (!this.allowNewDotTarget)
15675
{ this.raiseRecoverable(node.start, "'new.target' can only be used in functions and class static block"); }
15676
return this.finishNode(node, "MetaProperty")
15677
}
15678
var startPos = this.start, startLoc = this.startLoc, isImport = this.type === types$1._import;
15679
node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true, false);
15680
if (isImport && node.callee.type === "ImportExpression") {
15681
this.raise(startPos, "Cannot use new with import()");
15682
}
15683
if (this.eat(types$1.parenL)) { node.arguments = this.parseExprList(types$1.parenR, this.options.ecmaVersion >= 8, false); }
15684
else { node.arguments = empty; }
15685
return this.finishNode(node, "NewExpression")
15686
};
15687
15688
// Parse template expression.
15689
15690
pp$5.parseTemplateElement = function(ref) {
15691
var isTagged = ref.isTagged;
15692
15693
var elem = this.startNode();
15694
if (this.type === types$1.invalidTemplate) {
15695
if (!isTagged) {
15696
this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
15697
}
15698
elem.value = {
15699
raw: this.value,
15700
cooked: null
15701
};
15702
} else {
15703
elem.value = {
15704
raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
15705
cooked: this.value
15706
};
15707
}
15708
this.next();
15709
elem.tail = this.type === types$1.backQuote;
15710
return this.finishNode(elem, "TemplateElement")
15711
};
15712
15713
pp$5.parseTemplate = function(ref) {
15714
if ( ref === void 0 ) ref = {};
15715
var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
15716
15717
var node = this.startNode();
15718
this.next();
15719
node.expressions = [];
15720
var curElt = this.parseTemplateElement({isTagged: isTagged});
15721
node.quasis = [curElt];
15722
while (!curElt.tail) {
15723
if (this.type === types$1.eof) { this.raise(this.pos, "Unterminated template literal"); }
15724
this.expect(types$1.dollarBraceL);
15725
node.expressions.push(this.parseExpression());
15726
this.expect(types$1.braceR);
15727
node.quasis.push(curElt = this.parseTemplateElement({isTagged: isTagged}));
15728
}
15729
this.next();
15730
return this.finishNode(node, "TemplateLiteral")
15731
};
15732
15733
pp$5.isAsyncProp = function(prop) {
15734
return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
15735
(this.type === types$1.name || this.type === types$1.num || this.type === types$1.string || this.type === types$1.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types$1.star)) &&
15736
!lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
15737
};
15738
15739
// Parse an object literal or binding pattern.
15740
15741
pp$5.parseObj = function(isPattern, refDestructuringErrors) {
15742
var node = this.startNode(), first = true, propHash = {};
15743
node.properties = [];
15744
this.next();
15745
while (!this.eat(types$1.braceR)) {
15746
if (!first) {
15747
this.expect(types$1.comma);
15748
if (this.options.ecmaVersion >= 5 && this.afterTrailingComma(types$1.braceR)) { break }
15749
} else { first = false; }
15750
15751
var prop = this.parseProperty(isPattern, refDestructuringErrors);
15752
if (!isPattern) { this.checkPropClash(prop, propHash, refDestructuringErrors); }
15753
node.properties.push(prop);
15754
}
15755
return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
15756
};
15757
15758
pp$5.parseProperty = function(isPattern, refDestructuringErrors) {
15759
var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
15760
if (this.options.ecmaVersion >= 9 && this.eat(types$1.ellipsis)) {
15761
if (isPattern) {
15762
prop.argument = this.parseIdent(false);
15763
if (this.type === types$1.comma) {
15764
this.raise(this.start, "Comma is not permitted after the rest element");
15765
}
15766
return this.finishNode(prop, "RestElement")
15767
}
15768
// Parse argument.
15769
prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
15770
// To disallow trailing comma via `this.toAssignable()`.
15771
if (this.type === types$1.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
15772
refDestructuringErrors.trailingComma = this.start;
15773
}
15774
// Finish
15775
return this.finishNode(prop, "SpreadElement")
15776
}
15777
if (this.options.ecmaVersion >= 6) {
15778
prop.method = false;
15779
prop.shorthand = false;
15780
if (isPattern || refDestructuringErrors) {
15781
startPos = this.start;
15782
startLoc = this.startLoc;
15783
}
15784
if (!isPattern)
15785
{ isGenerator = this.eat(types$1.star); }
15786
}
15787
var containsEsc = this.containsEsc;
15788
this.parsePropertyName(prop);
15789
if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
15790
isAsync = true;
15791
isGenerator = this.options.ecmaVersion >= 9 && this.eat(types$1.star);
15792
this.parsePropertyName(prop, refDestructuringErrors);
15793
} else {
15794
isAsync = false;
15795
}
15796
this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
15797
return this.finishNode(prop, "Property")
15798
};
15799
15800
pp$5.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
15801
if ((isGenerator || isAsync) && this.type === types$1.colon)
15802
{ this.unexpected(); }
15803
15804
if (this.eat(types$1.colon)) {
15805
prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
15806
prop.kind = "init";
15807
} else if (this.options.ecmaVersion >= 6 && this.type === types$1.parenL) {
15808
if (isPattern) { this.unexpected(); }
15809
prop.kind = "init";
15810
prop.method = true;
15811
prop.value = this.parseMethod(isGenerator, isAsync);
15812
} else if (!isPattern && !containsEsc &&
15813
this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
15814
(prop.key.name === "get" || prop.key.name === "set") &&
15815
(this.type !== types$1.comma && this.type !== types$1.braceR && this.type !== types$1.eq)) {
15816
if (isGenerator || isAsync) { this.unexpected(); }
15817
prop.kind = prop.key.name;
15818
this.parsePropertyName(prop);
15819
prop.value = this.parseMethod(false);
15820
var paramCount = prop.kind === "get" ? 0 : 1;
15821
if (prop.value.params.length !== paramCount) {
15822
var start = prop.value.start;
15823
if (prop.kind === "get")
15824
{ this.raiseRecoverable(start, "getter should have no params"); }
15825
else
15826
{ this.raiseRecoverable(start, "setter should have exactly one param"); }
15827
} else {
15828
if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
15829
{ this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
15830
}
15831
} else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
15832
if (isGenerator || isAsync) { this.unexpected(); }
15833
this.checkUnreserved(prop.key);
15834
if (prop.key.name === "await" && !this.awaitIdentPos)
15835
{ this.awaitIdentPos = startPos; }
15836
prop.kind = "init";
15837
if (isPattern) {
15838
prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
15839
} else if (this.type === types$1.eq && refDestructuringErrors) {
15840
if (refDestructuringErrors.shorthandAssign < 0)
15841
{ refDestructuringErrors.shorthandAssign = this.start; }
15842
prop.value = this.parseMaybeDefault(startPos, startLoc, this.copyNode(prop.key));
15843
} else {
15844
prop.value = this.copyNode(prop.key);
15845
}
15846
prop.shorthand = true;
15847
} else { this.unexpected(); }
15848
};
15849
15850
pp$5.parsePropertyName = function(prop) {
15851
if (this.options.ecmaVersion >= 6) {
15852
if (this.eat(types$1.bracketL)) {
15853
prop.computed = true;
15854
prop.key = this.parseMaybeAssign();
15855
this.expect(types$1.bracketR);
15856
return prop.key
15857
} else {
15858
prop.computed = false;
15859
}
15860
}
15861
return prop.key = this.type === types$1.num || this.type === types$1.string ? this.parseExprAtom() : this.parseIdent(this.options.allowReserved !== "never")
15862
};
15863
15864
// Initialize empty function node.
15865
15866
pp$5.initFunction = function(node) {
15867
node.id = null;
15868
if (this.options.ecmaVersion >= 6) { node.generator = node.expression = false; }
15869
if (this.options.ecmaVersion >= 8) { node.async = false; }
15870
};
15871
15872
// Parse object or class method.
15873
15874
pp$5.parseMethod = function(isGenerator, isAsync, allowDirectSuper) {
15875
var node = this.startNode(), oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
15876
15877
this.initFunction(node);
15878
if (this.options.ecmaVersion >= 6)
15879
{ node.generator = isGenerator; }
15880
if (this.options.ecmaVersion >= 8)
15881
{ node.async = !!isAsync; }
15882
15883
this.yieldPos = 0;
15884
this.awaitPos = 0;
15885
this.awaitIdentPos = 0;
15886
this.enterScope(functionFlags(isAsync, node.generator) | SCOPE_SUPER | (allowDirectSuper ? SCOPE_DIRECT_SUPER : 0));
15887
15888
this.expect(types$1.parenL);
15889
node.params = this.parseBindingList(types$1.parenR, false, this.options.ecmaVersion >= 8);
15890
this.checkYieldAwaitInDefaultParams();
15891
this.parseFunctionBody(node, false, true, false);
15892
15893
this.yieldPos = oldYieldPos;
15894
this.awaitPos = oldAwaitPos;
15895
this.awaitIdentPos = oldAwaitIdentPos;
15896
return this.finishNode(node, "FunctionExpression")
15897
};
15898
15899
// Parse arrow function expression with given parameters.
15900
15901
pp$5.parseArrowExpression = function(node, params, isAsync, forInit) {
15902
var oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldAwaitIdentPos = this.awaitIdentPos;
15903
15904
this.enterScope(functionFlags(isAsync, false) | SCOPE_ARROW);
15905
this.initFunction(node);
15906
if (this.options.ecmaVersion >= 8) { node.async = !!isAsync; }
15907
15908
this.yieldPos = 0;
15909
this.awaitPos = 0;
15910
this.awaitIdentPos = 0;
15911
15912
node.params = this.toAssignableList(params, true);
15913
this.parseFunctionBody(node, true, false, forInit);
15914
15915
this.yieldPos = oldYieldPos;
15916
this.awaitPos = oldAwaitPos;
15917
this.awaitIdentPos = oldAwaitIdentPos;
15918
return this.finishNode(node, "ArrowFunctionExpression")
15919
};
15920
15921
// Parse function body and check parameters.
15922
15923
pp$5.parseFunctionBody = function(node, isArrowFunction, isMethod, forInit) {
15924
var isExpression = isArrowFunction && this.type !== types$1.braceL;
15925
var oldStrict = this.strict, useStrict = false;
15926
15927
if (isExpression) {
15928
node.body = this.parseMaybeAssign(forInit);
15929
node.expression = true;
15930
this.checkParams(node, false);
15931
} else {
15932
var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
15933
if (!oldStrict || nonSimple) {
15934
useStrict = this.strictDirective(this.end);
15935
// If this is a strict mode function, verify that argument names
15936
// are not repeated, and it does not try to bind the words `eval`
15937
// or `arguments`.
15938
if (useStrict && nonSimple)
15939
{ this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
15940
}
15941
// Start a new scope with regard to labels and the `inFunction`
15942
// flag (restore them to their old value afterwards).
15943
var oldLabels = this.labels;
15944
this.labels = [];
15945
if (useStrict) { this.strict = true; }
15946
15947
// Add the params to varDeclaredNames to ensure that an error is thrown
15948
// if a let/const declaration in the function clashes with one of the params.
15949
this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && !isMethod && this.isSimpleParamList(node.params));
15950
// Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
15951
if (this.strict && node.id) { this.checkLValSimple(node.id, BIND_OUTSIDE); }
15952
node.body = this.parseBlock(false, undefined, useStrict && !oldStrict);
15953
node.expression = false;
15954
this.adaptDirectivePrologue(node.body.body);
15955
this.labels = oldLabels;
15956
}
15957
this.exitScope();
15958
};
15959
15960
pp$5.isSimpleParamList = function(params) {
15961
for (var i = 0, list = params; i < list.length; i += 1)
15962
{
15963
var param = list[i];
15964
15965
if (param.type !== "Identifier") { return false
15966
} }
15967
return true
15968
};
15969
15970
// Checks function params for various disallowed patterns such as using "eval"
15971
// or "arguments" and duplicate parameters.
15972
15973
pp$5.checkParams = function(node, allowDuplicates) {
15974
var nameHash = Object.create(null);
15975
for (var i = 0, list = node.params; i < list.length; i += 1)
15976
{
15977
var param = list[i];
15978
15979
this.checkLValInnerPattern(param, BIND_VAR, allowDuplicates ? null : nameHash);
15980
}
15981
};
15982
15983
// Parses a comma-separated list of expressions, and returns them as
15984
// an array. `close` is the token type that ends the list, and
15985
// `allowEmpty` can be turned on to allow subsequent commas with
15986
// nothing in between them to be parsed as `null` (which is needed
15987
// for array literals).
15988
15989
pp$5.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
15990
var elts = [], first = true;
15991
while (!this.eat(close)) {
15992
if (!first) {
15993
this.expect(types$1.comma);
15994
if (allowTrailingComma && this.afterTrailingComma(close)) { break }
15995
} else { first = false; }
15996
15997
var elt = (void 0);
15998
if (allowEmpty && this.type === types$1.comma)
15999
{ elt = null; }
16000
else if (this.type === types$1.ellipsis) {
16001
elt = this.parseSpread(refDestructuringErrors);
16002
if (refDestructuringErrors && this.type === types$1.comma && refDestructuringErrors.trailingComma < 0)
16003
{ refDestructuringErrors.trailingComma = this.start; }
16004
} else {
16005
elt = this.parseMaybeAssign(false, refDestructuringErrors);
16006
}
16007
elts.push(elt);
16008
}
16009
return elts
16010
};
16011
16012
pp$5.checkUnreserved = function(ref) {
16013
var start = ref.start;
16014
var end = ref.end;
16015
var name = ref.name;
16016
16017
if (this.inGenerator && name === "yield")
16018
{ this.raiseRecoverable(start, "Cannot use 'yield' as identifier inside a generator"); }
16019
if (this.inAsync && name === "await")
16020
{ this.raiseRecoverable(start, "Cannot use 'await' as identifier inside an async function"); }
16021
if (this.currentThisScope().inClassFieldInit && name === "arguments")
16022
{ this.raiseRecoverable(start, "Cannot use 'arguments' in class field initializer"); }
16023
if (this.inClassStaticBlock && (name === "arguments" || name === "await"))
16024
{ this.raise(start, ("Cannot use " + name + " in class static initialization block")); }
16025
if (this.keywords.test(name))
16026
{ this.raise(start, ("Unexpected keyword '" + name + "'")); }
16027
if (this.options.ecmaVersion < 6 &&
16028
this.input.slice(start, end).indexOf("\\") !== -1) { return }
16029
var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
16030
if (re.test(name)) {
16031
if (!this.inAsync && name === "await")
16032
{ this.raiseRecoverable(start, "Cannot use keyword 'await' outside an async function"); }
16033
this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
16034
}
16035
};
16036
16037
// Parse the next token as an identifier. If `liberal` is true (used
16038
// when parsing properties), it will also convert keywords into
16039
// identifiers.
16040
16041
pp$5.parseIdent = function(liberal, isBinding) {
16042
var node = this.startNode();
16043
if (this.type === types$1.name) {
16044
node.name = this.value;
16045
} else if (this.type.keyword) {
16046
node.name = this.type.keyword;
16047
16048
// To fix https://github.com/acornjs/acorn/issues/575
16049
// `class` and `function` keywords push new context into this.context.
16050
// But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
16051
// If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
16052
if ((node.name === "class" || node.name === "function") &&
16053
(this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
16054
this.context.pop();
16055
}
16056
} else {
16057
this.unexpected();
16058
}
16059
this.next(!!liberal);
16060
this.finishNode(node, "Identifier");
16061
if (!liberal) {
16062
this.checkUnreserved(node);
16063
if (node.name === "await" && !this.awaitIdentPos)
16064
{ this.awaitIdentPos = node.start; }
16065
}
16066
return node
16067
};
16068
16069
pp$5.parsePrivateIdent = function() {
16070
var node = this.startNode();
16071
if (this.type === types$1.privateId) {
16072
node.name = this.value;
16073
} else {
16074
this.unexpected();
16075
}
16076
this.next();
16077
this.finishNode(node, "PrivateIdentifier");
16078
16079
// For validating existence
16080
if (this.privateNameStack.length === 0) {
16081
this.raise(node.start, ("Private field '#" + (node.name) + "' must be declared in an enclosing class"));
16082
} else {
16083
this.privateNameStack[this.privateNameStack.length - 1].used.push(node);
16084
}
16085
16086
return node
16087
};
16088
16089
// Parses yield expression inside generator.
16090
16091
pp$5.parseYield = function(forInit) {
16092
if (!this.yieldPos) { this.yieldPos = this.start; }
16093
16094
var node = this.startNode();
16095
this.next();
16096
if (this.type === types$1.semi || this.canInsertSemicolon() || (this.type !== types$1.star && !this.type.startsExpr)) {
16097
node.delegate = false;
16098
node.argument = null;
16099
} else {
16100
node.delegate = this.eat(types$1.star);
16101
node.argument = this.parseMaybeAssign(forInit);
16102
}
16103
return this.finishNode(node, "YieldExpression")
16104
};
16105
16106
pp$5.parseAwait = function(forInit) {
16107
if (!this.awaitPos) { this.awaitPos = this.start; }
16108
16109
var node = this.startNode();
16110
this.next();
16111
node.argument = this.parseMaybeUnary(null, true, false, forInit);
16112
return this.finishNode(node, "AwaitExpression")
16113
};
16114
16115
var pp$4 = Parser.prototype;
16116
16117
// This function is used to raise exceptions on parse errors. It
16118
// takes an offset integer (into the current `input`) to indicate
16119
// the location of the error, attaches the position to the end
16120
// of the error message, and then raises a `SyntaxError` with that
16121
// message.
16122
16123
pp$4.raise = function(pos, message) {
16124
var loc = getLineInfo(this.input, pos);
16125
message += " (" + loc.line + ":" + loc.column + ")";
16126
var err = new SyntaxError(message);
16127
err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
16128
throw err
16129
};
16130
16131
pp$4.raiseRecoverable = pp$4.raise;
16132
16133
pp$4.curPosition = function() {
16134
if (this.options.locations) {
16135
return new Position(this.curLine, this.pos - this.lineStart)
16136
}
16137
};
16138
16139
var pp$3 = Parser.prototype;
16140
16141
var Scope = function Scope(flags) {
16142
this.flags = flags;
16143
// A list of var-declared names in the current lexical scope
16144
this.var = [];
16145
// A list of lexically-declared names in the current lexical scope
16146
this.lexical = [];
16147
// A list of lexically-declared FunctionDeclaration names in the current lexical scope
16148
this.functions = [];
16149
// A switch to disallow the identifier reference 'arguments'
16150
this.inClassFieldInit = false;
16151
};
16152
16153
// The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
16154
16155
pp$3.enterScope = function(flags) {
16156
this.scopeStack.push(new Scope(flags));
16157
};
16158
16159
pp$3.exitScope = function() {
16160
this.scopeStack.pop();
16161
};
16162
16163
// The spec says:
16164
// > At the top level of a function, or script, function declarations are
16165
// > treated like var declarations rather than like lexical declarations.
16166
pp$3.treatFunctionsAsVarInScope = function(scope) {
16167
return (scope.flags & SCOPE_FUNCTION$1) || !this.inModule && (scope.flags & SCOPE_TOP)
16168
};
16169
16170
pp$3.declareName = function(name, bindingType, pos) {
16171
var redeclared = false;
16172
if (bindingType === BIND_LEXICAL) {
16173
var scope = this.currentScope();
16174
redeclared = scope.lexical.indexOf(name) > -1 || scope.functions.indexOf(name) > -1 || scope.var.indexOf(name) > -1;
16175
scope.lexical.push(name);
16176
if (this.inModule && (scope.flags & SCOPE_TOP))
16177
{ delete this.undefinedExports[name]; }
16178
} else if (bindingType === BIND_SIMPLE_CATCH) {
16179
var scope$1 = this.currentScope();
16180
scope$1.lexical.push(name);
16181
} else if (bindingType === BIND_FUNCTION) {
16182
var scope$2 = this.currentScope();
16183
if (this.treatFunctionsAsVar)
16184
{ redeclared = scope$2.lexical.indexOf(name) > -1; }
16185
else
16186
{ redeclared = scope$2.lexical.indexOf(name) > -1 || scope$2.var.indexOf(name) > -1; }
16187
scope$2.functions.push(name);
16188
} else {
16189
for (var i = this.scopeStack.length - 1; i >= 0; --i) {
16190
var scope$3 = this.scopeStack[i];
16191
if (scope$3.lexical.indexOf(name) > -1 && !((scope$3.flags & SCOPE_SIMPLE_CATCH) && scope$3.lexical[0] === name) ||
16192
!this.treatFunctionsAsVarInScope(scope$3) && scope$3.functions.indexOf(name) > -1) {
16193
redeclared = true;
16194
break
16195
}
16196
scope$3.var.push(name);
16197
if (this.inModule && (scope$3.flags & SCOPE_TOP))
16198
{ delete this.undefinedExports[name]; }
16199
if (scope$3.flags & SCOPE_VAR) { break }
16200
}
16201
}
16202
if (redeclared) { this.raiseRecoverable(pos, ("Identifier '" + name + "' has already been declared")); }
16203
};
16204
16205
pp$3.checkLocalExport = function(id) {
16206
// scope.functions must be empty as Module code is always strict.
16207
if (this.scopeStack[0].lexical.indexOf(id.name) === -1 &&
16208
this.scopeStack[0].var.indexOf(id.name) === -1) {
16209
this.undefinedExports[id.name] = id;
16210
}
16211
};
16212
16213
pp$3.currentScope = function() {
16214
return this.scopeStack[this.scopeStack.length - 1]
16215
};
16216
16217
pp$3.currentVarScope = function() {
16218
for (var i = this.scopeStack.length - 1;; i--) {
16219
var scope = this.scopeStack[i];
16220
if (scope.flags & SCOPE_VAR) { return scope }
16221
}
16222
};
16223
16224
// Could be useful for `this`, `new.target`, `super()`, `super.property`, and `super[property]`.
16225
pp$3.currentThisScope = function() {
16226
for (var i = this.scopeStack.length - 1;; i--) {
16227
var scope = this.scopeStack[i];
16228
if (scope.flags & SCOPE_VAR && !(scope.flags & SCOPE_ARROW)) { return scope }
16229
}
16230
};
16231
16232
var Node$1 = function Node(parser, pos, loc) {
16233
this.type = "";
16234
this.start = pos;
16235
this.end = 0;
16236
if (parser.options.locations)
16237
{ this.loc = new SourceLocation(parser, loc); }
16238
if (parser.options.directSourceFile)
16239
{ this.sourceFile = parser.options.directSourceFile; }
16240
if (parser.options.ranges)
16241
{ this.range = [pos, 0]; }
16242
};
16243
16244
// Start an AST node, attaching a start offset.
16245
16246
var pp$2 = Parser.prototype;
16247
16248
pp$2.startNode = function() {
16249
return new Node$1(this, this.start, this.startLoc)
16250
};
16251
16252
pp$2.startNodeAt = function(pos, loc) {
16253
return new Node$1(this, pos, loc)
16254
};
16255
16256
// Finish an AST node, adding `type` and `end` properties.
16257
16258
function finishNodeAt(node, type, pos, loc) {
16259
node.type = type;
16260
node.end = pos;
16261
if (this.options.locations)
16262
{ node.loc.end = loc; }
16263
if (this.options.ranges)
16264
{ node.range[1] = pos; }
16265
return node
16266
}
16267
16268
pp$2.finishNode = function(node, type) {
16269
return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
16270
};
16271
16272
// Finish node at given position
16273
16274
pp$2.finishNodeAt = function(node, type, pos, loc) {
16275
return finishNodeAt.call(this, node, type, pos, loc)
16276
};
16277
16278
pp$2.copyNode = function(node) {
16279
var newNode = new Node$1(this, node.start, this.startLoc);
16280
for (var prop in node) { newNode[prop] = node[prop]; }
16281
return newNode
16282
};
16283
16284
// This file contains Unicode properties extracted from the ECMAScript
16285
// specification. The lists are extracted like so:
16286
// $$('#table-binary-unicode-properties > figure > table > tbody > tr > td:nth-child(1) code').map(el => el.innerText)
16287
16288
// #table-binary-unicode-properties
16289
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";
16290
var ecma10BinaryProperties = ecma9BinaryProperties + " Extended_Pictographic";
16291
var ecma11BinaryProperties = ecma10BinaryProperties;
16292
var ecma12BinaryProperties = ecma11BinaryProperties + " EBase EComp EMod EPres ExtPict";
16293
var ecma13BinaryProperties = ecma12BinaryProperties;
16294
var unicodeBinaryProperties = {
16295
9: ecma9BinaryProperties,
16296
10: ecma10BinaryProperties,
16297
11: ecma11BinaryProperties,
16298
12: ecma12BinaryProperties,
16299
13: ecma13BinaryProperties
16300
};
16301
16302
// #table-unicode-general-category-values
16303
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";
16304
16305
// #table-unicode-script-values
16306
var ecma9ScriptValues = "Adlam Adlm 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 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";
16307
var ecma10ScriptValues = ecma9ScriptValues + " Dogra Dogr Gunjala_Gondi Gong Hanifi_Rohingya Rohg Makasar Maka Medefaidrin Medf Old_Sogdian Sogo Sogdian Sogd";
16308
var ecma11ScriptValues = ecma10ScriptValues + " Elymaic Elym Nandinagari Nand Nyiakeng_Puachue_Hmong Hmnp Wancho Wcho";
16309
var ecma12ScriptValues = ecma11ScriptValues + " Chorasmian Chrs Diak Dives_Akuru Khitan_Small_Script Kits Yezi Yezidi";
16310
var ecma13ScriptValues = ecma12ScriptValues + " Cypro_Minoan Cpmn Old_Uyghur Ougr Tangsa Tnsa Toto Vithkuqi Vith";
16311
var unicodeScriptValues = {
16312
9: ecma9ScriptValues,
16313
10: ecma10ScriptValues,
16314
11: ecma11ScriptValues,
16315
12: ecma12ScriptValues,
16316
13: ecma13ScriptValues
16317
};
16318
16319
var data = {};
16320
function buildUnicodeData(ecmaVersion) {
16321
var d = data[ecmaVersion] = {
16322
binary: wordsRegexp(unicodeBinaryProperties[ecmaVersion] + " " + unicodeGeneralCategoryValues),
16323
nonBinary: {
16324
General_Category: wordsRegexp(unicodeGeneralCategoryValues),
16325
Script: wordsRegexp(unicodeScriptValues[ecmaVersion])
16326
}
16327
};
16328
d.nonBinary.Script_Extensions = d.nonBinary.Script;
16329
16330
d.nonBinary.gc = d.nonBinary.General_Category;
16331
d.nonBinary.sc = d.nonBinary.Script;
16332
d.nonBinary.scx = d.nonBinary.Script_Extensions;
16333
}
16334
16335
for (var i = 0, list = [9, 10, 11, 12, 13]; i < list.length; i += 1) {
16336
var ecmaVersion = list[i];
16337
16338
buildUnicodeData(ecmaVersion);
16339
}
16340
16341
var pp$1 = Parser.prototype;
16342
16343
var RegExpValidationState = function RegExpValidationState(parser) {
16344
this.parser = parser;
16345
this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "");
16346
this.unicodeProperties = data[parser.options.ecmaVersion >= 13 ? 13 : parser.options.ecmaVersion];
16347
this.source = "";
16348
this.flags = "";
16349
this.start = 0;
16350
this.switchU = false;
16351
this.switchN = false;
16352
this.pos = 0;
16353
this.lastIntValue = 0;
16354
this.lastStringValue = "";
16355
this.lastAssertionIsQuantifiable = false;
16356
this.numCapturingParens = 0;
16357
this.maxBackReference = 0;
16358
this.groupNames = [];
16359
this.backReferenceNames = [];
16360
};
16361
16362
RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
16363
var unicode = flags.indexOf("u") !== -1;
16364
this.start = start | 0;
16365
this.source = pattern + "";
16366
this.flags = flags;
16367
this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
16368
this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
16369
};
16370
16371
RegExpValidationState.prototype.raise = function raise (message) {
16372
this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
16373
};
16374
16375
// If u flag is given, this returns the code point at the index (it combines a surrogate pair).
16376
// Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
16377
RegExpValidationState.prototype.at = function at (i, forceU) {
16378
if ( forceU === void 0 ) forceU = false;
16379
16380
var s = this.source;
16381
var l = s.length;
16382
if (i >= l) {
16383
return -1
16384
}
16385
var c = s.charCodeAt(i);
16386
if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
16387
return c
16388
}
16389
var next = s.charCodeAt(i + 1);
16390
return next >= 0xDC00 && next <= 0xDFFF ? (c << 10) + next - 0x35FDC00 : c
16391
};
16392
16393
RegExpValidationState.prototype.nextIndex = function nextIndex (i, forceU) {
16394
if ( forceU === void 0 ) forceU = false;
16395
16396
var s = this.source;
16397
var l = s.length;
16398
if (i >= l) {
16399
return l
16400
}
16401
var c = s.charCodeAt(i), next;
16402
if (!(forceU || this.switchU) || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l ||
16403
(next = s.charCodeAt(i + 1)) < 0xDC00 || next > 0xDFFF) {
16404
return i + 1
16405
}
16406
return i + 2
16407
};
16408
16409
RegExpValidationState.prototype.current = function current (forceU) {
16410
if ( forceU === void 0 ) forceU = false;
16411
16412
return this.at(this.pos, forceU)
16413
};
16414
16415
RegExpValidationState.prototype.lookahead = function lookahead (forceU) {
16416
if ( forceU === void 0 ) forceU = false;
16417
16418
return this.at(this.nextIndex(this.pos, forceU), forceU)
16419
};
16420
16421
RegExpValidationState.prototype.advance = function advance (forceU) {
16422
if ( forceU === void 0 ) forceU = false;
16423
16424
this.pos = this.nextIndex(this.pos, forceU);
16425
};
16426
16427
RegExpValidationState.prototype.eat = function eat (ch, forceU) {
16428
if ( forceU === void 0 ) forceU = false;
16429
16430
if (this.current(forceU) === ch) {
16431
this.advance(forceU);
16432
return true
16433
}
16434
return false
16435
};
16436
16437
/**
16438
* Validate the flags part of a given RegExpLiteral.
16439
*
16440
* @param {RegExpValidationState} state The state to validate RegExp.
16441
* @returns {void}
16442
*/
16443
pp$1.validateRegExpFlags = function(state) {
16444
var validFlags = state.validFlags;
16445
var flags = state.flags;
16446
16447
for (var i = 0; i < flags.length; i++) {
16448
var flag = flags.charAt(i);
16449
if (validFlags.indexOf(flag) === -1) {
16450
this.raise(state.start, "Invalid regular expression flag");
16451
}
16452
if (flags.indexOf(flag, i + 1) > -1) {
16453
this.raise(state.start, "Duplicate regular expression flag");
16454
}
16455
}
16456
};
16457
16458
/**
16459
* Validate the pattern part of a given RegExpLiteral.
16460
*
16461
* @param {RegExpValidationState} state The state to validate RegExp.
16462
* @returns {void}
16463
*/
16464
pp$1.validateRegExpPattern = function(state) {
16465
this.regexp_pattern(state);
16466
16467
// The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
16468
// parsing contains a |GroupName|, reparse with the goal symbol
16469
// |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
16470
// exception if _P_ did not conform to the grammar, if any elements of _P_
16471
// were not matched by the parse, or if any Early Error conditions exist.
16472
if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
16473
state.switchN = true;
16474
this.regexp_pattern(state);
16475
}
16476
};
16477
16478
// https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
16479
pp$1.regexp_pattern = function(state) {
16480
state.pos = 0;
16481
state.lastIntValue = 0;
16482
state.lastStringValue = "";
16483
state.lastAssertionIsQuantifiable = false;
16484
state.numCapturingParens = 0;
16485
state.maxBackReference = 0;
16486
state.groupNames.length = 0;
16487
state.backReferenceNames.length = 0;
16488
16489
this.regexp_disjunction(state);
16490
16491
if (state.pos !== state.source.length) {
16492
// Make the same messages as V8.
16493
if (state.eat(0x29 /* ) */)) {
16494
state.raise("Unmatched ')'");
16495
}
16496
if (state.eat(0x5D /* ] */) || state.eat(0x7D /* } */)) {
16497
state.raise("Lone quantifier brackets");
16498
}
16499
}
16500
if (state.maxBackReference > state.numCapturingParens) {
16501
state.raise("Invalid escape");
16502
}
16503
for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
16504
var name = list[i];
16505
16506
if (state.groupNames.indexOf(name) === -1) {
16507
state.raise("Invalid named capture referenced");
16508
}
16509
}
16510
};
16511
16512
// https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
16513
pp$1.regexp_disjunction = function(state) {
16514
this.regexp_alternative(state);
16515
while (state.eat(0x7C /* | */)) {
16516
this.regexp_alternative(state);
16517
}
16518
16519
// Make the same message as V8.
16520
if (this.regexp_eatQuantifier(state, true)) {
16521
state.raise("Nothing to repeat");
16522
}
16523
if (state.eat(0x7B /* { */)) {
16524
state.raise("Lone quantifier brackets");
16525
}
16526
};
16527
16528
// https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
16529
pp$1.regexp_alternative = function(state) {
16530
while (state.pos < state.source.length && this.regexp_eatTerm(state))
16531
{ }
16532
};
16533
16534
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
16535
pp$1.regexp_eatTerm = function(state) {
16536
if (this.regexp_eatAssertion(state)) {
16537
// Handle `QuantifiableAssertion Quantifier` alternative.
16538
// `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
16539
// is a QuantifiableAssertion.
16540
if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
16541
// Make the same message as V8.
16542
if (state.switchU) {
16543
state.raise("Invalid quantifier");
16544
}
16545
}
16546
return true
16547
}
16548
16549
if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
16550
this.regexp_eatQuantifier(state);
16551
return true
16552
}
16553
16554
return false
16555
};
16556
16557
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
16558
pp$1.regexp_eatAssertion = function(state) {
16559
var start = state.pos;
16560
state.lastAssertionIsQuantifiable = false;
16561
16562
// ^, $
16563
if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
16564
return true
16565
}
16566
16567
// \b \B
16568
if (state.eat(0x5C /* \ */)) {
16569
if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
16570
return true
16571
}
16572
state.pos = start;
16573
}
16574
16575
// Lookahead / Lookbehind
16576
if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
16577
var lookbehind = false;
16578
if (this.options.ecmaVersion >= 9) {
16579
lookbehind = state.eat(0x3C /* < */);
16580
}
16581
if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
16582
this.regexp_disjunction(state);
16583
if (!state.eat(0x29 /* ) */)) {
16584
state.raise("Unterminated group");
16585
}
16586
state.lastAssertionIsQuantifiable = !lookbehind;
16587
return true
16588
}
16589
}
16590
16591
state.pos = start;
16592
return false
16593
};
16594
16595
// https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
16596
pp$1.regexp_eatQuantifier = function(state, noError) {
16597
if ( noError === void 0 ) noError = false;
16598
16599
if (this.regexp_eatQuantifierPrefix(state, noError)) {
16600
state.eat(0x3F /* ? */);
16601
return true
16602
}
16603
return false
16604
};
16605
16606
// https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
16607
pp$1.regexp_eatQuantifierPrefix = function(state, noError) {
16608
return (
16609
state.eat(0x2A /* * */) ||
16610
state.eat(0x2B /* + */) ||
16611
state.eat(0x3F /* ? */) ||
16612
this.regexp_eatBracedQuantifier(state, noError)
16613
)
16614
};
16615
pp$1.regexp_eatBracedQuantifier = function(state, noError) {
16616
var start = state.pos;
16617
if (state.eat(0x7B /* { */)) {
16618
var min = 0, max = -1;
16619
if (this.regexp_eatDecimalDigits(state)) {
16620
min = state.lastIntValue;
16621
if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
16622
max = state.lastIntValue;
16623
}
16624
if (state.eat(0x7D /* } */)) {
16625
// SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
16626
if (max !== -1 && max < min && !noError) {
16627
state.raise("numbers out of order in {} quantifier");
16628
}
16629
return true
16630
}
16631
}
16632
if (state.switchU && !noError) {
16633
state.raise("Incomplete quantifier");
16634
}
16635
state.pos = start;
16636
}
16637
return false
16638
};
16639
16640
// https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
16641
pp$1.regexp_eatAtom = function(state) {
16642
return (
16643
this.regexp_eatPatternCharacters(state) ||
16644
state.eat(0x2E /* . */) ||
16645
this.regexp_eatReverseSolidusAtomEscape(state) ||
16646
this.regexp_eatCharacterClass(state) ||
16647
this.regexp_eatUncapturingGroup(state) ||
16648
this.regexp_eatCapturingGroup(state)
16649
)
16650
};
16651
pp$1.regexp_eatReverseSolidusAtomEscape = function(state) {
16652
var start = state.pos;
16653
if (state.eat(0x5C /* \ */)) {
16654
if (this.regexp_eatAtomEscape(state)) {
16655
return true
16656
}
16657
state.pos = start;
16658
}
16659
return false
16660
};
16661
pp$1.regexp_eatUncapturingGroup = function(state) {
16662
var start = state.pos;
16663
if (state.eat(0x28 /* ( */)) {
16664
if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
16665
this.regexp_disjunction(state);
16666
if (state.eat(0x29 /* ) */)) {
16667
return true
16668
}
16669
state.raise("Unterminated group");
16670
}
16671
state.pos = start;
16672
}
16673
return false
16674
};
16675
pp$1.regexp_eatCapturingGroup = function(state) {
16676
if (state.eat(0x28 /* ( */)) {
16677
if (this.options.ecmaVersion >= 9) {
16678
this.regexp_groupSpecifier(state);
16679
} else if (state.current() === 0x3F /* ? */) {
16680
state.raise("Invalid group");
16681
}
16682
this.regexp_disjunction(state);
16683
if (state.eat(0x29 /* ) */)) {
16684
state.numCapturingParens += 1;
16685
return true
16686
}
16687
state.raise("Unterminated group");
16688
}
16689
return false
16690
};
16691
16692
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
16693
pp$1.regexp_eatExtendedAtom = function(state) {
16694
return (
16695
state.eat(0x2E /* . */) ||
16696
this.regexp_eatReverseSolidusAtomEscape(state) ||
16697
this.regexp_eatCharacterClass(state) ||
16698
this.regexp_eatUncapturingGroup(state) ||
16699
this.regexp_eatCapturingGroup(state) ||
16700
this.regexp_eatInvalidBracedQuantifier(state) ||
16701
this.regexp_eatExtendedPatternCharacter(state)
16702
)
16703
};
16704
16705
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
16706
pp$1.regexp_eatInvalidBracedQuantifier = function(state) {
16707
if (this.regexp_eatBracedQuantifier(state, true)) {
16708
state.raise("Nothing to repeat");
16709
}
16710
return false
16711
};
16712
16713
// https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
16714
pp$1.regexp_eatSyntaxCharacter = function(state) {
16715
var ch = state.current();
16716
if (isSyntaxCharacter(ch)) {
16717
state.lastIntValue = ch;
16718
state.advance();
16719
return true
16720
}
16721
return false
16722
};
16723
function isSyntaxCharacter(ch) {
16724
return (
16725
ch === 0x24 /* $ */ ||
16726
ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
16727
ch === 0x2E /* . */ ||
16728
ch === 0x3F /* ? */ ||
16729
ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
16730
ch >= 0x7B /* { */ && ch <= 0x7D /* } */
16731
)
16732
}
16733
16734
// https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
16735
// But eat eager.
16736
pp$1.regexp_eatPatternCharacters = function(state) {
16737
var start = state.pos;
16738
var ch = 0;
16739
while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
16740
state.advance();
16741
}
16742
return state.pos !== start
16743
};
16744
16745
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
16746
pp$1.regexp_eatExtendedPatternCharacter = function(state) {
16747
var ch = state.current();
16748
if (
16749
ch !== -1 &&
16750
ch !== 0x24 /* $ */ &&
16751
!(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
16752
ch !== 0x2E /* . */ &&
16753
ch !== 0x3F /* ? */ &&
16754
ch !== 0x5B /* [ */ &&
16755
ch !== 0x5E /* ^ */ &&
16756
ch !== 0x7C /* | */
16757
) {
16758
state.advance();
16759
return true
16760
}
16761
return false
16762
};
16763
16764
// GroupSpecifier ::
16765
// [empty]
16766
// `?` GroupName
16767
pp$1.regexp_groupSpecifier = function(state) {
16768
if (state.eat(0x3F /* ? */)) {
16769
if (this.regexp_eatGroupName(state)) {
16770
if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
16771
state.raise("Duplicate capture group name");
16772
}
16773
state.groupNames.push(state.lastStringValue);
16774
return
16775
}
16776
state.raise("Invalid group");
16777
}
16778
};
16779
16780
// GroupName ::
16781
// `<` RegExpIdentifierName `>`
16782
// Note: this updates `state.lastStringValue` property with the eaten name.
16783
pp$1.regexp_eatGroupName = function(state) {
16784
state.lastStringValue = "";
16785
if (state.eat(0x3C /* < */)) {
16786
if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
16787
return true
16788
}
16789
state.raise("Invalid capture group name");
16790
}
16791
return false
16792
};
16793
16794
// RegExpIdentifierName ::
16795
// RegExpIdentifierStart
16796
// RegExpIdentifierName RegExpIdentifierPart
16797
// Note: this updates `state.lastStringValue` property with the eaten name.
16798
pp$1.regexp_eatRegExpIdentifierName = function(state) {
16799
state.lastStringValue = "";
16800
if (this.regexp_eatRegExpIdentifierStart(state)) {
16801
state.lastStringValue += codePointToString(state.lastIntValue);
16802
while (this.regexp_eatRegExpIdentifierPart(state)) {
16803
state.lastStringValue += codePointToString(state.lastIntValue);
16804
}
16805
return true
16806
}
16807
return false
16808
};
16809
16810
// RegExpIdentifierStart ::
16811
// UnicodeIDStart
16812
// `$`
16813
// `_`
16814
// `\` RegExpUnicodeEscapeSequence[+U]
16815
pp$1.regexp_eatRegExpIdentifierStart = function(state) {
16816
var start = state.pos;
16817
var forceU = this.options.ecmaVersion >= 11;
16818
var ch = state.current(forceU);
16819
state.advance(forceU);
16820
16821
if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
16822
ch = state.lastIntValue;
16823
}
16824
if (isRegExpIdentifierStart(ch)) {
16825
state.lastIntValue = ch;
16826
return true
16827
}
16828
16829
state.pos = start;
16830
return false
16831
};
16832
function isRegExpIdentifierStart(ch) {
16833
return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
16834
}
16835
16836
// RegExpIdentifierPart ::
16837
// UnicodeIDContinue
16838
// `$`
16839
// `_`
16840
// `\` RegExpUnicodeEscapeSequence[+U]
16841
// <ZWNJ>
16842
// <ZWJ>
16843
pp$1.regexp_eatRegExpIdentifierPart = function(state) {
16844
var start = state.pos;
16845
var forceU = this.options.ecmaVersion >= 11;
16846
var ch = state.current(forceU);
16847
state.advance(forceU);
16848
16849
if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state, forceU)) {
16850
ch = state.lastIntValue;
16851
}
16852
if (isRegExpIdentifierPart(ch)) {
16853
state.lastIntValue = ch;
16854
return true
16855
}
16856
16857
state.pos = start;
16858
return false
16859
};
16860
function isRegExpIdentifierPart(ch) {
16861
return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
16862
}
16863
16864
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
16865
pp$1.regexp_eatAtomEscape = function(state) {
16866
if (
16867
this.regexp_eatBackReference(state) ||
16868
this.regexp_eatCharacterClassEscape(state) ||
16869
this.regexp_eatCharacterEscape(state) ||
16870
(state.switchN && this.regexp_eatKGroupName(state))
16871
) {
16872
return true
16873
}
16874
if (state.switchU) {
16875
// Make the same message as V8.
16876
if (state.current() === 0x63 /* c */) {
16877
state.raise("Invalid unicode escape");
16878
}
16879
state.raise("Invalid escape");
16880
}
16881
return false
16882
};
16883
pp$1.regexp_eatBackReference = function(state) {
16884
var start = state.pos;
16885
if (this.regexp_eatDecimalEscape(state)) {
16886
var n = state.lastIntValue;
16887
if (state.switchU) {
16888
// For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
16889
if (n > state.maxBackReference) {
16890
state.maxBackReference = n;
16891
}
16892
return true
16893
}
16894
if (n <= state.numCapturingParens) {
16895
return true
16896
}
16897
state.pos = start;
16898
}
16899
return false
16900
};
16901
pp$1.regexp_eatKGroupName = function(state) {
16902
if (state.eat(0x6B /* k */)) {
16903
if (this.regexp_eatGroupName(state)) {
16904
state.backReferenceNames.push(state.lastStringValue);
16905
return true
16906
}
16907
state.raise("Invalid named reference");
16908
}
16909
return false
16910
};
16911
16912
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
16913
pp$1.regexp_eatCharacterEscape = function(state) {
16914
return (
16915
this.regexp_eatControlEscape(state) ||
16916
this.regexp_eatCControlLetter(state) ||
16917
this.regexp_eatZero(state) ||
16918
this.regexp_eatHexEscapeSequence(state) ||
16919
this.regexp_eatRegExpUnicodeEscapeSequence(state, false) ||
16920
(!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
16921
this.regexp_eatIdentityEscape(state)
16922
)
16923
};
16924
pp$1.regexp_eatCControlLetter = function(state) {
16925
var start = state.pos;
16926
if (state.eat(0x63 /* c */)) {
16927
if (this.regexp_eatControlLetter(state)) {
16928
return true
16929
}
16930
state.pos = start;
16931
}
16932
return false
16933
};
16934
pp$1.regexp_eatZero = function(state) {
16935
if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
16936
state.lastIntValue = 0;
16937
state.advance();
16938
return true
16939
}
16940
return false
16941
};
16942
16943
// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
16944
pp$1.regexp_eatControlEscape = function(state) {
16945
var ch = state.current();
16946
if (ch === 0x74 /* t */) {
16947
state.lastIntValue = 0x09; /* \t */
16948
state.advance();
16949
return true
16950
}
16951
if (ch === 0x6E /* n */) {
16952
state.lastIntValue = 0x0A; /* \n */
16953
state.advance();
16954
return true
16955
}
16956
if (ch === 0x76 /* v */) {
16957
state.lastIntValue = 0x0B; /* \v */
16958
state.advance();
16959
return true
16960
}
16961
if (ch === 0x66 /* f */) {
16962
state.lastIntValue = 0x0C; /* \f */
16963
state.advance();
16964
return true
16965
}
16966
if (ch === 0x72 /* r */) {
16967
state.lastIntValue = 0x0D; /* \r */
16968
state.advance();
16969
return true
16970
}
16971
return false
16972
};
16973
16974
// https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
16975
pp$1.regexp_eatControlLetter = function(state) {
16976
var ch = state.current();
16977
if (isControlLetter(ch)) {
16978
state.lastIntValue = ch % 0x20;
16979
state.advance();
16980
return true
16981
}
16982
return false
16983
};
16984
function isControlLetter(ch) {
16985
return (
16986
(ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
16987
(ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
16988
)
16989
}
16990
16991
// https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
16992
pp$1.regexp_eatRegExpUnicodeEscapeSequence = function(state, forceU) {
16993
if ( forceU === void 0 ) forceU = false;
16994
16995
var start = state.pos;
16996
var switchU = forceU || state.switchU;
16997
16998
if (state.eat(0x75 /* u */)) {
16999
if (this.regexp_eatFixedHexDigits(state, 4)) {
17000
var lead = state.lastIntValue;
17001
if (switchU && lead >= 0xD800 && lead <= 0xDBFF) {
17002
var leadSurrogateEnd = state.pos;
17003
if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
17004
var trail = state.lastIntValue;
17005
if (trail >= 0xDC00 && trail <= 0xDFFF) {
17006
state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
17007
return true
17008
}
17009
}
17010
state.pos = leadSurrogateEnd;
17011
state.lastIntValue = lead;
17012
}
17013
return true
17014
}
17015
if (
17016
switchU &&
17017
state.eat(0x7B /* { */) &&
17018
this.regexp_eatHexDigits(state) &&
17019
state.eat(0x7D /* } */) &&
17020
isValidUnicode(state.lastIntValue)
17021
) {
17022
return true
17023
}
17024
if (switchU) {
17025
state.raise("Invalid unicode escape");
17026
}
17027
state.pos = start;
17028
}
17029
17030
return false
17031
};
17032
function isValidUnicode(ch) {
17033
return ch >= 0 && ch <= 0x10FFFF
17034
}
17035
17036
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
17037
pp$1.regexp_eatIdentityEscape = function(state) {
17038
if (state.switchU) {
17039
if (this.regexp_eatSyntaxCharacter(state)) {
17040
return true
17041
}
17042
if (state.eat(0x2F /* / */)) {
17043
state.lastIntValue = 0x2F; /* / */
17044
return true
17045
}
17046
return false
17047
}
17048
17049
var ch = state.current();
17050
if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
17051
state.lastIntValue = ch;
17052
state.advance();
17053
return true
17054
}
17055
17056
return false
17057
};
17058
17059
// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
17060
pp$1.regexp_eatDecimalEscape = function(state) {
17061
state.lastIntValue = 0;
17062
var ch = state.current();
17063
if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
17064
do {
17065
state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
17066
state.advance();
17067
} while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
17068
return true
17069
}
17070
return false
17071
};
17072
17073
// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
17074
pp$1.regexp_eatCharacterClassEscape = function(state) {
17075
var ch = state.current();
17076
17077
if (isCharacterClassEscape(ch)) {
17078
state.lastIntValue = -1;
17079
state.advance();
17080
return true
17081
}
17082
17083
if (
17084
state.switchU &&
17085
this.options.ecmaVersion >= 9 &&
17086
(ch === 0x50 /* P */ || ch === 0x70 /* p */)
17087
) {
17088
state.lastIntValue = -1;
17089
state.advance();
17090
if (
17091
state.eat(0x7B /* { */) &&
17092
this.regexp_eatUnicodePropertyValueExpression(state) &&
17093
state.eat(0x7D /* } */)
17094
) {
17095
return true
17096
}
17097
state.raise("Invalid property name");
17098
}
17099
17100
return false
17101
};
17102
function isCharacterClassEscape(ch) {
17103
return (
17104
ch === 0x64 /* d */ ||
17105
ch === 0x44 /* D */ ||
17106
ch === 0x73 /* s */ ||
17107
ch === 0x53 /* S */ ||
17108
ch === 0x77 /* w */ ||
17109
ch === 0x57 /* W */
17110
)
17111
}
17112
17113
// UnicodePropertyValueExpression ::
17114
// UnicodePropertyName `=` UnicodePropertyValue
17115
// LoneUnicodePropertyNameOrValue
17116
pp$1.regexp_eatUnicodePropertyValueExpression = function(state) {
17117
var start = state.pos;
17118
17119
// UnicodePropertyName `=` UnicodePropertyValue
17120
if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
17121
var name = state.lastStringValue;
17122
if (this.regexp_eatUnicodePropertyValue(state)) {
17123
var value = state.lastStringValue;
17124
this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
17125
return true
17126
}
17127
}
17128
state.pos = start;
17129
17130
// LoneUnicodePropertyNameOrValue
17131
if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
17132
var nameOrValue = state.lastStringValue;
17133
this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
17134
return true
17135
}
17136
return false
17137
};
17138
pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
17139
if (!hasOwn(state.unicodeProperties.nonBinary, name))
17140
{ state.raise("Invalid property name"); }
17141
if (!state.unicodeProperties.nonBinary[name].test(value))
17142
{ state.raise("Invalid property value"); }
17143
};
17144
pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
17145
if (!state.unicodeProperties.binary.test(nameOrValue))
17146
{ state.raise("Invalid property name"); }
17147
};
17148
17149
// UnicodePropertyName ::
17150
// UnicodePropertyNameCharacters
17151
pp$1.regexp_eatUnicodePropertyName = function(state) {
17152
var ch = 0;
17153
state.lastStringValue = "";
17154
while (isUnicodePropertyNameCharacter(ch = state.current())) {
17155
state.lastStringValue += codePointToString(ch);
17156
state.advance();
17157
}
17158
return state.lastStringValue !== ""
17159
};
17160
function isUnicodePropertyNameCharacter(ch) {
17161
return isControlLetter(ch) || ch === 0x5F /* _ */
17162
}
17163
17164
// UnicodePropertyValue ::
17165
// UnicodePropertyValueCharacters
17166
pp$1.regexp_eatUnicodePropertyValue = function(state) {
17167
var ch = 0;
17168
state.lastStringValue = "";
17169
while (isUnicodePropertyValueCharacter(ch = state.current())) {
17170
state.lastStringValue += codePointToString(ch);
17171
state.advance();
17172
}
17173
return state.lastStringValue !== ""
17174
};
17175
function isUnicodePropertyValueCharacter(ch) {
17176
return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
17177
}
17178
17179
// LoneUnicodePropertyNameOrValue ::
17180
// UnicodePropertyValueCharacters
17181
pp$1.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
17182
return this.regexp_eatUnicodePropertyValue(state)
17183
};
17184
17185
// https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
17186
pp$1.regexp_eatCharacterClass = function(state) {
17187
if (state.eat(0x5B /* [ */)) {
17188
state.eat(0x5E /* ^ */);
17189
this.regexp_classRanges(state);
17190
if (state.eat(0x5D /* ] */)) {
17191
return true
17192
}
17193
// Unreachable since it threw "unterminated regular expression" error before.
17194
state.raise("Unterminated character class");
17195
}
17196
return false
17197
};
17198
17199
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
17200
// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
17201
// https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
17202
pp$1.regexp_classRanges = function(state) {
17203
while (this.regexp_eatClassAtom(state)) {
17204
var left = state.lastIntValue;
17205
if (state.eat(0x2D /* - */) && this.regexp_eatClassAtom(state)) {
17206
var right = state.lastIntValue;
17207
if (state.switchU && (left === -1 || right === -1)) {
17208
state.raise("Invalid character class");
17209
}
17210
if (left !== -1 && right !== -1 && left > right) {
17211
state.raise("Range out of order in character class");
17212
}
17213
}
17214
}
17215
};
17216
17217
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
17218
// https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
17219
pp$1.regexp_eatClassAtom = function(state) {
17220
var start = state.pos;
17221
17222
if (state.eat(0x5C /* \ */)) {
17223
if (this.regexp_eatClassEscape(state)) {
17224
return true
17225
}
17226
if (state.switchU) {
17227
// Make the same message as V8.
17228
var ch$1 = state.current();
17229
if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
17230
state.raise("Invalid class escape");
17231
}
17232
state.raise("Invalid escape");
17233
}
17234
state.pos = start;
17235
}
17236
17237
var ch = state.current();
17238
if (ch !== 0x5D /* ] */) {
17239
state.lastIntValue = ch;
17240
state.advance();
17241
return true
17242
}
17243
17244
return false
17245
};
17246
17247
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
17248
pp$1.regexp_eatClassEscape = function(state) {
17249
var start = state.pos;
17250
17251
if (state.eat(0x62 /* b */)) {
17252
state.lastIntValue = 0x08; /* <BS> */
17253
return true
17254
}
17255
17256
if (state.switchU && state.eat(0x2D /* - */)) {
17257
state.lastIntValue = 0x2D; /* - */
17258
return true
17259
}
17260
17261
if (!state.switchU && state.eat(0x63 /* c */)) {
17262
if (this.regexp_eatClassControlLetter(state)) {
17263
return true
17264
}
17265
state.pos = start;
17266
}
17267
17268
return (
17269
this.regexp_eatCharacterClassEscape(state) ||
17270
this.regexp_eatCharacterEscape(state)
17271
)
17272
};
17273
17274
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
17275
pp$1.regexp_eatClassControlLetter = function(state) {
17276
var ch = state.current();
17277
if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
17278
state.lastIntValue = ch % 0x20;
17279
state.advance();
17280
return true
17281
}
17282
return false
17283
};
17284
17285
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
17286
pp$1.regexp_eatHexEscapeSequence = function(state) {
17287
var start = state.pos;
17288
if (state.eat(0x78 /* x */)) {
17289
if (this.regexp_eatFixedHexDigits(state, 2)) {
17290
return true
17291
}
17292
if (state.switchU) {
17293
state.raise("Invalid escape");
17294
}
17295
state.pos = start;
17296
}
17297
return false
17298
};
17299
17300
// https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
17301
pp$1.regexp_eatDecimalDigits = function(state) {
17302
var start = state.pos;
17303
var ch = 0;
17304
state.lastIntValue = 0;
17305
while (isDecimalDigit(ch = state.current())) {
17306
state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
17307
state.advance();
17308
}
17309
return state.pos !== start
17310
};
17311
function isDecimalDigit(ch) {
17312
return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
17313
}
17314
17315
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
17316
pp$1.regexp_eatHexDigits = function(state) {
17317
var start = state.pos;
17318
var ch = 0;
17319
state.lastIntValue = 0;
17320
while (isHexDigit(ch = state.current())) {
17321
state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
17322
state.advance();
17323
}
17324
return state.pos !== start
17325
};
17326
function isHexDigit(ch) {
17327
return (
17328
(ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
17329
(ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
17330
(ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
17331
)
17332
}
17333
function hexToInt(ch) {
17334
if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
17335
return 10 + (ch - 0x41 /* A */)
17336
}
17337
if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
17338
return 10 + (ch - 0x61 /* a */)
17339
}
17340
return ch - 0x30 /* 0 */
17341
}
17342
17343
// https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
17344
// Allows only 0-377(octal) i.e. 0-255(decimal).
17345
pp$1.regexp_eatLegacyOctalEscapeSequence = function(state) {
17346
if (this.regexp_eatOctalDigit(state)) {
17347
var n1 = state.lastIntValue;
17348
if (this.regexp_eatOctalDigit(state)) {
17349
var n2 = state.lastIntValue;
17350
if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
17351
state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
17352
} else {
17353
state.lastIntValue = n1 * 8 + n2;
17354
}
17355
} else {
17356
state.lastIntValue = n1;
17357
}
17358
return true
17359
}
17360
return false
17361
};
17362
17363
// https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
17364
pp$1.regexp_eatOctalDigit = function(state) {
17365
var ch = state.current();
17366
if (isOctalDigit(ch)) {
17367
state.lastIntValue = ch - 0x30; /* 0 */
17368
state.advance();
17369
return true
17370
}
17371
state.lastIntValue = 0;
17372
return false
17373
};
17374
function isOctalDigit(ch) {
17375
return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
17376
}
17377
17378
// https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
17379
// https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
17380
// And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
17381
pp$1.regexp_eatFixedHexDigits = function(state, length) {
17382
var start = state.pos;
17383
state.lastIntValue = 0;
17384
for (var i = 0; i < length; ++i) {
17385
var ch = state.current();
17386
if (!isHexDigit(ch)) {
17387
state.pos = start;
17388
return false
17389
}
17390
state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
17391
state.advance();
17392
}
17393
return true
17394
};
17395
17396
// Object type used to represent tokens. Note that normally, tokens
17397
// simply exist as properties on the parser object. This is only
17398
// used for the onToken callback and the external tokenizer.
17399
17400
var Token = function Token(p) {
17401
this.type = p.type;
17402
this.value = p.value;
17403
this.start = p.start;
17404
this.end = p.end;
17405
if (p.options.locations)
17406
{ this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
17407
if (p.options.ranges)
17408
{ this.range = [p.start, p.end]; }
17409
};
17410
17411
// ## Tokenizer
17412
17413
var pp = Parser.prototype;
17414
17415
// Move to the next token
17416
17417
pp.next = function(ignoreEscapeSequenceInKeyword) {
17418
if (!ignoreEscapeSequenceInKeyword && this.type.keyword && this.containsEsc)
17419
{ this.raiseRecoverable(this.start, "Escape sequence in keyword " + this.type.keyword); }
17420
if (this.options.onToken)
17421
{ this.options.onToken(new Token(this)); }
17422
17423
this.lastTokEnd = this.end;
17424
this.lastTokStart = this.start;
17425
this.lastTokEndLoc = this.endLoc;
17426
this.lastTokStartLoc = this.startLoc;
17427
this.nextToken();
17428
};
17429
17430
pp.getToken = function() {
17431
this.next();
17432
return new Token(this)
17433
};
17434
17435
// If we're in an ES6 environment, make parsers iterable
17436
if (typeof Symbol !== "undefined")
17437
{ pp[Symbol.iterator] = function() {
17438
var this$1$1 = this;
17439
17440
return {
17441
next: function () {
17442
var token = this$1$1.getToken();
17443
return {
17444
done: token.type === types$1.eof,
17445
value: token
17446
}
17447
}
17448
}
17449
}; }
17450
17451
// Toggle strict mode. Re-reads the next number or string to please
17452
// pedantic tests (`"use strict"; 010;` should fail).
17453
17454
// Read a single token, updating the parser object's token-related
17455
// properties.
17456
17457
pp.nextToken = function() {
17458
var curContext = this.curContext();
17459
if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
17460
17461
this.start = this.pos;
17462
if (this.options.locations) { this.startLoc = this.curPosition(); }
17463
if (this.pos >= this.input.length) { return this.finishToken(types$1.eof) }
17464
17465
if (curContext.override) { return curContext.override(this) }
17466
else { this.readToken(this.fullCharCodeAtPos()); }
17467
};
17468
17469
pp.readToken = function(code) {
17470
// Identifier or keyword. '\uXXXX' sequences are allowed in
17471
// identifiers, so '\' also dispatches to that.
17472
if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
17473
{ return this.readWord() }
17474
17475
return this.getTokenFromCode(code)
17476
};
17477
17478
pp.fullCharCodeAtPos = function() {
17479
var code = this.input.charCodeAt(this.pos);
17480
if (code <= 0xd7ff || code >= 0xdc00) { return code }
17481
var next = this.input.charCodeAt(this.pos + 1);
17482
return next <= 0xdbff || next >= 0xe000 ? code : (code << 10) + next - 0x35fdc00
17483
};
17484
17485
pp.skipBlockComment = function() {
17486
var startLoc = this.options.onComment && this.curPosition();
17487
var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
17488
if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
17489
this.pos = end + 2;
17490
if (this.options.locations) {
17491
for (var nextBreak = (void 0), pos = start; (nextBreak = nextLineBreak(this.input, pos, this.pos)) > -1;) {
17492
++this.curLine;
17493
pos = this.lineStart = nextBreak;
17494
}
17495
}
17496
if (this.options.onComment)
17497
{ this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
17498
startLoc, this.curPosition()); }
17499
};
17500
17501
pp.skipLineComment = function(startSkip) {
17502
var start = this.pos;
17503
var startLoc = this.options.onComment && this.curPosition();
17504
var ch = this.input.charCodeAt(this.pos += startSkip);
17505
while (this.pos < this.input.length && !isNewLine(ch)) {
17506
ch = this.input.charCodeAt(++this.pos);
17507
}
17508
if (this.options.onComment)
17509
{ this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
17510
startLoc, this.curPosition()); }
17511
};
17512
17513
// Called at the start of the parse and after every token. Skips
17514
// whitespace and comments, and.
17515
17516
pp.skipSpace = function() {
17517
loop: while (this.pos < this.input.length) {
17518
var ch = this.input.charCodeAt(this.pos);
17519
switch (ch) {
17520
case 32: case 160: // ' '
17521
++this.pos;
17522
break
17523
case 13:
17524
if (this.input.charCodeAt(this.pos + 1) === 10) {
17525
++this.pos;
17526
}
17527
case 10: case 8232: case 8233:
17528
++this.pos;
17529
if (this.options.locations) {
17530
++this.curLine;
17531
this.lineStart = this.pos;
17532
}
17533
break
17534
case 47: // '/'
17535
switch (this.input.charCodeAt(this.pos + 1)) {
17536
case 42: // '*'
17537
this.skipBlockComment();
17538
break
17539
case 47:
17540
this.skipLineComment(2);
17541
break
17542
default:
17543
break loop
17544
}
17545
break
17546
default:
17547
if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
17548
++this.pos;
17549
} else {
17550
break loop
17551
}
17552
}
17553
}
17554
};
17555
17556
// Called at the end of every token. Sets `end`, `val`, and
17557
// maintains `context` and `exprAllowed`, and skips the space after
17558
// the token, so that the next one's `start` will point at the
17559
// right position.
17560
17561
pp.finishToken = function(type, val) {
17562
this.end = this.pos;
17563
if (this.options.locations) { this.endLoc = this.curPosition(); }
17564
var prevType = this.type;
17565
this.type = type;
17566
this.value = val;
17567
17568
this.updateContext(prevType);
17569
};
17570
17571
// ### Token reading
17572
17573
// This is the function that is called to fetch the next token. It
17574
// is somewhat obscure, because it works in character codes rather
17575
// than characters, and because operator parsing has been inlined
17576
// into it.
17577
//
17578
// All in the name of speed.
17579
//
17580
pp.readToken_dot = function() {
17581
var next = this.input.charCodeAt(this.pos + 1);
17582
if (next >= 48 && next <= 57) { return this.readNumber(true) }
17583
var next2 = this.input.charCodeAt(this.pos + 2);
17584
if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
17585
this.pos += 3;
17586
return this.finishToken(types$1.ellipsis)
17587
} else {
17588
++this.pos;
17589
return this.finishToken(types$1.dot)
17590
}
17591
};
17592
17593
pp.readToken_slash = function() { // '/'
17594
var next = this.input.charCodeAt(this.pos + 1);
17595
if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
17596
if (next === 61) { return this.finishOp(types$1.assign, 2) }
17597
return this.finishOp(types$1.slash, 1)
17598
};
17599
17600
pp.readToken_mult_modulo_exp = function(code) { // '%*'
17601
var next = this.input.charCodeAt(this.pos + 1);
17602
var size = 1;
17603
var tokentype = code === 42 ? types$1.star : types$1.modulo;
17604
17605
// exponentiation operator ** and **=
17606
if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
17607
++size;
17608
tokentype = types$1.starstar;
17609
next = this.input.charCodeAt(this.pos + 2);
17610
}
17611
17612
if (next === 61) { return this.finishOp(types$1.assign, size + 1) }
17613
return this.finishOp(tokentype, size)
17614
};
17615
17616
pp.readToken_pipe_amp = function(code) { // '|&'
17617
var next = this.input.charCodeAt(this.pos + 1);
17618
if (next === code) {
17619
if (this.options.ecmaVersion >= 12) {
17620
var next2 = this.input.charCodeAt(this.pos + 2);
17621
if (next2 === 61) { return this.finishOp(types$1.assign, 3) }
17622
}
17623
return this.finishOp(code === 124 ? types$1.logicalOR : types$1.logicalAND, 2)
17624
}
17625
if (next === 61) { return this.finishOp(types$1.assign, 2) }
17626
return this.finishOp(code === 124 ? types$1.bitwiseOR : types$1.bitwiseAND, 1)
17627
};
17628
17629
pp.readToken_caret = function() { // '^'
17630
var next = this.input.charCodeAt(this.pos + 1);
17631
if (next === 61) { return this.finishOp(types$1.assign, 2) }
17632
return this.finishOp(types$1.bitwiseXOR, 1)
17633
};
17634
17635
pp.readToken_plus_min = function(code) { // '+-'
17636
var next = this.input.charCodeAt(this.pos + 1);
17637
if (next === code) {
17638
if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
17639
(this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
17640
// A `-->` line comment
17641
this.skipLineComment(3);
17642
this.skipSpace();
17643
return this.nextToken()
17644
}
17645
return this.finishOp(types$1.incDec, 2)
17646
}
17647
if (next === 61) { return this.finishOp(types$1.assign, 2) }
17648
return this.finishOp(types$1.plusMin, 1)
17649
};
17650
17651
pp.readToken_lt_gt = function(code) { // '<>'
17652
var next = this.input.charCodeAt(this.pos + 1);
17653
var size = 1;
17654
if (next === code) {
17655
size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
17656
if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types$1.assign, size + 1) }
17657
return this.finishOp(types$1.bitShift, size)
17658
}
17659
if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
17660
this.input.charCodeAt(this.pos + 3) === 45) {
17661
// `<!--`, an XML-style comment that should be interpreted as a line comment
17662
this.skipLineComment(4);
17663
this.skipSpace();
17664
return this.nextToken()
17665
}
17666
if (next === 61) { size = 2; }
17667
return this.finishOp(types$1.relational, size)
17668
};
17669
17670
pp.readToken_eq_excl = function(code) { // '=!'
17671
var next = this.input.charCodeAt(this.pos + 1);
17672
if (next === 61) { return this.finishOp(types$1.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
17673
if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
17674
this.pos += 2;
17675
return this.finishToken(types$1.arrow)
17676
}
17677
return this.finishOp(code === 61 ? types$1.eq : types$1.prefix, 1)
17678
};
17679
17680
pp.readToken_question = function() { // '?'
17681
var ecmaVersion = this.options.ecmaVersion;
17682
if (ecmaVersion >= 11) {
17683
var next = this.input.charCodeAt(this.pos + 1);
17684
if (next === 46) {
17685
var next2 = this.input.charCodeAt(this.pos + 2);
17686
if (next2 < 48 || next2 > 57) { return this.finishOp(types$1.questionDot, 2) }
17687
}
17688
if (next === 63) {
17689
if (ecmaVersion >= 12) {
17690
var next2$1 = this.input.charCodeAt(this.pos + 2);
17691
if (next2$1 === 61) { return this.finishOp(types$1.assign, 3) }
17692
}
17693
return this.finishOp(types$1.coalesce, 2)
17694
}
17695
}
17696
return this.finishOp(types$1.question, 1)
17697
};
17698
17699
pp.readToken_numberSign = function() { // '#'
17700
var ecmaVersion = this.options.ecmaVersion;
17701
var code = 35; // '#'
17702
if (ecmaVersion >= 13) {
17703
++this.pos;
17704
code = this.fullCharCodeAtPos();
17705
if (isIdentifierStart(code, true) || code === 92 /* '\' */) {
17706
return this.finishToken(types$1.privateId, this.readWord1())
17707
}
17708
}
17709
17710
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
17711
};
17712
17713
pp.getTokenFromCode = function(code) {
17714
switch (code) {
17715
// The interpretation of a dot depends on whether it is followed
17716
// by a digit or another two dots.
17717
case 46: // '.'
17718
return this.readToken_dot()
17719
17720
// Punctuation tokens.
17721
case 40: ++this.pos; return this.finishToken(types$1.parenL)
17722
case 41: ++this.pos; return this.finishToken(types$1.parenR)
17723
case 59: ++this.pos; return this.finishToken(types$1.semi)
17724
case 44: ++this.pos; return this.finishToken(types$1.comma)
17725
case 91: ++this.pos; return this.finishToken(types$1.bracketL)
17726
case 93: ++this.pos; return this.finishToken(types$1.bracketR)
17727
case 123: ++this.pos; return this.finishToken(types$1.braceL)
17728
case 125: ++this.pos; return this.finishToken(types$1.braceR)
17729
case 58: ++this.pos; return this.finishToken(types$1.colon)
17730
17731
case 96: // '`'
17732
if (this.options.ecmaVersion < 6) { break }
17733
++this.pos;
17734
return this.finishToken(types$1.backQuote)
17735
17736
case 48: // '0'
17737
var next = this.input.charCodeAt(this.pos + 1);
17738
if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
17739
if (this.options.ecmaVersion >= 6) {
17740
if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
17741
if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
17742
}
17743
17744
// Anything else beginning with a digit is an integer, octal
17745
// number, or float.
17746
case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
17747
return this.readNumber(false)
17748
17749
// Quotes produce strings.
17750
case 34: case 39: // '"', "'"
17751
return this.readString(code)
17752
17753
// Operators are parsed inline in tiny state machines. '=' (61) is
17754
// often referred to. `finishOp` simply skips the amount of
17755
// characters it is given as second argument, and returns a token
17756
// of the type given by its first argument.
17757
case 47: // '/'
17758
return this.readToken_slash()
17759
17760
case 37: case 42: // '%*'
17761
return this.readToken_mult_modulo_exp(code)
17762
17763
case 124: case 38: // '|&'
17764
return this.readToken_pipe_amp(code)
17765
17766
case 94: // '^'
17767
return this.readToken_caret()
17768
17769
case 43: case 45: // '+-'
17770
return this.readToken_plus_min(code)
17771
17772
case 60: case 62: // '<>'
17773
return this.readToken_lt_gt(code)
17774
17775
case 61: case 33: // '=!'
17776
return this.readToken_eq_excl(code)
17777
17778
case 63: // '?'
17779
return this.readToken_question()
17780
17781
case 126: // '~'
17782
return this.finishOp(types$1.prefix, 1)
17783
17784
case 35: // '#'
17785
return this.readToken_numberSign()
17786
}
17787
17788
this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
17789
};
17790
17791
pp.finishOp = function(type, size) {
17792
var str = this.input.slice(this.pos, this.pos + size);
17793
this.pos += size;
17794
return this.finishToken(type, str)
17795
};
17796
17797
pp.readRegexp = function() {
17798
var escaped, inClass, start = this.pos;
17799
for (;;) {
17800
if (this.pos >= this.input.length) { this.raise(start, "Unterminated regular expression"); }
17801
var ch = this.input.charAt(this.pos);
17802
if (lineBreak.test(ch)) { this.raise(start, "Unterminated regular expression"); }
17803
if (!escaped) {
17804
if (ch === "[") { inClass = true; }
17805
else if (ch === "]" && inClass) { inClass = false; }
17806
else if (ch === "/" && !inClass) { break }
17807
escaped = ch === "\\";
17808
} else { escaped = false; }
17809
++this.pos;
17810
}
17811
var pattern = this.input.slice(start, this.pos);
17812
++this.pos;
17813
var flagsStart = this.pos;
17814
var flags = this.readWord1();
17815
if (this.containsEsc) { this.unexpected(flagsStart); }
17816
17817
// Validate pattern
17818
var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
17819
state.reset(start, pattern, flags);
17820
this.validateRegExpFlags(state);
17821
this.validateRegExpPattern(state);
17822
17823
// Create Literal#value property value.
17824
var value = null;
17825
try {
17826
value = new RegExp(pattern, flags);
17827
} catch (e) {
17828
// ESTree requires null if it failed to instantiate RegExp object.
17829
// https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
17830
}
17831
17832
return this.finishToken(types$1.regexp, {pattern: pattern, flags: flags, value: value})
17833
};
17834
17835
// Read an integer in the given radix. Return null if zero digits
17836
// were read, the integer value otherwise. When `len` is given, this
17837
// will return `null` unless the integer has exactly `len` digits.
17838
17839
pp.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
17840
// `len` is used for character escape sequences. In that case, disallow separators.
17841
var allowSeparators = this.options.ecmaVersion >= 12 && len === undefined;
17842
17843
// `maybeLegacyOctalNumericLiteral` is true if it doesn't have prefix (0x,0o,0b)
17844
// and isn't fraction part nor exponent part. In that case, if the first digit
17845
// is zero then disallow separators.
17846
var isLegacyOctalNumericLiteral = maybeLegacyOctalNumericLiteral && this.input.charCodeAt(this.pos) === 48;
17847
17848
var start = this.pos, total = 0, lastCode = 0;
17849
for (var i = 0, e = len == null ? Infinity : len; i < e; ++i, ++this.pos) {
17850
var code = this.input.charCodeAt(this.pos), val = (void 0);
17851
17852
if (allowSeparators && code === 95) {
17853
if (isLegacyOctalNumericLiteral) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed in legacy octal numeric literals"); }
17854
if (lastCode === 95) { this.raiseRecoverable(this.pos, "Numeric separator must be exactly one underscore"); }
17855
if (i === 0) { this.raiseRecoverable(this.pos, "Numeric separator is not allowed at the first of digits"); }
17856
lastCode = code;
17857
continue
17858
}
17859
17860
if (code >= 97) { val = code - 97 + 10; } // a
17861
else if (code >= 65) { val = code - 65 + 10; } // A
17862
else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
17863
else { val = Infinity; }
17864
if (val >= radix) { break }
17865
lastCode = code;
17866
total = total * radix + val;
17867
}
17868
17869
if (allowSeparators && lastCode === 95) { this.raiseRecoverable(this.pos - 1, "Numeric separator is not allowed at the last of digits"); }
17870
if (this.pos === start || len != null && this.pos - start !== len) { return null }
17871
17872
return total
17873
};
17874
17875
function stringToNumber(str, isLegacyOctalNumericLiteral) {
17876
if (isLegacyOctalNumericLiteral) {
17877
return parseInt(str, 8)
17878
}
17879
17880
// `parseFloat(value)` stops parsing at the first numeric separator then returns a wrong value.
17881
return parseFloat(str.replace(/_/g, ""))
17882
}
17883
17884
function stringToBigInt(str) {
17885
if (typeof BigInt !== "function") {
17886
return null
17887
}
17888
17889
// `BigInt(value)` throws syntax error if the string contains numeric separators.
17890
return BigInt(str.replace(/_/g, ""))
17891
}
17892
17893
pp.readRadixNumber = function(radix) {
17894
var start = this.pos;
17895
this.pos += 2; // 0x
17896
var val = this.readInt(radix);
17897
if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
17898
if (this.options.ecmaVersion >= 11 && this.input.charCodeAt(this.pos) === 110) {
17899
val = stringToBigInt(this.input.slice(start, this.pos));
17900
++this.pos;
17901
} else if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
17902
return this.finishToken(types$1.num, val)
17903
};
17904
17905
// Read an integer, octal integer, or floating-point number.
17906
17907
pp.readNumber = function(startsWithDot) {
17908
var start = this.pos;
17909
if (!startsWithDot && this.readInt(10, undefined, true) === null) { this.raise(start, "Invalid number"); }
17910
var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
17911
if (octal && this.strict) { this.raise(start, "Invalid number"); }
17912
var next = this.input.charCodeAt(this.pos);
17913
if (!octal && !startsWithDot && this.options.ecmaVersion >= 11 && next === 110) {
17914
var val$1 = stringToBigInt(this.input.slice(start, this.pos));
17915
++this.pos;
17916
if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
17917
return this.finishToken(types$1.num, val$1)
17918
}
17919
if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
17920
if (next === 46 && !octal) { // '.'
17921
++this.pos;
17922
this.readInt(10);
17923
next = this.input.charCodeAt(this.pos);
17924
}
17925
if ((next === 69 || next === 101) && !octal) { // 'eE'
17926
next = this.input.charCodeAt(++this.pos);
17927
if (next === 43 || next === 45) { ++this.pos; } // '+-'
17928
if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
17929
}
17930
if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
17931
17932
var val = stringToNumber(this.input.slice(start, this.pos), octal);
17933
return this.finishToken(types$1.num, val)
17934
};
17935
17936
// Read a string value, interpreting backslash-escapes.
17937
17938
pp.readCodePoint = function() {
17939
var ch = this.input.charCodeAt(this.pos), code;
17940
17941
if (ch === 123) { // '{'
17942
if (this.options.ecmaVersion < 6) { this.unexpected(); }
17943
var codePos = ++this.pos;
17944
code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
17945
++this.pos;
17946
if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
17947
} else {
17948
code = this.readHexChar(4);
17949
}
17950
return code
17951
};
17952
17953
pp.readString = function(quote) {
17954
var out = "", chunkStart = ++this.pos;
17955
for (;;) {
17956
if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated string constant"); }
17957
var ch = this.input.charCodeAt(this.pos);
17958
if (ch === quote) { break }
17959
if (ch === 92) { // '\'
17960
out += this.input.slice(chunkStart, this.pos);
17961
out += this.readEscapedChar(false);
17962
chunkStart = this.pos;
17963
} else if (ch === 0x2028 || ch === 0x2029) {
17964
if (this.options.ecmaVersion < 10) { this.raise(this.start, "Unterminated string constant"); }
17965
++this.pos;
17966
if (this.options.locations) {
17967
this.curLine++;
17968
this.lineStart = this.pos;
17969
}
17970
} else {
17971
if (isNewLine(ch)) { this.raise(this.start, "Unterminated string constant"); }
17972
++this.pos;
17973
}
17974
}
17975
out += this.input.slice(chunkStart, this.pos++);
17976
return this.finishToken(types$1.string, out)
17977
};
17978
17979
// Reads template string tokens.
17980
17981
var INVALID_TEMPLATE_ESCAPE_ERROR = {};
17982
17983
pp.tryReadTemplateToken = function() {
17984
this.inTemplateElement = true;
17985
try {
17986
this.readTmplToken();
17987
} catch (err) {
17988
if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
17989
this.readInvalidTemplateToken();
17990
} else {
17991
throw err
17992
}
17993
}
17994
17995
this.inTemplateElement = false;
17996
};
17997
17998
pp.invalidStringToken = function(position, message) {
17999
if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
18000
throw INVALID_TEMPLATE_ESCAPE_ERROR
18001
} else {
18002
this.raise(position, message);
18003
}
18004
};
18005
18006
pp.readTmplToken = function() {
18007
var out = "", chunkStart = this.pos;
18008
for (;;) {
18009
if (this.pos >= this.input.length) { this.raise(this.start, "Unterminated template"); }
18010
var ch = this.input.charCodeAt(this.pos);
18011
if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) { // '`', '${'
18012
if (this.pos === this.start && (this.type === types$1.template || this.type === types$1.invalidTemplate)) {
18013
if (ch === 36) {
18014
this.pos += 2;
18015
return this.finishToken(types$1.dollarBraceL)
18016
} else {
18017
++this.pos;
18018
return this.finishToken(types$1.backQuote)
18019
}
18020
}
18021
out += this.input.slice(chunkStart, this.pos);
18022
return this.finishToken(types$1.template, out)
18023
}
18024
if (ch === 92) { // '\'
18025
out += this.input.slice(chunkStart, this.pos);
18026
out += this.readEscapedChar(true);
18027
chunkStart = this.pos;
18028
} else if (isNewLine(ch)) {
18029
out += this.input.slice(chunkStart, this.pos);
18030
++this.pos;
18031
switch (ch) {
18032
case 13:
18033
if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; }
18034
case 10:
18035
out += "\n";
18036
break
18037
default:
18038
out += String.fromCharCode(ch);
18039
break
18040
}
18041
if (this.options.locations) {
18042
++this.curLine;
18043
this.lineStart = this.pos;
18044
}
18045
chunkStart = this.pos;
18046
} else {
18047
++this.pos;
18048
}
18049
}
18050
};
18051
18052
// Reads a template token to search for the end, without validating any escape sequences
18053
pp.readInvalidTemplateToken = function() {
18054
for (; this.pos < this.input.length; this.pos++) {
18055
switch (this.input[this.pos]) {
18056
case "\\":
18057
++this.pos;
18058
break
18059
18060
case "$":
18061
if (this.input[this.pos + 1] !== "{") {
18062
break
18063
}
18064
18065
// falls through
18066
case "`":
18067
return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos))
18068
18069
// no default
18070
}
18071
}
18072
this.raise(this.start, "Unterminated template");
18073
};
18074
18075
// Used to read escaped characters
18076
18077
pp.readEscapedChar = function(inTemplate) {
18078
var ch = this.input.charCodeAt(++this.pos);
18079
++this.pos;
18080
switch (ch) {
18081
case 110: return "\n" // 'n' -> '\n'
18082
case 114: return "\r" // 'r' -> '\r'
18083
case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
18084
case 117: return codePointToString(this.readCodePoint()) // 'u'
18085
case 116: return "\t" // 't' -> '\t'
18086
case 98: return "\b" // 'b' -> '\b'
18087
case 118: return "\u000b" // 'v' -> '\u000b'
18088
case 102: return "\f" // 'f' -> '\f'
18089
case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
18090
case 10: // ' \n'
18091
if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
18092
return ""
18093
case 56:
18094
case 57:
18095
if (this.strict) {
18096
this.invalidStringToken(
18097
this.pos - 1,
18098
"Invalid escape sequence"
18099
);
18100
}
18101
if (inTemplate) {
18102
var codePos = this.pos - 1;
18103
18104
this.invalidStringToken(
18105
codePos,
18106
"Invalid escape sequence in template string"
18107
);
18108
18109
return null
18110
}
18111
default:
18112
if (ch >= 48 && ch <= 55) {
18113
var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
18114
var octal = parseInt(octalStr, 8);
18115
if (octal > 255) {
18116
octalStr = octalStr.slice(0, -1);
18117
octal = parseInt(octalStr, 8);
18118
}
18119
this.pos += octalStr.length - 1;
18120
ch = this.input.charCodeAt(this.pos);
18121
if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
18122
this.invalidStringToken(
18123
this.pos - 1 - octalStr.length,
18124
inTemplate
18125
? "Octal literal in template string"
18126
: "Octal literal in strict mode"
18127
);
18128
}
18129
return String.fromCharCode(octal)
18130
}
18131
if (isNewLine(ch)) {
18132
// Unicode new line characters after \ get removed from output in both
18133
// template literals and strings
18134
return ""
18135
}
18136
return String.fromCharCode(ch)
18137
}
18138
};
18139
18140
// Used to read character escape sequences ('\x', '\u', '\U').
18141
18142
pp.readHexChar = function(len) {
18143
var codePos = this.pos;
18144
var n = this.readInt(16, len);
18145
if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
18146
return n
18147
};
18148
18149
// Read an identifier, and return it as a string. Sets `this.containsEsc`
18150
// to whether the word contained a '\u' escape.
18151
//
18152
// Incrementally adds only escaped chars, adding other chunks as-is
18153
// as a micro-optimization.
18154
18155
pp.readWord1 = function() {
18156
this.containsEsc = false;
18157
var word = "", first = true, chunkStart = this.pos;
18158
var astral = this.options.ecmaVersion >= 6;
18159
while (this.pos < this.input.length) {
18160
var ch = this.fullCharCodeAtPos();
18161
if (isIdentifierChar(ch, astral)) {
18162
this.pos += ch <= 0xffff ? 1 : 2;
18163
} else if (ch === 92) { // "\"
18164
this.containsEsc = true;
18165
word += this.input.slice(chunkStart, this.pos);
18166
var escStart = this.pos;
18167
if (this.input.charCodeAt(++this.pos) !== 117) // "u"
18168
{ this.invalidStringToken(this.pos, "Expecting Unicode escape sequence \\uXXXX"); }
18169
++this.pos;
18170
var esc = this.readCodePoint();
18171
if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
18172
{ this.invalidStringToken(escStart, "Invalid Unicode escape"); }
18173
word += codePointToString(esc);
18174
chunkStart = this.pos;
18175
} else {
18176
break
18177
}
18178
first = false;
18179
}
18180
return word + this.input.slice(chunkStart, this.pos)
18181
};
18182
18183
// Read an identifier or keyword token. Will check for reserved
18184
// words when necessary.
18185
18186
pp.readWord = function() {
18187
var word = this.readWord1();
18188
var type = types$1.name;
18189
if (this.keywords.test(word)) {
18190
type = keywords[word];
18191
}
18192
return this.finishToken(type, word)
18193
};
18194
18195
// Acorn is a tiny, fast JavaScript parser written in JavaScript.
18196
18197
var version = "8.8.1";
18198
18199
Parser.acorn = {
18200
Parser: Parser,
18201
version: version,
18202
defaultOptions: defaultOptions,
18203
Position: Position,
18204
SourceLocation: SourceLocation,
18205
getLineInfo: getLineInfo,
18206
Node: Node$1,
18207
TokenType: TokenType,
18208
tokTypes: types$1,
18209
keywordTypes: keywords,
18210
TokContext: TokContext,
18211
tokContexts: types,
18212
isIdentifierChar: isIdentifierChar,
18213
isIdentifierStart: isIdentifierStart,
18214
Token: Token,
18215
isNewLine: isNewLine,
18216
lineBreak: lineBreak,
18217
lineBreakG: lineBreakG,
18218
nonASCIIwhitespace: nonASCIIwhitespace
18219
};
18220
18221
var defaultGlobals = new Set([
18222
"Array",
18223
"ArrayBuffer",
18224
"atob",
18225
"AudioContext",
18226
"Blob",
18227
"Boolean",
18228
"BigInt",
18229
"btoa",
18230
"clearInterval",
18231
"clearTimeout",
18232
"console",
18233
"crypto",
18234
"CustomEvent",
18235
"DataView",
18236
"Date",
18237
"decodeURI",
18238
"decodeURIComponent",
18239
"devicePixelRatio",
18240
"document",
18241
"encodeURI",
18242
"encodeURIComponent",
18243
"Error",
18244
"escape",
18245
"eval",
18246
"fetch",
18247
"File",
18248
"FileList",
18249
"FileReader",
18250
"Float32Array",
18251
"Float64Array",
18252
"Function",
18253
"Headers",
18254
"Image",
18255
"ImageData",
18256
"Infinity",
18257
"Int16Array",
18258
"Int32Array",
18259
"Int8Array",
18260
"Intl",
18261
"isFinite",
18262
"isNaN",
18263
"JSON",
18264
"Map",
18265
"Math",
18266
"NaN",
18267
"Number",
18268
"navigator",
18269
"Object",
18270
"parseFloat",
18271
"parseInt",
18272
"performance",
18273
"Path2D",
18274
"Promise",
18275
"Proxy",
18276
"RangeError",
18277
"ReferenceError",
18278
"Reflect",
18279
"RegExp",
18280
"cancelAnimationFrame",
18281
"requestAnimationFrame",
18282
"Set",
18283
"setInterval",
18284
"setTimeout",
18285
"String",
18286
"Symbol",
18287
"SyntaxError",
18288
"TextDecoder",
18289
"TextEncoder",
18290
"this",
18291
"TypeError",
18292
"Uint16Array",
18293
"Uint32Array",
18294
"Uint8Array",
18295
"Uint8ClampedArray",
18296
"undefined",
18297
"unescape",
18298
"URIError",
18299
"URL",
18300
"WeakMap",
18301
"WeakSet",
18302
"WebSocket",
18303
"Worker",
18304
"window"
18305
]);
18306
18307
// AST walker module for Mozilla Parser API compatible trees
18308
18309
// A simple walk is one where you simply specify callbacks to be
18310
// called on specific nodes. The last two arguments are optional. A
18311
// simple use would be
18312
//
18313
// walk.simple(myTree, {
18314
// Expression: function(node) { ... }
18315
// });
18316
//
18317
// to do something with all expressions. All Parser API node types
18318
// can be used to identify node types, as well as Expression and
18319
// Statement, which denote categories of nodes.
18320
//
18321
// The base argument can be used to pass a custom (recursive)
18322
// walker, and state can be used to give this walked an initial
18323
// state.
18324
18325
function simple(node, visitors, baseVisitor, state, override) {
18326
if (!baseVisitor) { baseVisitor = base$1
18327
; }(function c(node, st, override) {
18328
var type = override || node.type, found = visitors[type];
18329
baseVisitor[type](node, st, c);
18330
if (found) { found(node, st); }
18331
})(node, state, override);
18332
}
18333
18334
// An ancestor walk keeps an array of ancestor nodes (including the
18335
// current node) and passes them to the callback as third parameter
18336
// (and also as state parameter when no other state is present).
18337
function ancestor(node, visitors, baseVisitor, state, override) {
18338
var ancestors = [];
18339
if (!baseVisitor) { baseVisitor = base$1
18340
; }(function c(node, st, override) {
18341
var type = override || node.type, found = visitors[type];
18342
var isNew = node !== ancestors[ancestors.length - 1];
18343
if (isNew) { ancestors.push(node); }
18344
baseVisitor[type](node, st, c);
18345
if (found) { found(node, st || ancestors, ancestors); }
18346
if (isNew) { ancestors.pop(); }
18347
})(node, state, override);
18348
}
18349
18350
// Used to create a custom walker. Will fill in all missing node
18351
// type properties with the defaults.
18352
function make(funcs, baseVisitor) {
18353
var visitor = Object.create(baseVisitor || base$1);
18354
for (var type in funcs) { visitor[type] = funcs[type]; }
18355
return visitor
18356
}
18357
18358
function skipThrough(node, st, c) { c(node, st); }
18359
function ignore(_node, _st, _c) {}
18360
18361
// Node walkers.
18362
18363
var base$1 = {};
18364
18365
base$1.Program = base$1.BlockStatement = base$1.StaticBlock = function (node, st, c) {
18366
for (var i = 0, list = node.body; i < list.length; i += 1)
18367
{
18368
var stmt = list[i];
18369
18370
c(stmt, st, "Statement");
18371
}
18372
};
18373
base$1.Statement = skipThrough;
18374
base$1.EmptyStatement = ignore;
18375
base$1.ExpressionStatement = base$1.ParenthesizedExpression = base$1.ChainExpression =
18376
function (node, st, c) { return c(node.expression, st, "Expression"); };
18377
base$1.IfStatement = function (node, st, c) {
18378
c(node.test, st, "Expression");
18379
c(node.consequent, st, "Statement");
18380
if (node.alternate) { c(node.alternate, st, "Statement"); }
18381
};
18382
base$1.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); };
18383
base$1.BreakStatement = base$1.ContinueStatement = ignore;
18384
base$1.WithStatement = function (node, st, c) {
18385
c(node.object, st, "Expression");
18386
c(node.body, st, "Statement");
18387
};
18388
base$1.SwitchStatement = function (node, st, c) {
18389
c(node.discriminant, st, "Expression");
18390
for (var i$1 = 0, list$1 = node.cases; i$1 < list$1.length; i$1 += 1) {
18391
var cs = list$1[i$1];
18392
18393
if (cs.test) { c(cs.test, st, "Expression"); }
18394
for (var i = 0, list = cs.consequent; i < list.length; i += 1)
18395
{
18396
var cons = list[i];
18397
18398
c(cons, st, "Statement");
18399
}
18400
}
18401
};
18402
base$1.SwitchCase = function (node, st, c) {
18403
if (node.test) { c(node.test, st, "Expression"); }
18404
for (var i = 0, list = node.consequent; i < list.length; i += 1)
18405
{
18406
var cons = list[i];
18407
18408
c(cons, st, "Statement");
18409
}
18410
};
18411
base$1.ReturnStatement = base$1.YieldExpression = base$1.AwaitExpression = function (node, st, c) {
18412
if (node.argument) { c(node.argument, st, "Expression"); }
18413
};
18414
base$1.ThrowStatement = base$1.SpreadElement =
18415
function (node, st, c) { return c(node.argument, st, "Expression"); };
18416
base$1.TryStatement = function (node, st, c) {
18417
c(node.block, st, "Statement");
18418
if (node.handler) { c(node.handler, st); }
18419
if (node.finalizer) { c(node.finalizer, st, "Statement"); }
18420
};
18421
base$1.CatchClause = function (node, st, c) {
18422
if (node.param) { c(node.param, st, "Pattern"); }
18423
c(node.body, st, "Statement");
18424
};
18425
base$1.WhileStatement = base$1.DoWhileStatement = function (node, st, c) {
18426
c(node.test, st, "Expression");
18427
c(node.body, st, "Statement");
18428
};
18429
base$1.ForStatement = function (node, st, c) {
18430
if (node.init) { c(node.init, st, "ForInit"); }
18431
if (node.test) { c(node.test, st, "Expression"); }
18432
if (node.update) { c(node.update, st, "Expression"); }
18433
c(node.body, st, "Statement");
18434
};
18435
base$1.ForInStatement = base$1.ForOfStatement = function (node, st, c) {
18436
c(node.left, st, "ForInit");
18437
c(node.right, st, "Expression");
18438
c(node.body, st, "Statement");
18439
};
18440
base$1.ForInit = function (node, st, c) {
18441
if (node.type === "VariableDeclaration") { c(node, st); }
18442
else { c(node, st, "Expression"); }
18443
};
18444
base$1.DebuggerStatement = ignore;
18445
18446
base$1.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); };
18447
base$1.VariableDeclaration = function (node, st, c) {
18448
for (var i = 0, list = node.declarations; i < list.length; i += 1)
18449
{
18450
var decl = list[i];
18451
18452
c(decl, st);
18453
}
18454
};
18455
base$1.VariableDeclarator = function (node, st, c) {
18456
c(node.id, st, "Pattern");
18457
if (node.init) { c(node.init, st, "Expression"); }
18458
};
18459
18460
base$1.Function = function (node, st, c) {
18461
if (node.id) { c(node.id, st, "Pattern"); }
18462
for (var i = 0, list = node.params; i < list.length; i += 1)
18463
{
18464
var param = list[i];
18465
18466
c(param, st, "Pattern");
18467
}
18468
c(node.body, st, node.expression ? "Expression" : "Statement");
18469
};
18470
18471
base$1.Pattern = function (node, st, c) {
18472
if (node.type === "Identifier")
18473
{ c(node, st, "VariablePattern"); }
18474
else if (node.type === "MemberExpression")
18475
{ c(node, st, "MemberPattern"); }
18476
else
18477
{ c(node, st); }
18478
};
18479
base$1.VariablePattern = ignore;
18480
base$1.MemberPattern = skipThrough;
18481
base$1.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); };
18482
base$1.ArrayPattern = function (node, st, c) {
18483
for (var i = 0, list = node.elements; i < list.length; i += 1) {
18484
var elt = list[i];
18485
18486
if (elt) { c(elt, st, "Pattern"); }
18487
}
18488
};
18489
base$1.ObjectPattern = function (node, st, c) {
18490
for (var i = 0, list = node.properties; i < list.length; i += 1) {
18491
var prop = list[i];
18492
18493
if (prop.type === "Property") {
18494
if (prop.computed) { c(prop.key, st, "Expression"); }
18495
c(prop.value, st, "Pattern");
18496
} else if (prop.type === "RestElement") {
18497
c(prop.argument, st, "Pattern");
18498
}
18499
}
18500
};
18501
18502
base$1.Expression = skipThrough;
18503
base$1.ThisExpression = base$1.Super = base$1.MetaProperty = ignore;
18504
base$1.ArrayExpression = function (node, st, c) {
18505
for (var i = 0, list = node.elements; i < list.length; i += 1) {
18506
var elt = list[i];
18507
18508
if (elt) { c(elt, st, "Expression"); }
18509
}
18510
};
18511
base$1.ObjectExpression = function (node, st, c) {
18512
for (var i = 0, list = node.properties; i < list.length; i += 1)
18513
{
18514
var prop = list[i];
18515
18516
c(prop, st);
18517
}
18518
};
18519
base$1.FunctionExpression = base$1.ArrowFunctionExpression = base$1.FunctionDeclaration;
18520
base$1.SequenceExpression = function (node, st, c) {
18521
for (var i = 0, list = node.expressions; i < list.length; i += 1)
18522
{
18523
var expr = list[i];
18524
18525
c(expr, st, "Expression");
18526
}
18527
};
18528
base$1.TemplateLiteral = function (node, st, c) {
18529
for (var i = 0, list = node.quasis; i < list.length; i += 1)
18530
{
18531
var quasi = list[i];
18532
18533
c(quasi, st);
18534
}
18535
18536
for (var i$1 = 0, list$1 = node.expressions; i$1 < list$1.length; i$1 += 1)
18537
{
18538
var expr = list$1[i$1];
18539
18540
c(expr, st, "Expression");
18541
}
18542
};
18543
base$1.TemplateElement = ignore;
18544
base$1.UnaryExpression = base$1.UpdateExpression = function (node, st, c) {
18545
c(node.argument, st, "Expression");
18546
};
18547
base$1.BinaryExpression = base$1.LogicalExpression = function (node, st, c) {
18548
c(node.left, st, "Expression");
18549
c(node.right, st, "Expression");
18550
};
18551
base$1.AssignmentExpression = base$1.AssignmentPattern = function (node, st, c) {
18552
c(node.left, st, "Pattern");
18553
c(node.right, st, "Expression");
18554
};
18555
base$1.ConditionalExpression = function (node, st, c) {
18556
c(node.test, st, "Expression");
18557
c(node.consequent, st, "Expression");
18558
c(node.alternate, st, "Expression");
18559
};
18560
base$1.NewExpression = base$1.CallExpression = function (node, st, c) {
18561
c(node.callee, st, "Expression");
18562
if (node.arguments)
18563
{ for (var i = 0, list = node.arguments; i < list.length; i += 1)
18564
{
18565
var arg = list[i];
18566
18567
c(arg, st, "Expression");
18568
} }
18569
};
18570
base$1.MemberExpression = function (node, st, c) {
18571
c(node.object, st, "Expression");
18572
if (node.computed) { c(node.property, st, "Expression"); }
18573
};
18574
base$1.ExportNamedDeclaration = base$1.ExportDefaultDeclaration = function (node, st, c) {
18575
if (node.declaration)
18576
{ c(node.declaration, st, node.type === "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression"); }
18577
if (node.source) { c(node.source, st, "Expression"); }
18578
};
18579
base$1.ExportAllDeclaration = function (node, st, c) {
18580
if (node.exported)
18581
{ c(node.exported, st); }
18582
c(node.source, st, "Expression");
18583
};
18584
base$1.ImportDeclaration = function (node, st, c) {
18585
for (var i = 0, list = node.specifiers; i < list.length; i += 1)
18586
{
18587
var spec = list[i];
18588
18589
c(spec, st);
18590
}
18591
c(node.source, st, "Expression");
18592
};
18593
base$1.ImportExpression = function (node, st, c) {
18594
c(node.source, st, "Expression");
18595
};
18596
base$1.ImportSpecifier = base$1.ImportDefaultSpecifier = base$1.ImportNamespaceSpecifier = base$1.Identifier = base$1.PrivateIdentifier = base$1.Literal = ignore;
18597
18598
base$1.TaggedTemplateExpression = function (node, st, c) {
18599
c(node.tag, st, "Expression");
18600
c(node.quasi, st, "Expression");
18601
};
18602
base$1.ClassDeclaration = base$1.ClassExpression = function (node, st, c) { return c(node, st, "Class"); };
18603
base$1.Class = function (node, st, c) {
18604
if (node.id) { c(node.id, st, "Pattern"); }
18605
if (node.superClass) { c(node.superClass, st, "Expression"); }
18606
c(node.body, st);
18607
};
18608
base$1.ClassBody = function (node, st, c) {
18609
for (var i = 0, list = node.body; i < list.length; i += 1)
18610
{
18611
var elt = list[i];
18612
18613
c(elt, st);
18614
}
18615
};
18616
base$1.MethodDefinition = base$1.PropertyDefinition = base$1.Property = function (node, st, c) {
18617
if (node.computed) { c(node.key, st, "Expression"); }
18618
if (node.value) { c(node.value, st, "Expression"); }
18619
};
18620
18621
var walk = make({
18622
Import() {},
18623
ViewExpression(node, st, c) {
18624
c(node.id, st, "Identifier");
18625
},
18626
MutableExpression(node, st, c) {
18627
c(node.id, st, "Identifier");
18628
}
18629
});
18630
18631
// Based on https://github.com/ForbesLindesay/acorn-globals
18632
18633
function isScope(node) {
18634
return node.type === "FunctionExpression"
18635
|| node.type === "FunctionDeclaration"
18636
|| node.type === "ArrowFunctionExpression"
18637
|| node.type === "Program";
18638
}
18639
18640
function isBlockScope(node) {
18641
return node.type === "BlockStatement"
18642
|| node.type === "ForInStatement"
18643
|| node.type === "ForOfStatement"
18644
|| node.type === "ForStatement"
18645
|| isScope(node);
18646
}
18647
18648
function declaresArguments(node) {
18649
return node.type === "FunctionExpression"
18650
|| node.type === "FunctionDeclaration";
18651
}
18652
18653
function findReferences(cell, globals) {
18654
const ast = {type: "Program", body: [cell.body]};
18655
const locals = new Map;
18656
const globalSet = new Set(globals);
18657
const references = [];
18658
18659
function hasLocal(node, name) {
18660
const l = locals.get(node);
18661
return l ? l.has(name) : false;
18662
}
18663
18664
function declareLocal(node, id) {
18665
const l = locals.get(node);
18666
if (l) l.add(id.name);
18667
else locals.set(node, new Set([id.name]));
18668
}
18669
18670
function declareClass(node) {
18671
if (node.id) declareLocal(node, node.id);
18672
}
18673
18674
function declareFunction(node) {
18675
node.params.forEach(param => declarePattern(param, node));
18676
if (node.id) declareLocal(node, node.id);
18677
}
18678
18679
function declareCatchClause(node) {
18680
if (node.param) declarePattern(node.param, node);
18681
}
18682
18683
function declarePattern(node, parent) {
18684
switch (node.type) {
18685
case "Identifier":
18686
declareLocal(parent, node);
18687
break;
18688
case "ObjectPattern":
18689
node.properties.forEach(node => declarePattern(node, parent));
18690
break;
18691
case "ArrayPattern":
18692
node.elements.forEach(node => node && declarePattern(node, parent));
18693
break;
18694
case "Property":
18695
declarePattern(node.value, parent);
18696
break;
18697
case "RestElement":
18698
declarePattern(node.argument, parent);
18699
break;
18700
case "AssignmentPattern":
18701
declarePattern(node.left, parent);
18702
break;
18703
default:
18704
throw new Error("Unrecognized pattern type: " + node.type);
18705
}
18706
}
18707
18708
function declareModuleSpecifier(node) {
18709
declareLocal(ast, node.local);
18710
}
18711
18712
ancestor(
18713
ast,
18714
{
18715
VariableDeclaration: (node, parents) => {
18716
let parent = null;
18717
for (let i = parents.length - 1; i >= 0 && parent === null; --i) {
18718
if (node.kind === "var" ? isScope(parents[i]) : isBlockScope(parents[i])) {
18719
parent = parents[i];
18720
}
18721
}
18722
node.declarations.forEach(declaration => declarePattern(declaration.id, parent));
18723
},
18724
FunctionDeclaration: (node, parents) => {
18725
let parent = null;
18726
for (let i = parents.length - 2; i >= 0 && parent === null; --i) {
18727
if (isScope(parents[i])) {
18728
parent = parents[i];
18729
}
18730
}
18731
declareLocal(parent, node.id);
18732
declareFunction(node);
18733
},
18734
Function: declareFunction,
18735
ClassDeclaration: (node, parents) => {
18736
let parent = null;
18737
for (let i = parents.length - 2; i >= 0 && parent === null; i--) {
18738
if (isScope(parents[i])) {
18739
parent = parents[i];
18740
}
18741
}
18742
declareLocal(parent, node.id);
18743
},
18744
Class: declareClass,
18745
CatchClause: declareCatchClause,
18746
ImportDefaultSpecifier: declareModuleSpecifier,
18747
ImportSpecifier: declareModuleSpecifier,
18748
ImportNamespaceSpecifier: declareModuleSpecifier
18749
},
18750
walk
18751
);
18752
18753
function identifier(node, parents) {
18754
let name = node.name;
18755
if (name === "undefined") return;
18756
for (let i = parents.length - 2; i >= 0; --i) {
18757
if (name === "arguments") {
18758
if (declaresArguments(parents[i])) {
18759
return;
18760
}
18761
}
18762
if (hasLocal(parents[i], name)) {
18763
return;
18764
}
18765
if (parents[i].type === "ViewExpression") {
18766
node = parents[i];
18767
name = `viewof ${node.id.name}`;
18768
}
18769
if (parents[i].type === "MutableExpression") {
18770
node = parents[i];
18771
name = `mutable ${node.id.name}`;
18772
}
18773
}
18774
if (!globalSet.has(name)) {
18775
if (name === "arguments") {
18776
throw Object.assign(new SyntaxError(`arguments is not allowed`), {node});
18777
}
18778
references.push(node);
18779
}
18780
}
18781
18782
ancestor(
18783
ast,
18784
{
18785
VariablePattern: identifier,
18786
Identifier: identifier
18787
},
18788
walk
18789
);
18790
18791
function checkConst(node, parents) {
18792
if (!node) return;
18793
switch (node.type) {
18794
case "Identifier":
18795
case "VariablePattern": {
18796
for (const parent of parents) {
18797
if (hasLocal(parent, node.name)) {
18798
return;
18799
}
18800
}
18801
if (parents[parents.length - 2].type === "MutableExpression") {
18802
return;
18803
}
18804
throw Object.assign(new SyntaxError(`Assignment to constant variable ${node.name}`), {node});
18805
}
18806
case "ArrayPattern": {
18807
for (const element of node.elements) {
18808
checkConst(element, parents);
18809
}
18810
return;
18811
}
18812
case "ObjectPattern": {
18813
for (const property of node.properties) {
18814
checkConst(property, parents);
18815
}
18816
return;
18817
}
18818
case "Property": {
18819
checkConst(node.value, parents);
18820
return;
18821
}
18822
case "RestElement": {
18823
checkConst(node.argument, parents);
18824
return;
18825
}
18826
}
18827
}
18828
18829
function checkConstArgument(node, parents) {
18830
checkConst(node.argument, parents);
18831
}
18832
18833
function checkConstLeft(node, parents) {
18834
checkConst(node.left, parents);
18835
}
18836
18837
ancestor(
18838
ast,
18839
{
18840
AssignmentExpression: checkConstLeft,
18841
AssignmentPattern: checkConstLeft,
18842
UpdateExpression: checkConstArgument,
18843
ForOfStatement: checkConstLeft,
18844
ForInStatement: checkConstLeft
18845
},
18846
walk
18847
);
18848
18849
return references;
18850
}
18851
18852
function findFeatures(cell, featureName) {
18853
const ast = {type: "Program", body: [cell.body]};
18854
const features = new Map();
18855
const {references} = cell;
18856
18857
simple(
18858
ast,
18859
{
18860
CallExpression: node => {
18861
const {callee, arguments: args} = node;
18862
18863
// Ignore function calls that are not references to the feature.
18864
if (
18865
callee.type !== "Identifier" ||
18866
callee.name !== featureName ||
18867
references.indexOf(callee) < 0
18868
) return;
18869
18870
// Forbid dynamic calls.
18871
if (
18872
args.length !== 1 ||
18873
!((args[0].type === "Literal" && /^['"]/.test(args[0].raw)) ||
18874
(args[0].type === "TemplateLiteral" && args[0].expressions.length === 0))
18875
) {
18876
throw Object.assign(new SyntaxError(`${featureName} requires a single literal string argument`), {node});
18877
}
18878
18879
const [arg] = args;
18880
const name = arg.type === "Literal" ? arg.value : arg.quasis[0].value.cooked;
18881
const location = {start: arg.start, end: arg.end};
18882
if (features.has(name)) features.get(name).push(location);
18883
else features.set(name, [location]);
18884
}
18885
},
18886
walk
18887
);
18888
18889
return features;
18890
}
18891
18892
const SCOPE_FUNCTION = 2;
18893
const SCOPE_ASYNC = 4;
18894
const SCOPE_GENERATOR = 8;
18895
18896
class CellParser extends Parser {
18897
constructor(options, ...args) {
18898
super(Object.assign({ecmaVersion: 13}, options), ...args);
18899
}
18900
enterScope(flags) {
18901
if (flags & SCOPE_FUNCTION) ++this.O_function;
18902
return super.enterScope(flags);
18903
}
18904
exitScope() {
18905
if (this.currentScope().flags & SCOPE_FUNCTION) --this.O_function;
18906
return super.exitScope();
18907
}
18908
parseForIn(node, init) {
18909
if (this.O_function === 1 && node.await) this.O_async = true;
18910
return super.parseForIn(node, init);
18911
}
18912
parseAwait() {
18913
if (this.O_function === 1) this.O_async = true;
18914
return super.parseAwait();
18915
}
18916
parseYield(noIn) {
18917
if (this.O_function === 1) this.O_generator = true;
18918
return super.parseYield(noIn);
18919
}
18920
parseImport(node) {
18921
this.next();
18922
node.specifiers = this.parseImportSpecifiers();
18923
if (this.type === types$1._with) {
18924
this.next();
18925
node.injections = this.parseImportSpecifiers();
18926
}
18927
this.expectContextual("from");
18928
node.source = this.type === types$1.string ? this.parseExprAtom() : this.unexpected();
18929
return this.finishNode(node, "ImportDeclaration");
18930
}
18931
parseImportSpecifiers() {
18932
const nodes = [];
18933
const identifiers = new Set;
18934
let first = true;
18935
this.expect(types$1.braceL);
18936
while (!this.eat(types$1.braceR)) {
18937
if (first) {
18938
first = false;
18939
} else {
18940
this.expect(types$1.comma);
18941
if (this.afterTrailingComma(types$1.braceR)) break;
18942
}
18943
const node = this.startNode();
18944
node.view = this.eatContextual("viewof");
18945
node.mutable = node.view ? false : this.eatContextual("mutable");
18946
node.imported = this.parseIdent();
18947
this.checkUnreserved(node.imported);
18948
this.checkLocal(node.imported);
18949
if (this.eatContextual("as")) {
18950
node.local = this.parseIdent();
18951
this.checkUnreserved(node.local);
18952
this.checkLocal(node.local);
18953
} else {
18954
node.local = node.imported;
18955
}
18956
this.checkLValSimple(node.local, "let");
18957
if (identifiers.has(node.local.name)) {
18958
this.raise(node.local.start, `Identifier '${node.local.name}' has already been declared`);
18959
}
18960
identifiers.add(node.local.name);
18961
nodes.push(this.finishNode(node, "ImportSpecifier"));
18962
}
18963
return nodes;
18964
}
18965
parseExprAtom(refDestructuringErrors) {
18966
return (
18967
this.parseMaybeKeywordExpression("viewof", "ViewExpression") ||
18968
this.parseMaybeKeywordExpression("mutable", "MutableExpression") ||
18969
super.parseExprAtom(refDestructuringErrors)
18970
);
18971
}
18972
startCell() {
18973
this.O_function = 0;
18974
this.O_async = false;
18975
this.O_generator = false;
18976
this.strict = true;
18977
this.enterScope(SCOPE_FUNCTION | SCOPE_ASYNC | SCOPE_GENERATOR);
18978
}
18979
finishCell(node, body, id) {
18980
if (id) this.checkLocal(id);
18981
node.id = id;
18982
node.body = body;
18983
node.async = this.O_async;
18984
node.generator = this.O_generator;
18985
this.exitScope();
18986
return this.finishNode(node, "Cell");
18987
}
18988
parseCell(node, eof) {
18989
const lookahead = new CellParser({}, this.input, this.start);
18990
let token = lookahead.getToken();
18991
let body = null;
18992
let id = null;
18993
18994
this.startCell();
18995
18996
// An import?
18997
if (token.type === types$1._import && lookahead.getToken().type !== types$1.parenL) {
18998
body = this.parseImport(this.startNode());
18999
}
19000
19001
// A non-empty cell?
19002
else if (token.type !== types$1.eof && token.type !== types$1.semi) {
19003
// A named cell?
19004
if (token.type === types$1.name) {
19005
if (token.value === "viewof" || token.value === "mutable") {
19006
token = lookahead.getToken();
19007
if (token.type !== types$1.name) {
19008
lookahead.unexpected();
19009
}
19010
}
19011
token = lookahead.getToken();
19012
if (token.type === types$1.eq) {
19013
id =
19014
this.parseMaybeKeywordExpression("viewof", "ViewExpression") ||
19015
this.parseMaybeKeywordExpression("mutable", "MutableExpression") ||
19016
this.parseIdent();
19017
token = lookahead.getToken();
19018
this.expect(types$1.eq);
19019
}
19020
}
19021
19022
// A block?
19023
if (token.type === types$1.braceL) {
19024
body = this.parseBlock();
19025
}
19026
19027
// An expression?
19028
// Possibly a function or class declaration?
19029
else {
19030
body = this.parseExpression();
19031
if (
19032
id === null &&
19033
(body.type === "FunctionExpression" ||
19034
body.type === "ClassExpression")
19035
) {
19036
id = body.id;
19037
}
19038
}
19039
}
19040
19041
this.semicolon();
19042
if (eof) this.expect(types$1.eof); // TODO
19043
19044
return this.finishCell(node, body, id);
19045
}
19046
parseTopLevel(node) {
19047
return this.parseCell(node, true);
19048
}
19049
toAssignable(node, isBinding, refDestructuringErrors) {
19050
return node.type === "MutableExpression"
19051
? node
19052
: super.toAssignable(node, isBinding, refDestructuringErrors);
19053
}
19054
checkLocal(id) {
19055
const node = id.id || id;
19056
if (defaultGlobals.has(node.name) || node.name === "arguments") {
19057
this.raise(node.start, `Identifier '${node.name}' is reserved`);
19058
}
19059
}
19060
checkUnreserved(node) {
19061
if (node.name === "viewof" || node.name === "mutable") {
19062
this.raise(node.start, `Unexpected keyword '${node.name}'`);
19063
}
19064
return super.checkUnreserved(node);
19065
}
19066
checkLValSimple(expr, bindingType, checkClashes) {
19067
return super.checkLValSimple(
19068
expr.type === "MutableExpression" ? expr.id : expr,
19069
bindingType,
19070
checkClashes
19071
);
19072
}
19073
unexpected(pos) {
19074
this.raise(
19075
pos != null ? pos : this.start,
19076
this.type === types$1.eof ? "Unexpected end of input" : "Unexpected token"
19077
);
19078
}
19079
parseMaybeKeywordExpression(keyword, type) {
19080
if (this.isContextual(keyword)) {
19081
const node = this.startNode();
19082
this.next();
19083
node.id = this.parseIdent();
19084
return this.finishNode(node, type);
19085
}
19086
}
19087
}
19088
19089
// Based on acorn’s q_tmpl. We will use this to initialize the
19090
// parser context so our `readTemplateToken` override is called.
19091
// `readTemplateToken` is based on acorn's `readTmplToken` which
19092
// is used inside template literals. Our version allows backQuotes.
19093
new TokContext(
19094
"`", // token
19095
true, // isExpr
19096
true, // preserveSpace
19097
parser => readTemplateToken.call(parser) // override
19098
);
19099
19100
// This is our custom override for parsing a template that allows backticks.
19101
// Based on acorn's readInvalidTemplateToken.
19102
function readTemplateToken() {
19103
out: for (; this.pos < this.input.length; this.pos++) {
19104
switch (this.input.charCodeAt(this.pos)) {
19105
case 92: { // slash
19106
if (this.pos < this.input.length - 1) ++this.pos; // not a terminal slash
19107
break;
19108
}
19109
case 36: { // dollar
19110
if (this.input.charCodeAt(this.pos + 1) === 123) { // dollar curly
19111
if (this.pos === this.start && this.type === types$1.invalidTemplate) {
19112
this.pos += 2;
19113
return this.finishToken(types$1.dollarBraceL);
19114
}
19115
break out;
19116
}
19117
break;
19118
}
19119
}
19120
}
19121
return this.finishToken(types$1.invalidTemplate, this.input.slice(this.start, this.pos));
19122
}
19123
19124
// Find references.
19125
// Check for illegal references to arguments.
19126
// Check for illegal assignments to global references.
19127
function parseReferences(cell, input, globals = defaultGlobals) {
19128
if (!cell.body) {
19129
cell.references = [];
19130
} else if (cell.body.type === "ImportDeclaration") {
19131
cell.references = cell.body.injections
19132
? cell.body.injections.map(i => i.imported)
19133
: [];
19134
} else {
19135
try {
19136
cell.references = findReferences(cell, globals);
19137
} catch (error) {
19138
if (error.node) {
19139
const loc = getLineInfo(input, error.node.start);
19140
error.message += ` (${loc.line}:${loc.column})`;
19141
error.pos = error.node.start;
19142
error.loc = loc;
19143
delete error.node;
19144
}
19145
throw error;
19146
}
19147
}
19148
return cell;
19149
}
19150
19151
// Find features: file attachments, secrets, database clients.
19152
// Check for illegal references to arguments.
19153
// Check for illegal assignments to global references.
19154
function parseFeatures(cell, input) {
19155
if (cell.body && cell.body.type !== "ImportDeclaration") {
19156
try {
19157
cell.fileAttachments = findFeatures(cell, "FileAttachment");
19158
cell.databaseClients = findFeatures(cell, "DatabaseClient");
19159
cell.secrets = findFeatures(cell, "Secret");
19160
cell.notificationClients = findFeatures(cell, "NotificationClient");
19161
} catch (error) {
19162
if (error.node) {
19163
const loc = getLineInfo(input, error.node.start);
19164
error.message += ` (${loc.line}:${loc.column})`;
19165
error.pos = error.node.start;
19166
error.loc = loc;
19167
delete error.node;
19168
}
19169
throw error;
19170
}
19171
} else {
19172
cell.fileAttachments = new Map();
19173
cell.databaseClients = new Map();
19174
cell.secrets = new Map();
19175
cell.notificationClients = new Map();
19176
}
19177
return cell;
19178
}
19179
19180
/* Fork changes begin here */
19181
19182
function parseModule(input, {globals} = {}) {
19183
const program = ModuleParser.parse(input);
19184
for (const cell of program.cells) {
19185
parseReferences(cell, input, globals);
19186
parseFeatures(cell, input);
19187
}
19188
return program;
19189
}
19190
19191
class ModuleParser extends CellParser {
19192
parseTopLevel(node) {
19193
if (!node.cells) node.cells = [];
19194
while (this.type !== types$1.eof) {
19195
const cell = this.parseCell(this.startNode());
19196
cell.input = this.input;
19197
node.cells.push(cell);
19198
}
19199
this.next();
19200
return this.finishNode(node, "Program");
19201
}
19202
}
19203
19204
/* Fork changes end here */
19205
19206
// https://developer.mozilla.org/en-US/docs/Glossary/Base64
19207
19208
function base64ToBytes(base64) {
19209
const binString = atob(base64);
19210
return Uint8Array.from(binString, (m) => m.codePointAt(0));
19211
}
19212
19213
function base64ToStr(base64) {
19214
return new TextDecoder().decode(base64ToBytes(base64));
19215
}
19216
19217
/*global Shiny, $, DOMParser, MutationObserver, URL
19218
*
19219
* ojs-connector.js
19220
*
19221
* Copyright (C) 2022 RStudio, PBC
19222
*
19223
*/
19224
19225
//////////////////////////////////////////////////////////////////////////////
19226
19227
class EmptyInspector {
19228
pending() {
19229
}
19230
fulfilled(_value, _name) {
19231
}
19232
rejected(_error, _name) {
19233
// TODO we should probably communicate this upstream somehow.
19234
}
19235
}
19236
19237
// here we need to convert from an ES6 module to an observable module
19238
// in, well, a best-effort kind of way.
19239
function es6ImportAsObservableModule(modulePromise, specs) {
19240
const promiseMap = {};
19241
const resolveMap = {};
19242
specs.forEach(spec => {
19243
promiseMap[spec] = new Promise((resolve, reject) => { resolveMap[spec] = { resolve, reject }; });
19244
});
19245
modulePromise.then(m => {
19246
specs.forEach(spec => {
19247
resolveMap[spec].resolve(m[spec]);
19248
});
19249
}).catch(error => {
19250
specs.forEach(spec => {
19251
resolveMap[spec].reject(error);
19252
});
19253
});
19254
return function (runtime, observer) {
19255
const main = runtime.module();
19256
19257
specs.forEach(key => {
19258
main.variable(observer(key)).define(key, [], () => promiseMap[key]);
19259
});
19260
/*
19261
Object.keys(m).forEach((key) => {
19262
const v = m[key];
19263
19264
main.variable(observer(key)).define(key, [], () => promiseMap[key]v);
19265
});
19266
*/
19267
return main;
19268
};
19269
}
19270
19271
19272
// this is essentially the import resolution code from observable's
19273
// runtime. we change it to add a license check for permissive
19274
// open-source licenses before resolving the import
19275
async function defaultResolveImportPath(path) {
19276
const extractPath = (path) => {
19277
let source = path;
19278
let m;
19279
if ((m = /\.js(\?|$)/i.exec(source))) {
19280
source = source.slice(0, m.index);
19281
}
19282
if ((m = /^[0-9a-f]{16}$/i.test(source))) {
19283
source = `d/${source}`;
19284
}
19285
if ((m = /^https:\/\/(api\.|beta\.|)observablehq\.com\//i.exec(source))) {
19286
source = source.slice(m[0].length);
19287
}
19288
return source;
19289
};
19290
const source = extractPath(path);
19291
const moduleURL = `https://api.observablehq.com/${source}.js?v=3`;
19292
19293
/* TODO This should be the implementation we use, once/if observable
19294
starts reporting notebook license on their metadata.
19295
19296
const metadata = await fetch(metadataURL, { mode: 'no-cors' });
19297
const nbJson = metadata.json();
19298
if (["isc", "mit", "bsd-3-clause", "apache-2.0"].indexOf(nbJson.license) === -1) {
19299
throw new Error(`Notebook doesn't have a permissive open-source license`);
19300
} */
19301
19302
const m = await import(moduleURL);
19303
return m.default;
19304
}
19305
19306
/*
19307
importPathResolver encodes the rules for ojsconnector to resolve
19308
import statements.
19309
19310
This code doesn't depend have any dependencies on quarto, but some
19311
of the decisions here are influence by the needs of the quarto
19312
system.
19313
19314
We use the same name from observable's runtime so the intended
19315
functionality is clear. However, note that their name is slightly
19316
misleading. importPathResolver not only resolves import paths but
19317
performs module imports as well. This is useful for us because it
19318
allows us to extend the meaning of ojs's import statement, but it
19319
makes the name confusing.
19320
19321
Here are the rules for our version of the import statement.
19322
19323
The function returned by importPathResolver expects a "module specifier", and
19324
produces a module as defined by observable's runtime.
19325
19326
## Local vs remote vs observable imports
19327
19328
A module specifier is a string, interpreted differently depending on
19329
the following properties:
19330
19331
- it starts with "." or "/", in which case we call it a "local module"
19332
19333
- it is a well-defined absolute URL which does _not_ match the regexp:
19334
/^https:\/\/(api\.|beta\.|)observablehq\.com\//i
19335
in which case we call it a "remote import"
19336
19337
- otherwise, it is an "observable import"
19338
19339
If the string is an observable import, it behaves exactly like the import
19340
statement inside observable notebooks (we actually defer to their function
19341
call.) Otherwise, the import statement first retrieves the text content
19342
of the resource referenced by the path, and then interprets it.
19343
19344
## where resources come from
19345
19346
When operating in non-self-contained mode, local and remote import
19347
paths are then interpreted as relative URLs (RFC 1808) with base URL
19348
window.location (specifically as "relative path" and "absolute path"
19349
relative URLs).
19350
19351
In self-contained mode, these paths are interpreted as paths in the
19352
quarto project, either as root-relative or relative paths. The
19353
contents of these files are converted to data URLs and stored in a
19354
local resolution map.
19355
19356
## how are contents interpreted
19357
19358
The contents of the resource are then interpreted differently
19359
depending on the file type of the requested resource.
19360
19361
For non-self-contained imports, the file type is determined by the
19362
extension of the URL pathname. If the extension is "js", we take the
19363
specifier to mean an ES module; If the extension is "ojs", we take
19364
the specifier to mean an "ojs" module (a collection of observable
19365
statements packaged into a module, suitable for reuse). If the
19366
extension is "ts" or "tsx", then this is an import that was actually transpiled
19367
into js during quarto render, and we change the extension to .js and
19368
resolve that. Finally, if the extension is "qmd", we take the specifier
19369
to mean an "implicit ojs module", equivalent to extracting all
19370
the ojs statements from the .qmd file and producing an OJS module.
19371
19372
For self-contained imports, the file type is determined by the MIME
19373
type of the data URL. "application/javascript" is interpreted to
19374
mean an ES module, and "application/ojs-javascript" is interpreted
19375
to mean an "ojs" module. (.qmd imports will have been
19376
translated to ojs modules by the compilation step.)
19377
19378
The resources are finally retrieved, compiled into modules
19379
compatible with the observable runtime, and returned as
19380
the result of the import statement.
19381
19382
*/
19383
19384
function importPathResolver(paths, localResolverMap) {
19385
// NB: only resolve the field values in paths when calling rootPath
19386
// and relativePath. If we prematurely optimize this by moving the
19387
// const declarations outside, then we will capture the
19388
// uninitialized values.
19389
19390
// fetch() and import() have different relative path semantics, so
19391
// we need different paths for each use case
19392
19393
function importRootPath(path) {
19394
const { runtimeToRoot } = paths;
19395
if (!runtimeToRoot) {
19396
return path;
19397
} else {
19398
return `${runtimeToRoot}/${path}`;
19399
}
19400
}
19401
19402
function importRelativePath(path) {
19403
const { runtimeToDoc } = paths;
19404
if (!runtimeToDoc) {
19405
return path;
19406
} else {
19407
return `${runtimeToDoc}/${path}`;
19408
}
19409
}
19410
19411
// a fetch path of a root-relative path is resolved wrt to
19412
// the document root
19413
function fetchRootPath(path) {
19414
const { docToRoot } = paths;
19415
if (!docToRoot) {
19416
return path;
19417
} else {
19418
return `${docToRoot}/${path}`;
19419
}
19420
}
19421
19422
// a fetch path of a relative path is resolved the naive way
19423
function fetchRelativePath(path) {
19424
return path;
19425
}
19426
19427
return async (path, specs) => {
19428
const isLocalModule = path.startsWith("/") || path.startsWith(".");
19429
const isImportFromObservableWebsite = path.match(
19430
/^https:\/\/(api\.|beta\.|)observablehq\.com\//i,
19431
);
19432
19433
if (!isLocalModule || isImportFromObservableWebsite) {
19434
return defaultResolveImportPath(path);
19435
}
19436
19437
let importPath, fetchPath;
19438
let moduleType;
19439
if (window._ojs.selfContained) {
19440
if (path.endsWith(".ts")) {
19441
path = path.replace(/\.ts$/, ".js");
19442
} else if (path.endsWith(".tsx")) {
19443
path = path.replace(/\.tsx$/, ".js");
19444
}
19445
const resolved = localResolverMap.get(path);
19446
if (resolved === undefined) {
19447
throw new Error(`missing local file ${path} in self-contained mode`);
19448
}
19449
// self-contained resolves to data URLs, so they behave the same.
19450
importPath = resolved;
19451
fetchPath = resolved;
19452
19453
// we have a data URL here.
19454
const mimeType = resolved.match(/data:(.*);base64/)[1];
19455
switch (mimeType) {
19456
case "application/javascript":
19457
moduleType = "js";
19458
break;
19459
case "application/ojs-javascript":
19460
moduleType = "ojs";
19461
break;
19462
default:
19463
throw new Error(`unrecognized MIME type ${mimeType}`);
19464
}
19465
} else {
19466
// we have a relative URL here
19467
const resourceURL = new URL(path, window.location);
19468
moduleType = resourceURL.pathname.match(/\.(ojs|js|ts|tsx|qmd)$/)[1];
19469
19470
// resolve path according to quarto path resolution rules.
19471
if (path.startsWith("/")) {
19472
importPath = importRootPath(path);
19473
fetchPath = fetchRootPath(path);
19474
} else {
19475
importPath = importRelativePath(path);
19476
fetchPath = fetchRelativePath(path);
19477
}
19478
}
19479
19480
if (moduleType === "ts" || moduleType === "tsx") {
19481
try {
19482
const modulePromise = import(window._ojs.selfContained ?
19483
importPath :
19484
importPath.replace(/\.ts$/, ".js").replace(/\.tsx$/, ".js"));
19485
return es6ImportAsObservableModule(modulePromise, specs);
19486
} catch (e) {
19487
// record the error on the browser console to make debugging
19488
// slightly more convenient.
19489
console.error(e);
19490
throw e;
19491
}
19492
} else if (moduleType === "js") {
19493
try {
19494
const modulePromise = import(importPath);
19495
return es6ImportAsObservableModule(modulePromise, specs);
19496
} catch (e) {
19497
// record the error on the browser console to make debugging
19498
// slightly more convenient.
19499
console.error(e);
19500
throw e;
19501
}
19502
} else if (moduleType === "ojs") {
19503
return importOjsFromURL(fetchPath);
19504
} else if (moduleType === "qmd") {
19505
const htmlPath = `${fetchPath.slice(0, -4)}.html`;
19506
const response = await fetch(htmlPath);
19507
const text = await response.text();
19508
return createOjsModuleFromHTMLSrc(text);
19509
} else {
19510
throw new Error(`internal error, unrecognized module type ${moduleType}`);
19511
}
19512
};
19513
}
19514
19515
19516
function createOjsModuleFromHTMLSrc(text) {
19517
const parser = new DOMParser();
19518
const doc = parser.parseFromString(text, "text/html");
19519
const staticDefns = [];
19520
for (const el of doc.querySelectorAll('script[type="ojs-define"]')) {
19521
staticDefns.push(el.text);
19522
}
19523
const ojsSource = [];
19524
for (
19525
const content of doc.querySelectorAll('script[type="ojs-module-contents"]')
19526
) {
19527
for (const cell of JSON.parse(base64ToStr(content.text)).contents) {
19528
ojsSource.push(cell.source);
19529
}
19530
}
19531
return createOjsModuleFromSrc(ojsSource.join("\n"), staticDefns);
19532
}
19533
19534
function createOjsModuleFromSrc(src, staticDefns = []) {
19535
return (runtime, _observer) => {
19536
const newModule = runtime.module();
19537
const interpreter = window._ojs.ojsConnector.interpreter;
19538
interpreter.module(
19539
src,
19540
newModule,
19541
(_name) => new EmptyInspector(),
19542
);
19543
for (const defn of staticDefns) {
19544
for (const { name, value } of JSON.parse(defn).contents) {
19545
window._ojs.ojsConnector.define(name, newModule)(value);
19546
}
19547
}
19548
return newModule;
19549
};
19550
}
19551
19552
/*
19553
* Given a URL, fetches the text content and creates a new observable module
19554
* exporting all of the names as variables
19555
*/
19556
async function importOjsFromURL(path) {
19557
const r = await fetch(path);
19558
const src = await r.text();
19559
return createOjsModuleFromSrc(src);
19560
}
19561
19562
class OJSConnector {
19563
constructor({ paths, inspectorClass, library, allowPendingGlobals = false }) {
19564
this.library = library || new Library();
19565
19566
// this map contains a mapping from resource names to data URLs
19567
// that governs fileAttachment and import() resolutions in the
19568
// case of self-contained files.
19569
this.localResolverMap = new Map();
19570
// Keeps track of variables that have been requested by ojs code, but do
19571
// not exist (not in the module, not in the library, not on window).
19572
// The keys are variable names, the values are {promise, resolve, reject}.
19573
// This is intended to allow for a (hopefully brief) phase during startup
19574
// in which, if an ojs code chunk references a variable that is not defined,
19575
// instead of treating it as an "x is not defined" error we instead
19576
// take a wait-and-see approach, in case the variable dynamically becomes
19577
// defined later. When the phase ends, killPendingGlobals() must be called
19578
// so any variables that are still missing do cause "x is not defined"
19579
// errors.
19580
this.pendingGlobals = {};
19581
// When true, the mechanism described in the `this.pendingGlobals` comment
19582
// is used. When false, the result of accessing undefined variables is just
19583
// "x is not defined". This should be considered private, only settable via
19584
// constructor or `killPendingGlobals`.
19585
this.allowPendingGlobals = allowPendingGlobals;
19586
// NB it looks like Runtime makes a local copy of the library object,
19587
// such that mutating library after this is initializaed doesn't actually
19588
// work.
19589
this.runtime = new Runtime(this.library, (name) => this.global(name));
19590
this.mainModule = this.runtime.module();
19591
this.interpreter = new dist.exports.Interpreter({
19592
module: this.mainModule,
19593
resolveImportPath: importPathResolver(paths, this.localResolverMap),
19594
});
19595
this.inspectorClass = inspectorClass || Inspector;
19596
19597
// state to handle flash of unevaluated js because of async module imports
19598
this.mainModuleHasImports = false;
19599
this.mainModuleOutstandingImportCount = 0;
19600
this.chunkPromises = [];
19601
}
19602
19603
// Customizes the Runtime's behavior when an undefined variable is accessed.
19604
// This is needed for cases where the ojs graph is not all present at the
19605
// time of initialization; in particular, the case where a dependent cell
19606
// starts executing before one or more of its dependencies have been defined.
19607
// Without this customization, the user would see a flash of errors while the
19608
// graph is constructed; with this customization, the dependents stay blank
19609
// while they wait.
19610
global(name) {
19611
if (typeof window[name] !== "undefined") {
19612
return window[name];
19613
}
19614
if (!this.allowPendingGlobals) {
19615
return undefined;
19616
}
19617
19618
// deno-lint-ignore no-prototype-builtins
19619
if (!this.pendingGlobals.hasOwnProperty(name)) {
19620
// This is a pending global we haven't seen before. Stash a new promise,
19621
// along with its resolve/reject callbacks, in an object and remember it
19622
// for later.
19623
const info = {};
19624
info.promise = new Promise((resolve, reject) => {
19625
info.resolve = resolve;
19626
info.reject = reject;
19627
});
19628
this.pendingGlobals[name] = info;
19629
}
19630
return this.pendingGlobals[name].promise;
19631
}
19632
19633
// Signals the end of the "pending globals" phase. Any promises we've handed
19634
// out from the global() method now are rejected. (We never resolve these
19635
// promises to values; if these variables made an appearance, it would've
19636
// been as variables on modules.)
19637
killPendingGlobals() {
19638
this.allowPendingGlobals = false;
19639
for (const [name, { reject }] of Object.entries(this.pendingGlobals)) {
19640
reject(new RuntimeError(`${name} is not defined`));
19641
}
19642
}
19643
19644
setLocalResolver(map) {
19645
for (const [key, value] of Object.entries(map)) {
19646
this.localResolverMap.set(key, value);
19647
}
19648
}
19649
19650
define(name, module = undefined) {
19651
if (!module) {
19652
module = this.mainModule;
19653
}
19654
let change;
19655
const obs = this.library.Generators.observe((change_) => {
19656
change = change_;
19657
// TODO do something about destruction
19658
});
19659
module.variable().define(name, obs);
19660
return change;
19661
}
19662
19663
watch(name, k, module = undefined) {
19664
if (!module) {
19665
module = this.mainModule;
19666
}
19667
module.variable({
19668
fulfilled: (x) => k(x, name),
19669
}).define([name], (val) => val);
19670
}
19671
19672
async value(val, module = undefined) {
19673
if (!module) {
19674
module = this.mainModule;
19675
}
19676
const result = await module.value(val);
19677
return result;
19678
}
19679
19680
finishInterpreting() {
19681
return Promise.all(this.chunkPromises);
19682
}
19683
19684
interpretWithRunner(src, runner) {
19685
try {
19686
const parse = parseModule(src);
19687
const chunkPromise = Promise.all(parse.cells.map(runner));
19688
this.chunkPromises.push(chunkPromise);
19689
return chunkPromise;
19690
} catch (error) {
19691
return Promise.reject(error);
19692
}
19693
}
19694
19695
waitOnImports(cell, promise) {
19696
if (cell.body.type !== "ImportDeclaration") {
19697
return promise;
19698
} else {
19699
this.mainModuleHasImports = true;
19700
this.mainModuleOutstandingImportCount++;
19701
return promise.then((result) => {
19702
this.mainModuleOutstandingImportCount--;
19703
if (this.mainModuleOutstandingImportCount === 0) {
19704
this.clearImportModuleWait();
19705
}
19706
return result;
19707
});
19708
}
19709
}
19710
19711
interpretQuiet(src) {
19712
const runCell = (cell) => {
19713
const cellSrc = src.slice(cell.start, cell.end);
19714
const promise = this.interpreter.module(
19715
cellSrc,
19716
undefined,
19717
(_name) => new EmptyInspector(),
19718
);
19719
return this.waitOnImports(cell, promise);
19720
};
19721
return this.interpretWithRunner(src, runCell);
19722
}
19723
}
19724
19725
/*!
19726
* escape-html
19727
* Copyright(c) 2012-2013 TJ Holowaychuk
19728
* Copyright(c) 2015 Andreas Lubbe
19729
* Copyright(c) 2015 Tiancheng "Timothy" Gu
19730
* Copyright(c) 2022 RStudio, PBC
19731
*
19732
* MIT Licensed
19733
*
19734
* Minimal changes to make ES6
19735
*
19736
*/
19737
19738
var matchHtmlRegExp = /["'&<>]/;
19739
19740
/**
19741
* Escape special characters in the given string of text.
19742
*
19743
* @param {string} string The string to escape for inserting into HTML
19744
* @return {string}
19745
* @public
19746
*/
19747
19748
function escapeHtml (string) {
19749
var str = '' + string;
19750
var match = matchHtmlRegExp.exec(str);
19751
19752
if (!match) {
19753
return str
19754
}
19755
19756
var escape;
19757
var html = '';
19758
var index = 0;
19759
var lastIndex = 0;
19760
19761
for (index = match.index; index < str.length; index++) {
19762
switch (str.charCodeAt(index)) {
19763
case 34: // "
19764
escape = '&quot;';
19765
break
19766
case 38: // &
19767
escape = '&amp;';
19768
break
19769
case 39: // '
19770
escape = '&#39;';
19771
break
19772
case 60: // <
19773
escape = '&lt;';
19774
break
19775
case 62: // >
19776
escape = '&gt;';
19777
break
19778
default:
19779
continue
19780
}
19781
19782
if (lastIndex !== index) {
19783
html += str.substring(lastIndex, index);
19784
}
19785
19786
lastIndex = index + 1;
19787
html += escape;
19788
}
19789
19790
return lastIndex !== index
19791
? html + str.substring(lastIndex, index)
19792
: html
19793
}
19794
19795
function createHtmlElement(tag, attrs, ...children) {
19796
const el = document.createElement(tag);
19797
for (const [key, val] of Object.entries(attrs || {})) {
19798
el.setAttribute(key, val);
19799
}
19800
while (children.length) {
19801
const child = children.shift();
19802
if (Array.isArray(child)) {
19803
children.unshift(...child);
19804
} else if (child instanceof HTMLElement) {
19805
el.appendChild(child);
19806
} else {
19807
el.appendChild(document.createTextNode(escapeHtml(child)));
19808
}
19809
}
19810
return el;
19811
}
19812
19813
function createNamespacedElement(ns, tag, attrs, ...children) {
19814
const el = document.createElementNS(ns.namespace, tag);
19815
for (const [key, val] of Object.entries(attrs || {})) {
19816
el.setAttribute(key, val);
19817
}
19818
while (children.length) {
19819
const child = children.shift();
19820
if (Array.isArray(child)) {
19821
children.unshift(...child);
19822
} else if (child instanceof HTMLElement || child instanceof ns.class) {
19823
el.appendChild(child);
19824
} else {
19825
el.appendChild(document.createTextNode(escapeHtml(child)));
19826
}
19827
}
19828
return el;
19829
}
19830
19831
const resolver = {
19832
a: "svg",
19833
animate: "svg",
19834
animateMotion: "svg",
19835
animateTransform: "svg",
19836
circle: "svg",
19837
clipPath: "svg",
19838
defs: "svg",
19839
desc: "svg",
19840
discard: "svg",
19841
ellipse: "svg",
19842
feBlend: "svg",
19843
feColorMatrix: "svg",
19844
feComponentTransfer: "svg",
19845
feComposite: "svg",
19846
feConvolveMatrix: "svg",
19847
feDiffuseLighting: "svg",
19848
feDisplacementMap: "svg",
19849
feDistantLight: "svg",
19850
feDropShadow: "svg",
19851
feFlood: "svg",
19852
feFuncA: "svg",
19853
feFuncB: "svg",
19854
feFuncG: "svg",
19855
feFuncR: "svg",
19856
feGaussianBlur: "svg",
19857
feImage: "svg",
19858
feMerge: "svg",
19859
feMergeNode: "svg",
19860
feMorphology: "svg",
19861
feOffset: "svg",
19862
fePointLight: "svg",
19863
feSpecularLighting: "svg",
19864
feSpotLight: "svg",
19865
feTile: "svg",
19866
feTurbulence: "svg",
19867
filter: "svg",
19868
foreignObject: "svg",
19869
g: "svg",
19870
image: "svg",
19871
line: "svg",
19872
linearGradient: "svg",
19873
marker: "svg",
19874
mask: "svg",
19875
metadata: "svg",
19876
mpath: "svg",
19877
path: "svg",
19878
pattern: "svg",
19879
polygon: "svg",
19880
polyline: "svg",
19881
radialGradient: "svg",
19882
rect: "svg",
19883
script: "svg",
19884
set: "svg",
19885
stop: "svg",
19886
style: "svg",
19887
svg: "svg",
19888
switch: "svg",
19889
symbol: "svg",
19890
text: "svg",
19891
textPath: "svg",
19892
title: "svg",
19893
tspan: "svg",
19894
use: "svg",
19895
view: "svg",
19896
};
19897
19898
const nss = {
19899
"svg": { namespace: "http://www.w3.org/2000/svg", class: SVGElement }
19900
};
19901
19902
function resolveCreator(tag) {
19903
const nsKey = resolver[tag];
19904
if (nsKey === undefined) {
19905
return createHtmlElement;
19906
}
19907
const namespace = nss[nsKey];
19908
19909
return function(tag, attrs, ...children) {
19910
return createNamespacedElement(namespace, tag, attrs, ...children);
19911
}
19912
}
19913
19914
function createQuartoJsxShim()
19915
{
19916
return {
19917
createElement(tag, attrs, ...children) {
19918
if (typeof tag === "function") {
19919
return tag({...attrs, children });
19920
}
19921
19922
return resolveCreator(tag)(tag, attrs, ...children);
19923
}
19924
};
19925
}
19926
19927
/*
19928
Copyright (C) 2012-2014 Yusuke Suzuki <[email protected]>
19929
Copyright (C) 2015 Ingvar Stepanyan <[email protected]>
19930
Copyright (C) 2014 Ivan Nikulin <[email protected]>
19931
Copyright (C) 2012-2013 Michael Ficarra <[email protected]>
19932
Copyright (C) 2012-2013 Mathias Bynens <[email protected]>
19933
Copyright (C) 2013 Irakli Gozalishvili <[email protected]>
19934
Copyright (C) 2012 Robert Gust-Bardon <[email protected]>
19935
Copyright (C) 2012 John Freeman <[email protected]>
19936
Copyright (C) 2011-2012 Ariya Hidayat <[email protected]>
19937
Copyright (C) 2012 Joost-Wim Boekesteijn <[email protected]>
19938
Copyright (C) 2012 Kris Kowal <[email protected]>
19939
Copyright (C) 2012 Arpad Borsos <[email protected]>
19940
Copyright (C) 2020 Apple Inc. All rights reserved.
19941
Copyright (C) 2023 Posit, PBC.
19942
19943
This is a minimal modern single-file fork of escodegen, so that
19944
19945
1) we can use it in modern module-based JS environments
19946
2) we can extend the CodeGenerator prototype for the ability to
19947
support custom code generation for new AST nodes.
19948
19949
Redistribution and use in source and binary forms, with or without
19950
modification, are permitted provided that the following conditions are met:
19951
19952
* Redistributions of source code must retain the above copyright
19953
notice, this list of conditions and the following disclaimer.
19954
* Redistributions in binary form must reproduce the above copyright
19955
notice, this list of conditions and the following disclaimer in the
19956
documentation and/or other materials provided with the distribution.
19957
19958
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19959
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19960
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19961
ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
19962
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19963
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19964
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19965
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19966
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
19967
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19968
*/
19969
19970
let Precedence;
19971
19972
var BinaryPrecedence,
19973
esutils,
19974
base,
19975
indent,
19976
json,
19977
renumber,
19978
hexadecimal,
19979
quotes,
19980
escapeless,
19981
newline,
19982
space,
19983
parentheses,
19984
semicolons,
19985
safeConcatenation,
19986
directive,
19987
extra,
19988
parse,
19989
sourceMap,
19990
sourceCode,
19991
preserveBlankLines;
19992
19993
esutils = {
19994
code: {
19995
ES5Regex: {
19996
NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\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\u0561-\u0587\u05D0-\u05EA\u05F0-\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\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\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\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\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-\u1877\u1880-\u1884\u1887-\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\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\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\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\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\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\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-\uAB65\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]/,
19997
NonAsciiIdentifierPart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFB-\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\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/
19998
},
19999
ES6Regex: {
20000
NonAsciiIdentifierStart: /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\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\u0561-\u0587\u05D0-\u05EA\u05F0-\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\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\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\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\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-\u1877\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\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\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-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\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-\uAB65\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]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]/,
20001
NonAsciiIdentifierPart: /[\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\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\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFB-\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\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\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-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF30-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/
20002
},
20003
isDecimalDigit: function(ch) {
20004
return 48 <= ch && ch <= 57;
20005
},
20006
isHexDigit: function(ch) {
20007
return 48 <= ch && ch <= 57 || 97 <= ch && ch <= 102 || 65 <= ch && ch <= 70;
20008
},
20009
isOctalDigit: function(ch) {
20010
return ch >= 48 && ch <= 55;
20011
},
20012
NON_ASCII_WHITESPACES: [
20013
5760,
20014
8192,
20015
8193,
20016
8194,
20017
8195,
20018
8196,
20019
8197,
20020
8198,
20021
8199,
20022
8200,
20023
8201,
20024
8202,
20025
8239,
20026
8287,
20027
12288,
20028
65279
20029
],
20030
isWhiteSpace: function(ch) {
20031
return ch === 32 || ch === 9 || ch === 11 || ch === 12 || ch === 160 || ch >= 5760 && esutils.code.NON_ASCII_WHITESPACES.indexOf(ch) >= 0;
20032
},
20033
isLineTerminator: function(ch) {
20034
return ch === 10 || ch === 13 || ch === 8232 || ch === 8233;
20035
},
20036
fromCodePoint: function(cp) {
20037
if (cp <= 65535) {
20038
return String.fromCharCode(cp);
20039
}
20040
var cu1 = String.fromCharCode(Math.floor((cp - 65536) / 1024) + 55296);
20041
var cu2 = String.fromCharCode((cp - 65536) % 1024 + 56320);
20042
return cu1 + cu2;
20043
},
20044
IDENTIFIER_START: new Array(128),
20045
IDENTIFIER_PART: new Array(128),
20046
isIdentifierStartES5: function(ch) {
20047
return ch < 128 ? esutils.code.IDENTIFIER_START[ch] : esutils.code.ES5Regex.NonAsciiIdentifierStart.test(esutils.code.fromCodePoint(ch));
20048
},
20049
isIdentifierPartES5: function(ch) {
20050
return ch < 128 ? esutils.code.IDENTIFIER_PART[ch] : esutils.code.ES5Regex.NonAsciiIdentifierPart.test(esutils.code.fromCodePoint(ch));
20051
},
20052
isIdentifierStartES6: function(ch) {
20053
return ch < 128 ? esutils.code.IDENTIFIER_START[ch] : esutils.code.ES6Regex.NonAsciiIdentifierStart.test(esutils.code.fromCodePoint(ch));
20054
},
20055
isIdentifierPartES6: function(ch) {
20056
return ch < 128 ? esutils.code.IDENTIFIER_PART[ch] : esutils.code.ES6Regex.NonAsciiIdentifierPart.test(esutils.code.fromCodePoint(ch));
20057
}
20058
}
20059
};
20060
for (var ch = 0; ch < 128; ++ch) {
20061
esutils.code.IDENTIFIER_START[ch] = ch >= 97 && ch <= 122 || ch >= 65 && ch <= 90 || ch === 36 || ch === 95;
20062
}
20063
for (var ch = 0; ch < 128; ++ch) {
20064
esutils.code.IDENTIFIER_PART[ch] = ch >= 97 && ch <= 122 || ch >= 65 && ch <= 90 || ch >= 48 && ch <= 57 || ch === 36 || ch === 95;
20065
}
20066
20067
// Generation is done by generateExpression.
20068
function isExpression(node) {
20069
return CodeGenerator.Expression.hasOwnProperty(node.type);
20070
}
20071
20072
// Generation is done by generateStatement.
20073
function isStatement(node) {
20074
return CodeGenerator.Statement.hasOwnProperty(node.type);
20075
}
20076
20077
Precedence = {
20078
Sequence: 0,
20079
Yield: 1,
20080
Assignment: 1,
20081
Conditional: 2,
20082
ArrowFunction: 2,
20083
Coalesce: 3,
20084
LogicalOR: 4,
20085
LogicalAND: 5,
20086
BitwiseOR: 6,
20087
BitwiseXOR: 7,
20088
BitwiseAND: 8,
20089
Equality: 9,
20090
Relational: 10,
20091
BitwiseSHIFT: 11,
20092
Additive: 12,
20093
Multiplicative: 13,
20094
Exponentiation: 14,
20095
Await: 15,
20096
Unary: 15,
20097
Postfix: 16,
20098
OptionalChaining: 17,
20099
Call: 18,
20100
New: 19,
20101
TaggedTemplate: 20,
20102
Member: 21,
20103
Primary: 22
20104
};
20105
20106
BinaryPrecedence = {
20107
'??': Precedence.Coalesce,
20108
'||': Precedence.LogicalOR,
20109
'&&': Precedence.LogicalAND,
20110
'|': Precedence.BitwiseOR,
20111
'^': Precedence.BitwiseXOR,
20112
'&': Precedence.BitwiseAND,
20113
'==': Precedence.Equality,
20114
'!=': Precedence.Equality,
20115
'===': Precedence.Equality,
20116
'!==': Precedence.Equality,
20117
'is': Precedence.Equality,
20118
'isnt': Precedence.Equality,
20119
'<': Precedence.Relational,
20120
'>': Precedence.Relational,
20121
'<=': Precedence.Relational,
20122
'>=': Precedence.Relational,
20123
'in': Precedence.Relational,
20124
'instanceof': Precedence.Relational,
20125
'<<': Precedence.BitwiseSHIFT,
20126
'>>': Precedence.BitwiseSHIFT,
20127
'>>>': Precedence.BitwiseSHIFT,
20128
'+': Precedence.Additive,
20129
'-': Precedence.Additive,
20130
'*': Precedence.Multiplicative,
20131
'%': Precedence.Multiplicative,
20132
'/': Precedence.Multiplicative,
20133
'**': Precedence.Exponentiation
20134
};
20135
20136
//Flags
20137
var F_ALLOW_IN = 1,
20138
F_ALLOW_CALL = 1 << 1,
20139
F_ALLOW_UNPARATH_NEW = 1 << 2,
20140
F_FUNC_BODY = 1 << 3,
20141
F_DIRECTIVE_CTX = 1 << 4,
20142
F_SEMICOLON_OPT = 1 << 5,
20143
F_FOUND_COALESCE = 1 << 6;
20144
20145
//Expression flag sets
20146
//NOTE: Flag order:
20147
// F_ALLOW_IN
20148
// F_ALLOW_CALL
20149
// F_ALLOW_UNPARATH_NEW
20150
var E_FTT = F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW,
20151
E_TTF = F_ALLOW_IN | F_ALLOW_CALL,
20152
E_TTT = F_ALLOW_IN | F_ALLOW_CALL | F_ALLOW_UNPARATH_NEW,
20153
E_TFF = F_ALLOW_IN,
20154
E_FFT = F_ALLOW_UNPARATH_NEW,
20155
E_TFT = F_ALLOW_IN | F_ALLOW_UNPARATH_NEW;
20156
20157
//Statement flag sets
20158
//NOTE: Flag order:
20159
// F_ALLOW_IN
20160
// F_FUNC_BODY
20161
// F_DIRECTIVE_CTX
20162
// F_SEMICOLON_OPT
20163
var S_TFFF = F_ALLOW_IN,
20164
S_TFFT = F_ALLOW_IN | F_SEMICOLON_OPT,
20165
S_FFFF = 0x00,
20166
S_TFTF = F_ALLOW_IN | F_DIRECTIVE_CTX,
20167
S_TTFF = F_ALLOW_IN | F_FUNC_BODY;
20168
20169
function getDefaultOptions() {
20170
// default options
20171
return {
20172
indent: null,
20173
base: null,
20174
parse: null,
20175
comment: false,
20176
format: {
20177
indent: {
20178
style: ' ',
20179
base: 0,
20180
adjustMultilineComment: false
20181
},
20182
newline: '\n',
20183
space: ' ',
20184
json: false,
20185
renumber: false,
20186
hexadecimal: false,
20187
quotes: 'single',
20188
escapeless: false,
20189
compact: false,
20190
parentheses: true,
20191
semicolons: true,
20192
safeConcatenation: false,
20193
preserveBlankLines: false
20194
},
20195
moz: {
20196
comprehensionExpressionStartsWithAssignment: false,
20197
starlessGenerator: false
20198
},
20199
sourceMap: null,
20200
sourceMapRoot: null,
20201
sourceMapWithCode: false,
20202
directive: false,
20203
raw: true,
20204
verbatim: null,
20205
sourceCode: null
20206
};
20207
}
20208
20209
function stringRepeat(str, num) {
20210
var result = '';
20211
20212
for (num |= 0; num > 0; num >>>= 1, str += str) {
20213
if (num & 1) {
20214
result += str;
20215
}
20216
}
20217
20218
return result;
20219
}
20220
20221
function hasLineTerminator(str) {
20222
return (/[\r\n]/g).test(str);
20223
}
20224
20225
function endsWithLineTerminator(str) {
20226
var len = str.length;
20227
return len && esutils.code.isLineTerminator(str.charCodeAt(len - 1));
20228
}
20229
20230
function merge(target, override) {
20231
var key;
20232
for (key in override) {
20233
if (override.hasOwnProperty(key)) {
20234
target[key] = override[key];
20235
}
20236
}
20237
return target;
20238
}
20239
20240
function updateDeeply(target, override) {
20241
var key, val;
20242
20243
function isHashObject(target) {
20244
return typeof target === 'object' && target instanceof Object && !(target instanceof RegExp);
20245
}
20246
20247
for (key in override) {
20248
if (override.hasOwnProperty(key)) {
20249
val = override[key];
20250
if (isHashObject(val)) {
20251
if (isHashObject(target[key])) {
20252
updateDeeply(target[key], val);
20253
} else {
20254
target[key] = updateDeeply({}, val);
20255
}
20256
} else {
20257
target[key] = val;
20258
}
20259
}
20260
}
20261
return target;
20262
}
20263
20264
function generateNumber(value) {
20265
var result, point, temp, exponent, pos;
20266
20267
if (value !== value) {
20268
throw new Error('Numeric literal whose value is NaN');
20269
}
20270
if (value < 0 || (value === 0 && 1 / value < 0)) {
20271
throw new Error('Numeric literal whose value is negative');
20272
}
20273
20274
if (value === 1 / 0) {
20275
return json ? 'null' : renumber ? '1e400' : '1e+400';
20276
}
20277
20278
result = '' + value;
20279
if (!renumber || result.length < 3) {
20280
return result;
20281
}
20282
20283
point = result.indexOf('.');
20284
if (!json && result.charCodeAt(0) === 0x30 /* 0 */ && point === 1) {
20285
point = 0;
20286
result = result.slice(1);
20287
}
20288
temp = result;
20289
result = result.replace('e+', 'e');
20290
exponent = 0;
20291
if ((pos = temp.indexOf('e')) > 0) {
20292
exponent = +temp.slice(pos + 1);
20293
temp = temp.slice(0, pos);
20294
}
20295
if (point >= 0) {
20296
exponent -= temp.length - point - 1;
20297
temp = +(temp.slice(0, point) + temp.slice(point + 1)) + '';
20298
}
20299
pos = 0;
20300
while (temp.charCodeAt(temp.length + pos - 1) === 0x30 /* 0 */) {
20301
--pos;
20302
}
20303
if (pos !== 0) {
20304
exponent -= pos;
20305
temp = temp.slice(0, pos);
20306
}
20307
if (exponent !== 0) {
20308
temp += 'e' + exponent;
20309
}
20310
if ((temp.length < result.length ||
20311
(hexadecimal && value > 1e12 && Math.floor(value) === value && (temp = '0x' + value.toString(16)).length < result.length)) &&
20312
+temp === value) {
20313
result = temp;
20314
}
20315
20316
return result;
20317
}
20318
20319
// Generate valid RegExp expression.
20320
// This function is based on https://github.com/Constellation/iv Engine
20321
20322
function escapeRegExpCharacter(ch, previousIsBackslash) {
20323
// not handling '\' and handling \u2028 or \u2029 to unicode escape sequence
20324
if ((ch & ~1) === 0x2028) {
20325
return (previousIsBackslash ? 'u' : '\\u') + ((ch === 0x2028) ? '2028' : '2029');
20326
} else if (ch === 10 || ch === 13) { // \n, \r
20327
return (previousIsBackslash ? '' : '\\') + ((ch === 10) ? 'n' : 'r');
20328
}
20329
return String.fromCharCode(ch);
20330
}
20331
20332
function generateRegExp(reg) {
20333
var match, result, flags, i, iz, ch, characterInBrack, previousIsBackslash;
20334
20335
result = reg.toString();
20336
20337
if (reg.source) {
20338
// extract flag from toString result
20339
match = result.match(/\/([^/]*)$/);
20340
if (!match) {
20341
return result;
20342
}
20343
20344
flags = match[1];
20345
result = '';
20346
20347
characterInBrack = false;
20348
previousIsBackslash = false;
20349
for (i = 0, iz = reg.source.length; i < iz; ++i) {
20350
ch = reg.source.charCodeAt(i);
20351
20352
if (!previousIsBackslash) {
20353
if (characterInBrack) {
20354
if (ch === 93) { // ]
20355
characterInBrack = false;
20356
}
20357
} else {
20358
if (ch === 47) { // /
20359
result += '\\';
20360
} else if (ch === 91) { // [
20361
characterInBrack = true;
20362
}
20363
}
20364
result += escapeRegExpCharacter(ch, previousIsBackslash);
20365
previousIsBackslash = ch === 92; // \
20366
} else {
20367
// if new RegExp("\\\n') is provided, create /\n/
20368
result += escapeRegExpCharacter(ch, previousIsBackslash);
20369
// prevent like /\\[/]/
20370
previousIsBackslash = false;
20371
}
20372
}
20373
20374
return '/' + result + '/' + flags;
20375
}
20376
20377
return result;
20378
}
20379
20380
function escapeAllowedCharacter(code, next) {
20381
var hex;
20382
20383
if (code === 0x08 /* \b */) {
20384
return '\\b';
20385
}
20386
20387
if (code === 0x0C /* \f */) {
20388
return '\\f';
20389
}
20390
20391
if (code === 0x09 /* \t */) {
20392
return '\\t';
20393
}
20394
20395
hex = code.toString(16).toUpperCase();
20396
if (json || code > 0xFF) {
20397
return '\\u' + '0000'.slice(hex.length) + hex;
20398
} else if (code === 0x0000 && !esutils.code.isDecimalDigit(next)) {
20399
return '\\0';
20400
} else if (code === 0x000B /* \v */) { // '\v'
20401
return '\\x0B';
20402
} else {
20403
return '\\x' + '00'.slice(hex.length) + hex;
20404
}
20405
}
20406
20407
function escapeDisallowedCharacter(code) {
20408
if (code === 0x5C /* \ */) {
20409
return '\\\\';
20410
}
20411
20412
if (code === 0x0A /* \n */) {
20413
return '\\n';
20414
}
20415
20416
if (code === 0x0D /* \r */) {
20417
return '\\r';
20418
}
20419
20420
if (code === 0x2028) {
20421
return '\\u2028';
20422
}
20423
20424
if (code === 0x2029) {
20425
return '\\u2029';
20426
}
20427
20428
throw new Error('Incorrectly classified character');
20429
}
20430
20431
function escapeDirective(str) {
20432
var i, iz, code, quote;
20433
20434
quote = quotes === 'double' ? '"' : '\'';
20435
for (i = 0, iz = str.length; i < iz; ++i) {
20436
code = str.charCodeAt(i);
20437
if (code === 0x27 /* ' */) {
20438
quote = '"';
20439
break;
20440
} else if (code === 0x22 /* " */) {
20441
quote = '\'';
20442
break;
20443
} else if (code === 0x5C /* \ */) {
20444
++i;
20445
}
20446
}
20447
20448
return quote + str + quote;
20449
}
20450
20451
function escapeString(str) {
20452
var result = '', i, len, code, singleQuotes = 0, doubleQuotes = 0, single, quote;
20453
20454
for (i = 0, len = str.length; i < len; ++i) {
20455
code = str.charCodeAt(i);
20456
if (code === 0x27 /* ' */) {
20457
++singleQuotes;
20458
} else if (code === 0x22 /* " */) {
20459
++doubleQuotes;
20460
} else if (code === 0x2F /* / */ && json) {
20461
result += '\\';
20462
} else if (esutils.code.isLineTerminator(code) || code === 0x5C /* \ */) {
20463
result += escapeDisallowedCharacter(code);
20464
continue;
20465
} else if (!esutils.code.isIdentifierPartES5(code) && (json && code < 0x20 /* SP */ || !json && !escapeless && (code < 0x20 /* SP */ || code > 0x7E /* ~ */))) {
20466
result += escapeAllowedCharacter(code, str.charCodeAt(i + 1));
20467
continue;
20468
}
20469
result += String.fromCharCode(code);
20470
}
20471
20472
single = !(quotes === 'double' || (quotes === 'auto' && doubleQuotes < singleQuotes));
20473
quote = single ? '\'' : '"';
20474
20475
if (!(single ? singleQuotes : doubleQuotes)) {
20476
return quote + result + quote;
20477
}
20478
20479
str = result;
20480
result = quote;
20481
20482
for (i = 0, len = str.length; i < len; ++i) {
20483
code = str.charCodeAt(i);
20484
if ((code === 0x27 /* ' */ && single) || (code === 0x22 /* " */ && !single)) {
20485
result += '\\';
20486
}
20487
result += String.fromCharCode(code);
20488
}
20489
20490
return result + quote;
20491
}
20492
20493
/**
20494
* flatten an array to a string, where the array can contain
20495
* either strings or nested arrays
20496
*/
20497
function flattenToString(arr) {
20498
var i, iz, elem, result = '';
20499
for (i = 0, iz = arr.length; i < iz; ++i) {
20500
elem = arr[i];
20501
result += Array.isArray(elem) ? flattenToString(elem) : elem;
20502
}
20503
return result;
20504
}
20505
20506
function toSourceNodeWhenNeeded(generated) {
20507
// with no source maps, generated is either an
20508
// array or a string. if an array, flatten it.
20509
// if a string, just return it
20510
if (Array.isArray(generated)) {
20511
return flattenToString(generated);
20512
} else {
20513
return generated;
20514
}
20515
}
20516
20517
function noEmptySpace() {
20518
return (space) ? space : ' ';
20519
}
20520
20521
function join(left, right) {
20522
var leftSource,
20523
rightSource,
20524
leftCharCode,
20525
rightCharCode;
20526
20527
leftSource = toSourceNodeWhenNeeded(left).toString();
20528
if (leftSource.length === 0) {
20529
return [right];
20530
}
20531
20532
rightSource = toSourceNodeWhenNeeded(right).toString();
20533
if (rightSource.length === 0) {
20534
return [left];
20535
}
20536
20537
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
20538
rightCharCode = rightSource.charCodeAt(0);
20539
20540
if ((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode ||
20541
esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode) ||
20542
leftCharCode === 0x2F /* / */ && rightCharCode === 0x69 /* i */) { // infix word operators all start with `i`
20543
return [left, noEmptySpace(), right];
20544
} else if (esutils.code.isWhiteSpace(leftCharCode) || esutils.code.isLineTerminator(leftCharCode) ||
20545
esutils.code.isWhiteSpace(rightCharCode) || esutils.code.isLineTerminator(rightCharCode)) {
20546
return [left, right];
20547
}
20548
return [left, space, right];
20549
}
20550
20551
function addIndent(stmt) {
20552
return [base, stmt];
20553
}
20554
20555
function withIndent(fn) {
20556
var previousBase;
20557
previousBase = base;
20558
base += indent;
20559
fn(base);
20560
base = previousBase;
20561
}
20562
20563
function calculateSpaces(str) {
20564
var i;
20565
for (i = str.length - 1; i >= 0; --i) {
20566
if (esutils.code.isLineTerminator(str.charCodeAt(i))) {
20567
break;
20568
}
20569
}
20570
return (str.length - 1) - i;
20571
}
20572
20573
function adjustMultilineComment(value, specialBase) {
20574
var array, i, len, line, j, spaces, previousBase, sn;
20575
20576
array = value.split(/\r\n|[\r\n]/);
20577
spaces = Number.MAX_VALUE;
20578
20579
// first line doesn't have indentation
20580
for (i = 1, len = array.length; i < len; ++i) {
20581
line = array[i];
20582
j = 0;
20583
while (j < line.length && esutils.code.isWhiteSpace(line.charCodeAt(j))) {
20584
++j;
20585
}
20586
if (spaces > j) {
20587
spaces = j;
20588
}
20589
}
20590
20591
if (typeof specialBase !== 'undefined') {
20592
// pattern like
20593
// {
20594
// var t = 20; /*
20595
// * this is comment
20596
// */
20597
// }
20598
previousBase = base;
20599
if (array[1][spaces] === '*') {
20600
specialBase += ' ';
20601
}
20602
base = specialBase;
20603
} else {
20604
if (spaces & 1) {
20605
// /*
20606
// *
20607
// */
20608
// If spaces are odd number, above pattern is considered.
20609
// We waste 1 space.
20610
--spaces;
20611
}
20612
previousBase = base;
20613
}
20614
20615
for (i = 1, len = array.length; i < len; ++i) {
20616
sn = toSourceNodeWhenNeeded(addIndent(array[i].slice(spaces)));
20617
array[i] = sourceMap ? sn.join('') : sn;
20618
}
20619
20620
base = previousBase;
20621
20622
return array.join('\n');
20623
}
20624
20625
function generateComment(comment, specialBase) {
20626
if (comment.type === 'Line') {
20627
if (endsWithLineTerminator(comment.value)) {
20628
return '//' + comment.value;
20629
} else {
20630
// Always use LineTerminator
20631
var result = '//' + comment.value;
20632
if (!preserveBlankLines) {
20633
result += '\n';
20634
}
20635
return result;
20636
}
20637
}
20638
if (extra.format.indent.adjustMultilineComment && /[\n\r]/.test(comment.value)) {
20639
return adjustMultilineComment('/*' + comment.value + '*/', specialBase);
20640
}
20641
return '/*' + comment.value + '*/';
20642
}
20643
20644
function addComments(stmt, result) {
20645
var i, len, comment, save, tailingToStatement, specialBase, fragment,
20646
extRange, range, prevRange, prefix, infix, suffix, count;
20647
20648
if (stmt.leadingComments && stmt.leadingComments.length > 0) {
20649
save = result;
20650
20651
if (preserveBlankLines) {
20652
comment = stmt.leadingComments[0];
20653
result = [];
20654
20655
extRange = comment.extendedRange;
20656
range = comment.range;
20657
20658
prefix = sourceCode.substring(extRange[0], range[0]);
20659
count = (prefix.match(/\n/g) || []).length;
20660
if (count > 0) {
20661
result.push(stringRepeat('\n', count));
20662
result.push(addIndent(generateComment(comment)));
20663
} else {
20664
result.push(prefix);
20665
result.push(generateComment(comment));
20666
}
20667
20668
prevRange = range;
20669
20670
for (i = 1, len = stmt.leadingComments.length; i < len; i++) {
20671
comment = stmt.leadingComments[i];
20672
range = comment.range;
20673
20674
infix = sourceCode.substring(prevRange[1], range[0]);
20675
count = (infix.match(/\n/g) || []).length;
20676
result.push(stringRepeat('\n', count));
20677
result.push(addIndent(generateComment(comment)));
20678
20679
prevRange = range;
20680
}
20681
20682
suffix = sourceCode.substring(range[1], extRange[1]);
20683
count = (suffix.match(/\n/g) || []).length;
20684
result.push(stringRepeat('\n', count));
20685
} else {
20686
comment = stmt.leadingComments[0];
20687
result = [];
20688
if (safeConcatenation && stmt.type === "Program" && stmt.body.length === 0) {
20689
result.push('\n');
20690
}
20691
result.push(generateComment(comment));
20692
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
20693
result.push('\n');
20694
}
20695
20696
for (i = 1, len = stmt.leadingComments.length; i < len; ++i) {
20697
comment = stmt.leadingComments[i];
20698
fragment = [generateComment(comment)];
20699
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
20700
fragment.push('\n');
20701
}
20702
result.push(addIndent(fragment));
20703
}
20704
}
20705
20706
result.push(addIndent(save));
20707
}
20708
20709
if (stmt.trailingComments) {
20710
20711
if (preserveBlankLines) {
20712
comment = stmt.trailingComments[0];
20713
extRange = comment.extendedRange;
20714
range = comment.range;
20715
20716
prefix = sourceCode.substring(extRange[0], range[0]);
20717
count = (prefix.match(/\n/g) || []).length;
20718
20719
if (count > 0) {
20720
result.push(stringRepeat('\n', count));
20721
result.push(addIndent(generateComment(comment)));
20722
} else {
20723
result.push(prefix);
20724
result.push(generateComment(comment));
20725
}
20726
} else {
20727
tailingToStatement = !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString());
20728
specialBase = stringRepeat(' ', calculateSpaces(toSourceNodeWhenNeeded([base, result, indent]).toString()));
20729
for (i = 0, len = stmt.trailingComments.length; i < len; ++i) {
20730
comment = stmt.trailingComments[i];
20731
if (tailingToStatement) {
20732
// We assume target like following script
20733
//
20734
// var t = 20; /**
20735
// * This is comment of t
20736
// */
20737
if (i === 0) {
20738
// first case
20739
result = [result, indent];
20740
} else {
20741
result = [result, specialBase];
20742
}
20743
result.push(generateComment(comment, specialBase));
20744
} else {
20745
result = [result, addIndent(generateComment(comment))];
20746
}
20747
if (i !== len - 1 && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
20748
result = [result, '\n'];
20749
}
20750
}
20751
}
20752
}
20753
20754
return result;
20755
}
20756
20757
function generateBlankLines(start, end, result) {
20758
var j, newlineCount = 0;
20759
20760
for (j = start; j < end; j++) {
20761
if (sourceCode[j] === '\n') {
20762
newlineCount++;
20763
}
20764
}
20765
20766
for (j = 1; j < newlineCount; j++) {
20767
result.push(newline);
20768
}
20769
}
20770
20771
function parenthesize(text, current, should) {
20772
if (current < should) {
20773
return ['(', text, ')'];
20774
}
20775
return text;
20776
}
20777
20778
function generateVerbatimString(string) {
20779
var i, iz, result;
20780
result = string.split(/\r\n|\n/);
20781
for (i = 1, iz = result.length; i < iz; i++) {
20782
result[i] = newline + base + result[i];
20783
}
20784
return result;
20785
}
20786
20787
function generateVerbatim(expr, precedence) {
20788
var verbatim, result, prec;
20789
verbatim = expr[extra.verbatim];
20790
20791
if (typeof verbatim === 'string') {
20792
result = parenthesize(generateVerbatimString(verbatim), Precedence.Sequence, precedence);
20793
} else {
20794
// verbatim is object
20795
result = generateVerbatimString(verbatim.content);
20796
prec = (verbatim.precedence != null) ? verbatim.precedence : Precedence.Sequence;
20797
result = parenthesize(result, prec, precedence);
20798
}
20799
20800
return toSourceNodeWhenNeeded(result);
20801
}
20802
20803
function CodeGenerator() {
20804
}
20805
20806
// Helpers.
20807
20808
CodeGenerator.prototype.maybeBlock = function(stmt, flags) {
20809
var result, noLeadingComment, that = this;
20810
20811
noLeadingComment = !extra.comment || !stmt.leadingComments;
20812
20813
if (stmt.type === "BlockStatement" && noLeadingComment) {
20814
return [space, this.generateStatement(stmt, flags)];
20815
}
20816
20817
if (stmt.type === "EmptyStatement" && noLeadingComment) {
20818
return ';';
20819
}
20820
20821
withIndent(function () {
20822
result = [
20823
newline,
20824
addIndent(that.generateStatement(stmt, flags))
20825
];
20826
});
20827
20828
return result;
20829
};
20830
20831
CodeGenerator.prototype.maybeBlockSuffix = function (stmt, result) {
20832
var ends = endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString());
20833
if (stmt.type === "BlockStatement" && (!extra.comment || !stmt.leadingComments) && !ends) {
20834
return [result, space];
20835
}
20836
if (ends) {
20837
return [result, base];
20838
}
20839
return [result, newline, base];
20840
};
20841
20842
function generateIdentifier(node) {
20843
return toSourceNodeWhenNeeded(node.name);
20844
}
20845
20846
function generateAsyncPrefix(node, spaceRequired) {
20847
return node.async ? 'async' + (spaceRequired ? noEmptySpace() : space) : '';
20848
}
20849
20850
function generateStarSuffix(node) {
20851
var isGenerator = node.generator && !extra.moz.starlessGenerator;
20852
return isGenerator ? '*' + space : '';
20853
}
20854
20855
function generateMethodPrefix(prop) {
20856
var func = prop.value, prefix = '';
20857
if (func.async) {
20858
prefix += generateAsyncPrefix(func, !prop.computed);
20859
}
20860
if (func.generator) {
20861
// avoid space before method name
20862
prefix += generateStarSuffix(func) ? '*' : '';
20863
}
20864
return prefix;
20865
}
20866
20867
CodeGenerator.prototype.generatePattern = function (node, precedence, flags) {
20868
if (node.type === "Identifier") {
20869
return generateIdentifier(node);
20870
}
20871
return this.generateExpression(node, precedence, flags);
20872
};
20873
20874
CodeGenerator.prototype.generateFunctionParams = function (node) {
20875
var i, iz, result, hasDefault;
20876
20877
hasDefault = false;
20878
20879
if (node.type === "ArrowFunctionExpression" &&
20880
!node.rest && (!node.defaults || node.defaults.length === 0) &&
20881
node.params.length === 1 && node.params[0].type === "Identifier") {
20882
// arg => { } case
20883
result = [generateAsyncPrefix(node, true), generateIdentifier(node.params[0])];
20884
} else {
20885
result = node.type === "ArrowFunctionExpression"? [generateAsyncPrefix(node, false)] : [];
20886
result.push('(');
20887
if (node.defaults) {
20888
hasDefault = true;
20889
}
20890
for (i = 0, iz = node.params.length; i < iz; ++i) {
20891
if (hasDefault && node.defaults[i]) {
20892
// Handle default values.
20893
result.push(this.generateAssignment(node.params[i], node.defaults[i], '=', Precedence.Assignment, E_TTT));
20894
} else {
20895
result.push(this.generatePattern(node.params[i], Precedence.Assignment, E_TTT));
20896
}
20897
if (i + 1 < iz) {
20898
result.push(',' + space);
20899
}
20900
}
20901
20902
if (node.rest) {
20903
if (node.params.length) {
20904
result.push(',' + space);
20905
}
20906
result.push('...');
20907
result.push(generateIdentifier(node.rest));
20908
}
20909
20910
result.push(')');
20911
}
20912
20913
return result;
20914
};
20915
20916
CodeGenerator.prototype.generateFunctionBody = function (node) {
20917
var result, expr;
20918
20919
result = this.generateFunctionParams(node);
20920
20921
if (node.type === "ArrowFunctionExpression") {
20922
result.push(space);
20923
result.push('=>');
20924
}
20925
20926
if (node.expression) {
20927
result.push(space);
20928
expr = this.generateExpression(node.body, Precedence.Assignment, E_TTT);
20929
if (expr.toString().charAt(0) === '{') {
20930
expr = ['(', expr, ')'];
20931
}
20932
result.push(expr);
20933
} else {
20934
result.push(this.maybeBlock(node.body, S_TTFF));
20935
}
20936
20937
return result;
20938
};
20939
20940
CodeGenerator.prototype.generateIterationForStatement = function (operator, stmt, flags) {
20941
var result = ['for' + (stmt.await ? noEmptySpace() + 'await' : '') + space + '('], that = this;
20942
withIndent(function () {
20943
if (stmt.left.type === "VariableDeclaration") {
20944
withIndent(function () {
20945
result.push(stmt.left.kind + noEmptySpace());
20946
result.push(that.generateStatement(stmt.left.declarations[0], S_FFFF));
20947
});
20948
} else {
20949
result.push(that.generateExpression(stmt.left, Precedence.Call, E_TTT));
20950
}
20951
20952
result = join(result, operator);
20953
result = [join(
20954
result,
20955
that.generateExpression(stmt.right, Precedence.Assignment, E_TTT)
20956
), ')'];
20957
});
20958
result.push(this.maybeBlock(stmt.body, flags));
20959
return result;
20960
};
20961
20962
CodeGenerator.prototype.generatePropertyKey = function (expr, computed) {
20963
var result = [];
20964
20965
if (computed) {
20966
result.push('[');
20967
}
20968
20969
result.push(this.generateExpression(expr, Precedence.Assignment, E_TTT));
20970
20971
if (computed) {
20972
result.push(']');
20973
}
20974
20975
return result;
20976
};
20977
20978
CodeGenerator.prototype.generateAssignment = function (left, right, operator, precedence, flags) {
20979
if (Precedence.Assignment < precedence) {
20980
flags |= F_ALLOW_IN;
20981
}
20982
20983
return parenthesize(
20984
[
20985
this.generateExpression(left, Precedence.Call, flags),
20986
space + operator + space,
20987
this.generateExpression(right, Precedence.Assignment, flags)
20988
],
20989
Precedence.Assignment,
20990
precedence
20991
);
20992
};
20993
20994
CodeGenerator.prototype.semicolon = function (flags) {
20995
if (!semicolons && flags & F_SEMICOLON_OPT) {
20996
return '';
20997
}
20998
return ';';
20999
};
21000
21001
// Statements.
21002
21003
CodeGenerator.Statement = {
21004
21005
BlockStatement: function (stmt, flags) {
21006
var range, content, result = ['{', newline], that = this;
21007
21008
withIndent(function () {
21009
// handle functions without any code
21010
if (stmt.body.length === 0 && preserveBlankLines) {
21011
range = stmt.range;
21012
if (range[1] - range[0] > 2) {
21013
content = sourceCode.substring(range[0] + 1, range[1] - 1);
21014
if (content[0] === '\n') {
21015
result = ['{'];
21016
}
21017
result.push(content);
21018
}
21019
}
21020
21021
var i, iz, fragment, bodyFlags;
21022
bodyFlags = S_TFFF;
21023
if (flags & F_FUNC_BODY) {
21024
bodyFlags |= F_DIRECTIVE_CTX;
21025
}
21026
21027
for (i = 0, iz = stmt.body.length; i < iz; ++i) {
21028
if (preserveBlankLines) {
21029
// handle spaces before the first line
21030
if (i === 0) {
21031
if (stmt.body[0].leadingComments) {
21032
range = stmt.body[0].leadingComments[0].extendedRange;
21033
content = sourceCode.substring(range[0], range[1]);
21034
if (content[0] === '\n') {
21035
result = ['{'];
21036
}
21037
}
21038
if (!stmt.body[0].leadingComments) {
21039
generateBlankLines(stmt.range[0], stmt.body[0].range[0], result);
21040
}
21041
}
21042
21043
// handle spaces between lines
21044
if (i > 0) {
21045
if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) {
21046
generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result);
21047
}
21048
}
21049
}
21050
21051
if (i === iz - 1) {
21052
bodyFlags |= F_SEMICOLON_OPT;
21053
}
21054
21055
if (stmt.body[i].leadingComments && preserveBlankLines) {
21056
fragment = that.generateStatement(stmt.body[i], bodyFlags);
21057
} else {
21058
fragment = addIndent(that.generateStatement(stmt.body[i], bodyFlags));
21059
}
21060
21061
result.push(fragment);
21062
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
21063
if (preserveBlankLines && i < iz - 1) {
21064
// don't add a new line if there are leading coments
21065
// in the next statement
21066
if (!stmt.body[i + 1].leadingComments) {
21067
result.push(newline);
21068
}
21069
} else {
21070
result.push(newline);
21071
}
21072
}
21073
21074
if (preserveBlankLines) {
21075
// handle spaces after the last line
21076
if (i === iz - 1) {
21077
if (!stmt.body[i].trailingComments) {
21078
generateBlankLines(stmt.body[i].range[1], stmt.range[1], result);
21079
}
21080
}
21081
}
21082
}
21083
});
21084
21085
result.push(addIndent('}'));
21086
return result;
21087
},
21088
21089
BreakStatement: function (stmt, flags) {
21090
if (stmt.label) {
21091
return 'break ' + stmt.label.name + this.semicolon(flags);
21092
}
21093
return 'break' + this.semicolon(flags);
21094
},
21095
21096
ContinueStatement: function (stmt, flags) {
21097
if (stmt.label) {
21098
return 'continue ' + stmt.label.name + this.semicolon(flags);
21099
}
21100
return 'continue' + this.semicolon(flags);
21101
},
21102
21103
ClassBody: function (stmt, flags) {
21104
var result = [ '{', newline], that = this;
21105
21106
withIndent(function (indent) {
21107
var i, iz;
21108
21109
for (i = 0, iz = stmt.body.length; i < iz; ++i) {
21110
result.push(indent);
21111
result.push(that.generateExpression(stmt.body[i], Precedence.Sequence, E_TTT));
21112
if (i + 1 < iz) {
21113
result.push(newline);
21114
}
21115
}
21116
});
21117
21118
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
21119
result.push(newline);
21120
}
21121
result.push(base);
21122
result.push('}');
21123
return result;
21124
},
21125
21126
ClassDeclaration: function (stmt, flags) {
21127
var result, fragment;
21128
result = ['class'];
21129
if (stmt.id) {
21130
result = join(result, this.generateExpression(stmt.id, Precedence.Sequence, E_TTT));
21131
}
21132
if (stmt.superClass) {
21133
fragment = join('extends', this.generateExpression(stmt.superClass, Precedence.Unary, E_TTT));
21134
result = join(result, fragment);
21135
}
21136
result.push(space);
21137
result.push(this.generateStatement(stmt.body, S_TFFT));
21138
return result;
21139
},
21140
21141
DirectiveStatement: function (stmt, flags) {
21142
if (extra.raw && stmt.raw) {
21143
return stmt.raw + this.semicolon(flags);
21144
}
21145
return escapeDirective(stmt.directive) + this.semicolon(flags);
21146
},
21147
21148
DoWhileStatement: function (stmt, flags) {
21149
// Because `do 42 while (cond)` is Syntax Error. We need semicolon.
21150
var result = join('do', this.maybeBlock(stmt.body, S_TFFF));
21151
result = this.maybeBlockSuffix(stmt.body, result);
21152
return join(result, [
21153
'while' + space + '(',
21154
this.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
21155
')' + this.semicolon(flags)
21156
]);
21157
},
21158
21159
CatchClause: function (stmt, flags) {
21160
var result, that = this;
21161
withIndent(function () {
21162
var guard;
21163
21164
if (stmt.param) {
21165
result = [
21166
'catch' + space + '(',
21167
that.generateExpression(stmt.param, Precedence.Sequence, E_TTT),
21168
')'
21169
];
21170
21171
if (stmt.guard) {
21172
guard = that.generateExpression(stmt.guard, Precedence.Sequence, E_TTT);
21173
result.splice(2, 0, ' if ', guard);
21174
}
21175
} else {
21176
result = ['catch'];
21177
}
21178
});
21179
result.push(this.maybeBlock(stmt.body, S_TFFF));
21180
return result;
21181
},
21182
21183
DebuggerStatement: function (stmt, flags) {
21184
return 'debugger' + this.semicolon(flags);
21185
},
21186
21187
EmptyStatement: function (stmt, flags) {
21188
return ';';
21189
},
21190
21191
ExportDefaultDeclaration: function (stmt, flags) {
21192
var result = [ 'export' ], bodyFlags;
21193
21194
bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF;
21195
21196
// export default HoistableDeclaration[Default]
21197
// export default AssignmentExpression[In] ;
21198
result = join(result, 'default');
21199
if (isStatement(stmt.declaration)) {
21200
result = join(result, this.generateStatement(stmt.declaration, bodyFlags));
21201
} else {
21202
result = join(result, this.generateExpression(stmt.declaration, Precedence.Assignment, E_TTT) + this.semicolon(flags));
21203
}
21204
return result;
21205
},
21206
21207
ExportNamedDeclaration: function (stmt, flags) {
21208
var result = [ 'export' ], bodyFlags, that = this;
21209
21210
bodyFlags = (flags & F_SEMICOLON_OPT) ? S_TFFT : S_TFFF;
21211
21212
// export VariableStatement
21213
// export Declaration[Default]
21214
if (stmt.declaration) {
21215
return join(result, this.generateStatement(stmt.declaration, bodyFlags));
21216
}
21217
21218
// export ExportClause[NoReference] FromClause ;
21219
// export ExportClause ;
21220
if (stmt.specifiers) {
21221
if (stmt.specifiers.length === 0) {
21222
result = join(result, '{' + space + '}');
21223
} else if (stmt.specifiers[0].type === "ExportBatchSpecifier") {
21224
result = join(result, this.generateExpression(stmt.specifiers[0], Precedence.Sequence, E_TTT));
21225
} else {
21226
result = join(result, '{');
21227
withIndent(function (indent) {
21228
var i, iz;
21229
result.push(newline);
21230
for (i = 0, iz = stmt.specifiers.length; i < iz; ++i) {
21231
result.push(indent);
21232
result.push(that.generateExpression(stmt.specifiers[i], Precedence.Sequence, E_TTT));
21233
if (i + 1 < iz) {
21234
result.push(',' + newline);
21235
}
21236
}
21237
});
21238
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
21239
result.push(newline);
21240
}
21241
result.push(base + '}');
21242
}
21243
21244
if (stmt.source) {
21245
result = join(result, [
21246
'from' + space,
21247
// ModuleSpecifier
21248
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
21249
this.semicolon(flags)
21250
]);
21251
} else {
21252
result.push(this.semicolon(flags));
21253
}
21254
}
21255
return result;
21256
},
21257
21258
ExportAllDeclaration: function (stmt, flags) {
21259
// export * FromClause ;
21260
return [
21261
'export' + space,
21262
'*' + space,
21263
'from' + space,
21264
// ModuleSpecifier
21265
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
21266
this.semicolon(flags)
21267
];
21268
},
21269
21270
ExpressionStatement: function (stmt, flags) {
21271
var result, fragment;
21272
21273
function isClassPrefixed(fragment) {
21274
var code;
21275
if (fragment.slice(0, 5) !== 'class') {
21276
return false;
21277
}
21278
code = fragment.charCodeAt(5);
21279
return code === 0x7B /* '{' */ || esutils.code.isWhiteSpace(code) || esutils.code.isLineTerminator(code);
21280
}
21281
21282
function isFunctionPrefixed(fragment) {
21283
var code;
21284
if (fragment.slice(0, 8) !== 'function') {
21285
return false;
21286
}
21287
code = fragment.charCodeAt(8);
21288
return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code);
21289
}
21290
21291
function isAsyncPrefixed(fragment) {
21292
var code, i, iz;
21293
if (fragment.slice(0, 5) !== 'async') {
21294
return false;
21295
}
21296
if (!esutils.code.isWhiteSpace(fragment.charCodeAt(5))) {
21297
return false;
21298
}
21299
for (i = 6, iz = fragment.length; i < iz; ++i) {
21300
if (!esutils.code.isWhiteSpace(fragment.charCodeAt(i))) {
21301
break;
21302
}
21303
}
21304
if (i === iz) {
21305
return false;
21306
}
21307
if (fragment.slice(i, i + 8) !== 'function') {
21308
return false;
21309
}
21310
code = fragment.charCodeAt(i + 8);
21311
return code === 0x28 /* '(' */ || esutils.code.isWhiteSpace(code) || code === 0x2A /* '*' */ || esutils.code.isLineTerminator(code);
21312
}
21313
21314
result = [this.generateExpression(stmt.expression, Precedence.Sequence, E_TTT)];
21315
// 12.4 '{', 'function', 'class' is not allowed in this position.
21316
// wrap expression with parentheses
21317
fragment = toSourceNodeWhenNeeded(result).toString();
21318
if (fragment.charCodeAt(0) === 0x7B /* '{' */ || // ObjectExpression
21319
isClassPrefixed(fragment) ||
21320
isFunctionPrefixed(fragment) ||
21321
isAsyncPrefixed(fragment) ||
21322
(directive && (flags & F_DIRECTIVE_CTX) && stmt.expression.type === "Literal" && typeof stmt.expression.value === 'string')) {
21323
result = ['(', result, ')' + this.semicolon(flags)];
21324
} else {
21325
result.push(this.semicolon(flags));
21326
}
21327
return result;
21328
},
21329
21330
ImportDeclaration: function (stmt, flags) {
21331
// ES6: 15.2.1 valid import declarations:
21332
// - import ImportClause FromClause ;
21333
// - import ModuleSpecifier ;
21334
var result, cursor, that = this;
21335
21336
// If no ImportClause is present,
21337
// this should be `import ModuleSpecifier` so skip `from`
21338
// ModuleSpecifier is StringLiteral.
21339
if (stmt.specifiers.length === 0) {
21340
// import ModuleSpecifier ;
21341
return [
21342
'import',
21343
space,
21344
// ModuleSpecifier
21345
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
21346
this.semicolon(flags)
21347
];
21348
}
21349
21350
// import ImportClause FromClause ;
21351
result = [
21352
'import'
21353
];
21354
cursor = 0;
21355
21356
// ImportedBinding
21357
if (stmt.specifiers[cursor].type === "ImportDefaultSpecifier") {
21358
result = join(result, [
21359
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
21360
]);
21361
++cursor;
21362
}
21363
21364
if (stmt.specifiers[cursor]) {
21365
if (cursor !== 0) {
21366
result.push(',');
21367
}
21368
21369
if (stmt.specifiers[cursor].type === "ImportNamespaceSpecifier") {
21370
// NameSpaceImport
21371
result = join(result, [
21372
space,
21373
this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT)
21374
]);
21375
} else {
21376
// NamedImports
21377
result.push(space + '{');
21378
21379
if ((stmt.specifiers.length - cursor) === 1) {
21380
// import { ... } from "...";
21381
result.push(space);
21382
result.push(this.generateExpression(stmt.specifiers[cursor], Precedence.Sequence, E_TTT));
21383
result.push(space + '}' + space);
21384
} else {
21385
// import {
21386
// ...,
21387
// ...,
21388
// } from "...";
21389
withIndent(function (indent) {
21390
var i, iz;
21391
result.push(newline);
21392
for (i = cursor, iz = stmt.specifiers.length; i < iz; ++i) {
21393
result.push(indent);
21394
result.push(that.generateExpression(stmt.specifiers[i], Precedence.Sequence, E_TTT));
21395
if (i + 1 < iz) {
21396
result.push(',' + newline);
21397
}
21398
}
21399
});
21400
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
21401
result.push(newline);
21402
}
21403
result.push(base + '}' + space);
21404
}
21405
}
21406
}
21407
21408
result = join(result, [
21409
'from' + space,
21410
// ModuleSpecifier
21411
this.generateExpression(stmt.source, Precedence.Sequence, E_TTT),
21412
this.semicolon(flags)
21413
]);
21414
return result;
21415
},
21416
21417
VariableDeclarator: function (stmt, flags) {
21418
var itemFlags = (flags & F_ALLOW_IN) ? E_TTT : E_FTT;
21419
if (stmt.init) {
21420
return [
21421
this.generateExpression(stmt.id, Precedence.Assignment, itemFlags),
21422
space,
21423
'=',
21424
space,
21425
this.generateExpression(stmt.init, Precedence.Assignment, itemFlags)
21426
];
21427
}
21428
return this.generatePattern(stmt.id, Precedence.Assignment, itemFlags);
21429
},
21430
21431
VariableDeclaration: function (stmt, flags) {
21432
// VariableDeclarator is typed as Statement,
21433
// but joined with comma (not LineTerminator).
21434
// So if comment is attached to target node, we should specialize.
21435
var result, i, iz, node, bodyFlags, that = this;
21436
21437
result = [ stmt.kind ];
21438
21439
bodyFlags = (flags & F_ALLOW_IN) ? S_TFFF : S_FFFF;
21440
21441
function block() {
21442
node = stmt.declarations[0];
21443
if (extra.comment && node.leadingComments) {
21444
result.push('\n');
21445
result.push(addIndent(that.generateStatement(node, bodyFlags)));
21446
} else {
21447
result.push(noEmptySpace());
21448
result.push(that.generateStatement(node, bodyFlags));
21449
}
21450
21451
for (i = 1, iz = stmt.declarations.length; i < iz; ++i) {
21452
node = stmt.declarations[i];
21453
if (extra.comment && node.leadingComments) {
21454
result.push(',' + newline);
21455
result.push(addIndent(that.generateStatement(node, bodyFlags)));
21456
} else {
21457
result.push(',' + space);
21458
result.push(that.generateStatement(node, bodyFlags));
21459
}
21460
}
21461
}
21462
21463
if (stmt.declarations.length > 1) {
21464
withIndent(block);
21465
} else {
21466
block();
21467
}
21468
21469
result.push(this.semicolon(flags));
21470
21471
return result;
21472
},
21473
21474
ThrowStatement: function (stmt, flags) {
21475
return [join(
21476
'throw',
21477
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
21478
), this.semicolon(flags)];
21479
},
21480
21481
TryStatement: function (stmt, flags) {
21482
var result, i, iz, guardedHandlers;
21483
21484
result = ['try', this.maybeBlock(stmt.block, S_TFFF)];
21485
result = this.maybeBlockSuffix(stmt.block, result);
21486
21487
if (stmt.handlers) {
21488
// old interface
21489
for (i = 0, iz = stmt.handlers.length; i < iz; ++i) {
21490
result = join(result, this.generateStatement(stmt.handlers[i], S_TFFF));
21491
if (stmt.finalizer || i + 1 !== iz) {
21492
result = this.maybeBlockSuffix(stmt.handlers[i].body, result);
21493
}
21494
}
21495
} else {
21496
guardedHandlers = stmt.guardedHandlers || [];
21497
21498
for (i = 0, iz = guardedHandlers.length; i < iz; ++i) {
21499
result = join(result, this.generateStatement(guardedHandlers[i], S_TFFF));
21500
if (stmt.finalizer || i + 1 !== iz) {
21501
result = this.maybeBlockSuffix(guardedHandlers[i].body, result);
21502
}
21503
}
21504
21505
// new interface
21506
if (stmt.handler) {
21507
if (Array.isArray(stmt.handler)) {
21508
for (i = 0, iz = stmt.handler.length; i < iz; ++i) {
21509
result = join(result, this.generateStatement(stmt.handler[i], S_TFFF));
21510
if (stmt.finalizer || i + 1 !== iz) {
21511
result = this.maybeBlockSuffix(stmt.handler[i].body, result);
21512
}
21513
}
21514
} else {
21515
result = join(result, this.generateStatement(stmt.handler, S_TFFF));
21516
if (stmt.finalizer) {
21517
result = this.maybeBlockSuffix(stmt.handler.body, result);
21518
}
21519
}
21520
}
21521
}
21522
if (stmt.finalizer) {
21523
result = join(result, ['finally', this.maybeBlock(stmt.finalizer, S_TFFF)]);
21524
}
21525
return result;
21526
},
21527
21528
SwitchStatement: function (stmt, flags) {
21529
var result, fragment, i, iz, bodyFlags, that = this;
21530
withIndent(function () {
21531
result = [
21532
'switch' + space + '(',
21533
that.generateExpression(stmt.discriminant, Precedence.Sequence, E_TTT),
21534
')' + space + '{' + newline
21535
];
21536
});
21537
if (stmt.cases) {
21538
bodyFlags = S_TFFF;
21539
for (i = 0, iz = stmt.cases.length; i < iz; ++i) {
21540
if (i === iz - 1) {
21541
bodyFlags |= F_SEMICOLON_OPT;
21542
}
21543
fragment = addIndent(this.generateStatement(stmt.cases[i], bodyFlags));
21544
result.push(fragment);
21545
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
21546
result.push(newline);
21547
}
21548
}
21549
}
21550
result.push(addIndent('}'));
21551
return result;
21552
},
21553
21554
SwitchCase: function (stmt, flags) {
21555
var result, fragment, i, iz, bodyFlags, that = this;
21556
withIndent(function () {
21557
if (stmt.test) {
21558
result = [
21559
join('case', that.generateExpression(stmt.test, Precedence.Sequence, E_TTT)),
21560
':'
21561
];
21562
} else {
21563
result = ['default:'];
21564
}
21565
21566
i = 0;
21567
iz = stmt.consequent.length;
21568
if (iz && stmt.consequent[0].type === "BlockStatement") {
21569
fragment = that.maybeBlock(stmt.consequent[0], S_TFFF);
21570
result.push(fragment);
21571
i = 1;
21572
}
21573
21574
if (i !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
21575
result.push(newline);
21576
}
21577
21578
bodyFlags = S_TFFF;
21579
for (; i < iz; ++i) {
21580
if (i === iz - 1 && flags & F_SEMICOLON_OPT) {
21581
bodyFlags |= F_SEMICOLON_OPT;
21582
}
21583
fragment = addIndent(that.generateStatement(stmt.consequent[i], bodyFlags));
21584
result.push(fragment);
21585
if (i + 1 !== iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
21586
result.push(newline);
21587
}
21588
}
21589
});
21590
return result;
21591
},
21592
21593
IfStatement: function (stmt, flags) {
21594
var result, bodyFlags, semicolonOptional, that = this;
21595
withIndent(function () {
21596
result = [
21597
'if' + space + '(',
21598
that.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
21599
')'
21600
];
21601
});
21602
semicolonOptional = flags & F_SEMICOLON_OPT;
21603
bodyFlags = S_TFFF;
21604
if (semicolonOptional) {
21605
bodyFlags |= F_SEMICOLON_OPT;
21606
}
21607
if (stmt.alternate) {
21608
result.push(this.maybeBlock(stmt.consequent, S_TFFF));
21609
result = this.maybeBlockSuffix(stmt.consequent, result);
21610
if (stmt.alternate.type === "IfStatement") {
21611
result = join(result, ['else ', this.generateStatement(stmt.alternate, bodyFlags)]);
21612
} else {
21613
result = join(result, join('else', this.maybeBlock(stmt.alternate, bodyFlags)));
21614
}
21615
} else {
21616
result.push(this.maybeBlock(stmt.consequent, bodyFlags));
21617
}
21618
return result;
21619
},
21620
21621
ForStatement: function (stmt, flags) {
21622
var result, that = this;
21623
withIndent(function () {
21624
result = ['for' + space + '('];
21625
if (stmt.init) {
21626
if (stmt.init.type === "VariableDeclaration") {
21627
result.push(that.generateStatement(stmt.init, S_FFFF));
21628
} else {
21629
// F_ALLOW_IN becomes false.
21630
result.push(that.generateExpression(stmt.init, Precedence.Sequence, E_FTT));
21631
result.push(';');
21632
}
21633
} else {
21634
result.push(';');
21635
}
21636
21637
if (stmt.test) {
21638
result.push(space);
21639
result.push(that.generateExpression(stmt.test, Precedence.Sequence, E_TTT));
21640
result.push(';');
21641
} else {
21642
result.push(';');
21643
}
21644
21645
if (stmt.update) {
21646
result.push(space);
21647
result.push(that.generateExpression(stmt.update, Precedence.Sequence, E_TTT));
21648
result.push(')');
21649
} else {
21650
result.push(')');
21651
}
21652
});
21653
21654
result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF));
21655
return result;
21656
},
21657
21658
ForInStatement: function (stmt, flags) {
21659
return this.generateIterationForStatement('in', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF);
21660
},
21661
21662
ForOfStatement: function (stmt, flags) {
21663
return this.generateIterationForStatement('of', stmt, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF);
21664
},
21665
21666
LabeledStatement: function (stmt, flags) {
21667
return [stmt.label.name + ':', this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF)];
21668
},
21669
21670
Program: function (stmt, flags) {
21671
var result, fragment, i, iz, bodyFlags;
21672
iz = stmt.body.length;
21673
result = [safeConcatenation && iz > 0 ? '\n' : ''];
21674
bodyFlags = S_TFTF;
21675
for (i = 0; i < iz; ++i) {
21676
if (!safeConcatenation && i === iz - 1) {
21677
bodyFlags |= F_SEMICOLON_OPT;
21678
}
21679
21680
if (preserveBlankLines) {
21681
// handle spaces before the first line
21682
if (i === 0) {
21683
if (!stmt.body[0].leadingComments) {
21684
generateBlankLines(stmt.range[0], stmt.body[i].range[0], result);
21685
}
21686
}
21687
21688
// handle spaces between lines
21689
if (i > 0) {
21690
if (!stmt.body[i - 1].trailingComments && !stmt.body[i].leadingComments) {
21691
generateBlankLines(stmt.body[i - 1].range[1], stmt.body[i].range[0], result);
21692
}
21693
}
21694
}
21695
21696
fragment = addIndent(this.generateStatement(stmt.body[i], bodyFlags));
21697
result.push(fragment);
21698
if (i + 1 < iz && !endsWithLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
21699
if (preserveBlankLines) {
21700
if (!stmt.body[i + 1].leadingComments) {
21701
result.push(newline);
21702
}
21703
} else {
21704
result.push(newline);
21705
}
21706
}
21707
21708
if (preserveBlankLines) {
21709
// handle spaces after the last line
21710
if (i === iz - 1) {
21711
if (!stmt.body[i].trailingComments) {
21712
generateBlankLines(stmt.body[i].range[1], stmt.range[1], result);
21713
}
21714
}
21715
}
21716
}
21717
return result;
21718
},
21719
21720
FunctionDeclaration: function (stmt, flags) {
21721
return [
21722
generateAsyncPrefix(stmt, true),
21723
'function',
21724
generateStarSuffix(stmt) || noEmptySpace(),
21725
stmt.id ? generateIdentifier(stmt.id) : '',
21726
this.generateFunctionBody(stmt)
21727
];
21728
},
21729
21730
ReturnStatement: function (stmt, flags) {
21731
if (stmt.argument) {
21732
return [join(
21733
'return',
21734
this.generateExpression(stmt.argument, Precedence.Sequence, E_TTT)
21735
), this.semicolon(flags)];
21736
}
21737
return ['return' + this.semicolon(flags)];
21738
},
21739
21740
WhileStatement: function (stmt, flags) {
21741
var result, that = this;
21742
withIndent(function () {
21743
result = [
21744
'while' + space + '(',
21745
that.generateExpression(stmt.test, Precedence.Sequence, E_TTT),
21746
')'
21747
];
21748
});
21749
result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF));
21750
return result;
21751
},
21752
21753
WithStatement: function (stmt, flags) {
21754
var result, that = this;
21755
withIndent(function () {
21756
result = [
21757
'with' + space + '(',
21758
that.generateExpression(stmt.object, Precedence.Sequence, E_TTT),
21759
')'
21760
];
21761
});
21762
result.push(this.maybeBlock(stmt.body, flags & F_SEMICOLON_OPT ? S_TFFT : S_TFFF));
21763
return result;
21764
}
21765
21766
};
21767
21768
merge(CodeGenerator.prototype, CodeGenerator.Statement);
21769
21770
// Expressions.
21771
21772
CodeGenerator.Expression = {
21773
21774
/* OJS expressions begin */
21775
21776
MutableExpression: function(expr, precedence, flags) {
21777
return `mutable ${expr.id.name}`;
21778
},
21779
21780
ViewExpression: function(expr, precedence, flags) {
21781
return `viewof ${expr.id.name}`;
21782
},
21783
21784
/* OJS expressions end */
21785
21786
SequenceExpression: function (expr, precedence, flags) {
21787
var result, i, iz;
21788
if (Precedence.Sequence < precedence) {
21789
flags |= F_ALLOW_IN;
21790
}
21791
result = [];
21792
for (i = 0, iz = expr.expressions.length; i < iz; ++i) {
21793
result.push(this.generateExpression(expr.expressions[i], Precedence.Assignment, flags));
21794
if (i + 1 < iz) {
21795
result.push(',' + space);
21796
}
21797
}
21798
return parenthesize(result, Precedence.Sequence, precedence);
21799
},
21800
21801
AssignmentExpression: function (expr, precedence, flags) {
21802
return this.generateAssignment(expr.left, expr.right, expr.operator, precedence, flags);
21803
},
21804
21805
ArrowFunctionExpression: function (expr, precedence, flags) {
21806
return parenthesize(this.generateFunctionBody(expr), Precedence.ArrowFunction, precedence);
21807
},
21808
21809
ConditionalExpression: function (expr, precedence, flags) {
21810
if (Precedence.Conditional < precedence) {
21811
flags |= F_ALLOW_IN;
21812
}
21813
return parenthesize(
21814
[
21815
this.generateExpression(expr.test, Precedence.Coalesce, flags),
21816
space + '?' + space,
21817
this.generateExpression(expr.consequent, Precedence.Assignment, flags),
21818
space + ':' + space,
21819
this.generateExpression(expr.alternate, Precedence.Assignment, flags)
21820
],
21821
Precedence.Conditional,
21822
precedence
21823
);
21824
},
21825
21826
LogicalExpression: function (expr, precedence, flags) {
21827
if (expr.operator === '??') {
21828
flags |= F_FOUND_COALESCE;
21829
}
21830
return this.BinaryExpression(expr, precedence, flags);
21831
},
21832
21833
BinaryExpression: function (expr, precedence, flags) {
21834
var result, leftPrecedence, rightPrecedence, currentPrecedence, fragment, leftSource;
21835
currentPrecedence = BinaryPrecedence[expr.operator];
21836
leftPrecedence = expr.operator === '**' ? Precedence.Postfix : currentPrecedence;
21837
rightPrecedence = expr.operator === '**' ? currentPrecedence : currentPrecedence + 1;
21838
21839
if (currentPrecedence < precedence) {
21840
flags |= F_ALLOW_IN;
21841
}
21842
21843
fragment = this.generateExpression(expr.left, leftPrecedence, flags);
21844
21845
leftSource = fragment.toString();
21846
21847
if (leftSource.charCodeAt(leftSource.length - 1) === 0x2F /* / */ && esutils.code.isIdentifierPartES5(expr.operator.charCodeAt(0))) {
21848
result = [fragment, noEmptySpace(), expr.operator];
21849
} else {
21850
result = join(fragment, expr.operator);
21851
}
21852
21853
fragment = this.generateExpression(expr.right, rightPrecedence, flags);
21854
21855
if (expr.operator === '/' && fragment.toString().charAt(0) === '/' ||
21856
expr.operator.slice(-1) === '<' && fragment.toString().slice(0, 3) === '!--') {
21857
// If '/' concats with '/' or `<` concats with `!--`, it is interpreted as comment start
21858
result.push(noEmptySpace());
21859
result.push(fragment);
21860
} else {
21861
result = join(result, fragment);
21862
}
21863
21864
if (expr.operator === 'in' && !(flags & F_ALLOW_IN)) {
21865
return ['(', result, ')'];
21866
}
21867
if ((expr.operator === '||' || expr.operator === '&&') && (flags & F_FOUND_COALESCE)) {
21868
return ['(', result, ')'];
21869
}
21870
return parenthesize(result, currentPrecedence, precedence);
21871
},
21872
21873
CallExpression: function (expr, precedence, flags) {
21874
var result, i, iz;
21875
21876
// F_ALLOW_UNPARATH_NEW becomes false.
21877
result = [this.generateExpression(expr.callee, Precedence.Call, E_TTF)];
21878
21879
if (expr.optional) {
21880
result.push('?.');
21881
}
21882
21883
result.push('(');
21884
for (i = 0, iz = expr['arguments'].length; i < iz; ++i) {
21885
result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT));
21886
if (i + 1 < iz) {
21887
result.push(',' + space);
21888
}
21889
}
21890
result.push(')');
21891
21892
if (!(flags & F_ALLOW_CALL)) {
21893
return ['(', result, ')'];
21894
}
21895
21896
return parenthesize(result, Precedence.Call, precedence);
21897
},
21898
21899
ChainExpression: function (expr, precedence, flags) {
21900
if (Precedence.OptionalChaining < precedence) {
21901
flags |= F_ALLOW_CALL;
21902
}
21903
21904
var result = this.generateExpression(expr.expression, Precedence.OptionalChaining, flags);
21905
21906
return parenthesize(result, Precedence.OptionalChaining, precedence);
21907
},
21908
21909
NewExpression: function (expr, precedence, flags) {
21910
var result, length, i, iz, itemFlags;
21911
length = expr['arguments'].length;
21912
21913
// F_ALLOW_CALL becomes false.
21914
// F_ALLOW_UNPARATH_NEW may become false.
21915
itemFlags = (flags & F_ALLOW_UNPARATH_NEW && !parentheses && length === 0) ? E_TFT : E_TFF;
21916
21917
result = join(
21918
'new',
21919
this.generateExpression(expr.callee, Precedence.New, itemFlags)
21920
);
21921
21922
if (!(flags & F_ALLOW_UNPARATH_NEW) || parentheses || length > 0) {
21923
result.push('(');
21924
for (i = 0, iz = length; i < iz; ++i) {
21925
result.push(this.generateExpression(expr['arguments'][i], Precedence.Assignment, E_TTT));
21926
if (i + 1 < iz) {
21927
result.push(',' + space);
21928
}
21929
}
21930
result.push(')');
21931
}
21932
21933
return parenthesize(result, Precedence.New, precedence);
21934
},
21935
21936
MemberExpression: function (expr, precedence, flags) {
21937
var result, fragment;
21938
21939
// F_ALLOW_UNPARATH_NEW becomes false.
21940
result = [this.generateExpression(expr.object, Precedence.Call, (flags & F_ALLOW_CALL) ? E_TTF : E_TFF)];
21941
21942
if (expr.computed) {
21943
if (expr.optional) {
21944
result.push('?.');
21945
}
21946
21947
result.push('[');
21948
result.push(this.generateExpression(expr.property, Precedence.Sequence, flags & F_ALLOW_CALL ? E_TTT : E_TFT));
21949
result.push(']');
21950
} else {
21951
if (!expr.optional && expr.object.type === "Literal" && typeof expr.object.value === 'number') {
21952
fragment = toSourceNodeWhenNeeded(result).toString();
21953
// When the following conditions are all true,
21954
// 1. No floating point
21955
// 2. Don't have exponents
21956
// 3. The last character is a decimal digit
21957
// 4. Not hexadecimal OR octal number literal
21958
// we should add a floating point.
21959
if (
21960
fragment.indexOf('.') < 0 &&
21961
!/[eExX]/.test(fragment) &&
21962
esutils.code.isDecimalDigit(fragment.charCodeAt(fragment.length - 1)) &&
21963
!(fragment.length >= 2 && fragment.charCodeAt(0) === 48) // '0'
21964
) {
21965
result.push(' ');
21966
}
21967
}
21968
result.push(expr.optional ? '?.' : '.');
21969
result.push(generateIdentifier(expr.property));
21970
}
21971
21972
return parenthesize(result, Precedence.Member, precedence);
21973
},
21974
21975
MetaProperty: function (expr, precedence, flags) {
21976
var result;
21977
result = [];
21978
result.push(typeof expr.meta === "string" ? expr.meta : generateIdentifier(expr.meta));
21979
result.push('.');
21980
result.push(typeof expr.property === "string" ? expr.property : generateIdentifier(expr.property));
21981
return parenthesize(result, Precedence.Member, precedence);
21982
},
21983
21984
UnaryExpression: function (expr, precedence, flags) {
21985
var result, fragment, rightCharCode, leftSource, leftCharCode;
21986
fragment = this.generateExpression(expr.argument, Precedence.Unary, E_TTT);
21987
21988
if (space === '') {
21989
result = join(expr.operator, fragment);
21990
} else {
21991
result = [expr.operator];
21992
if (expr.operator.length > 2) {
21993
// delete, void, typeof
21994
// get `typeof []`, not `typeof[]`
21995
result = join(result, fragment);
21996
} else {
21997
// Prevent inserting spaces between operator and argument if it is unnecessary
21998
// like, `!cond`
21999
leftSource = toSourceNodeWhenNeeded(result).toString();
22000
leftCharCode = leftSource.charCodeAt(leftSource.length - 1);
22001
rightCharCode = fragment.toString().charCodeAt(0);
22002
22003
if (((leftCharCode === 0x2B /* + */ || leftCharCode === 0x2D /* - */) && leftCharCode === rightCharCode) ||
22004
(esutils.code.isIdentifierPartES5(leftCharCode) && esutils.code.isIdentifierPartES5(rightCharCode))) {
22005
result.push(noEmptySpace());
22006
result.push(fragment);
22007
} else {
22008
result.push(fragment);
22009
}
22010
}
22011
}
22012
return parenthesize(result, Precedence.Unary, precedence);
22013
},
22014
22015
YieldExpression: function (expr, precedence, flags) {
22016
var result;
22017
if (expr.delegate) {
22018
result = 'yield*';
22019
} else {
22020
result = 'yield';
22021
}
22022
if (expr.argument) {
22023
result = join(
22024
result,
22025
this.generateExpression(expr.argument, Precedence.Yield, E_TTT)
22026
);
22027
}
22028
return parenthesize(result, Precedence.Yield, precedence);
22029
},
22030
22031
AwaitExpression: function (expr, precedence, flags) {
22032
var result = join(
22033
expr.all ? 'await*' : 'await',
22034
this.generateExpression(expr.argument, Precedence.Await, E_TTT)
22035
);
22036
return parenthesize(result, Precedence.Await, precedence);
22037
},
22038
22039
UpdateExpression: function (expr, precedence, flags) {
22040
if (expr.prefix) {
22041
return parenthesize(
22042
[
22043
expr.operator,
22044
this.generateExpression(expr.argument, Precedence.Unary, E_TTT)
22045
],
22046
Precedence.Unary,
22047
precedence
22048
);
22049
}
22050
return parenthesize(
22051
[
22052
this.generateExpression(expr.argument, Precedence.Postfix, E_TTT),
22053
expr.operator
22054
],
22055
Precedence.Postfix,
22056
precedence
22057
);
22058
},
22059
22060
FunctionExpression: function (expr, precedence, flags) {
22061
var result = [
22062
generateAsyncPrefix(expr, true),
22063
'function'
22064
];
22065
if (expr.id) {
22066
result.push(generateStarSuffix(expr) || noEmptySpace());
22067
result.push(generateIdentifier(expr.id));
22068
} else {
22069
result.push(generateStarSuffix(expr) || space);
22070
}
22071
result.push(this.generateFunctionBody(expr));
22072
return result;
22073
},
22074
22075
ArrayPattern: function (expr, precedence, flags) {
22076
return this.ArrayExpression(expr, precedence, flags, true);
22077
},
22078
22079
ArrayExpression: function (expr, precedence, flags, isPattern) {
22080
var result, multiline, that = this;
22081
if (!expr.elements.length) {
22082
return '[]';
22083
}
22084
multiline = isPattern ? false : expr.elements.length > 1;
22085
result = ['[', multiline ? newline : ''];
22086
withIndent(function (indent) {
22087
var i, iz;
22088
for (i = 0, iz = expr.elements.length; i < iz; ++i) {
22089
if (!expr.elements[i]) {
22090
if (multiline) {
22091
result.push(indent);
22092
}
22093
if (i + 1 === iz) {
22094
result.push(',');
22095
}
22096
} else {
22097
result.push(multiline ? indent : '');
22098
result.push(that.generateExpression(expr.elements[i], Precedence.Assignment, E_TTT));
22099
}
22100
if (i + 1 < iz) {
22101
result.push(',' + (multiline ? newline : space));
22102
}
22103
}
22104
});
22105
if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
22106
result.push(newline);
22107
}
22108
result.push(multiline ? base : '');
22109
result.push(']');
22110
return result;
22111
},
22112
22113
RestElement: function(expr, precedence, flags) {
22114
return '...' + this.generatePattern(expr.argument);
22115
},
22116
22117
ClassExpression: function (expr, precedence, flags) {
22118
var result, fragment;
22119
result = ['class'];
22120
if (expr.id) {
22121
result = join(result, this.generateExpression(expr.id, Precedence.Sequence, E_TTT));
22122
}
22123
if (expr.superClass) {
22124
fragment = join('extends', this.generateExpression(expr.superClass, Precedence.Unary, E_TTT));
22125
result = join(result, fragment);
22126
}
22127
result.push(space);
22128
result.push(this.generateStatement(expr.body, S_TFFT));
22129
return result;
22130
},
22131
22132
MethodDefinition: function (expr, precedence, flags) {
22133
var result, fragment;
22134
if (expr['static']) {
22135
result = ['static' + space];
22136
} else {
22137
result = [];
22138
}
22139
if (expr.kind === 'get' || expr.kind === 'set') {
22140
fragment = [
22141
join(expr.kind, this.generatePropertyKey(expr.key, expr.computed)),
22142
this.generateFunctionBody(expr.value)
22143
];
22144
} else {
22145
fragment = [
22146
generateMethodPrefix(expr),
22147
this.generatePropertyKey(expr.key, expr.computed),
22148
this.generateFunctionBody(expr.value)
22149
];
22150
}
22151
return join(result, fragment);
22152
},
22153
22154
Property: function (expr, precedence, flags) {
22155
if (expr.kind === 'get' || expr.kind === 'set') {
22156
return [
22157
expr.kind, noEmptySpace(),
22158
this.generatePropertyKey(expr.key, expr.computed),
22159
this.generateFunctionBody(expr.value)
22160
];
22161
}
22162
22163
if (expr.shorthand) {
22164
if (expr.value.type === "AssignmentPattern") {
22165
return this.AssignmentPattern(expr.value, Precedence.Sequence, E_TTT);
22166
}
22167
return this.generatePropertyKey(expr.key, expr.computed);
22168
}
22169
22170
if (expr.method) {
22171
return [
22172
generateMethodPrefix(expr),
22173
this.generatePropertyKey(expr.key, expr.computed),
22174
this.generateFunctionBody(expr.value)
22175
];
22176
}
22177
22178
return [
22179
this.generatePropertyKey(expr.key, expr.computed),
22180
':' + space,
22181
this.generateExpression(expr.value, Precedence.Assignment, E_TTT)
22182
];
22183
},
22184
22185
ObjectExpression: function (expr, precedence, flags) {
22186
var multiline, result, fragment, that = this;
22187
22188
if (!expr.properties.length) {
22189
return '{}';
22190
}
22191
multiline = expr.properties.length > 1;
22192
22193
withIndent(function () {
22194
fragment = that.generateExpression(expr.properties[0], Precedence.Sequence, E_TTT);
22195
});
22196
22197
if (!multiline) {
22198
// issues 4
22199
// Do not transform from
22200
// dejavu.Class.declare({
22201
// method2: function () {}
22202
// });
22203
// to
22204
// dejavu.Class.declare({method2: function () {
22205
// }});
22206
if (!hasLineTerminator(toSourceNodeWhenNeeded(fragment).toString())) {
22207
return [ '{', space, fragment, space, '}' ];
22208
}
22209
}
22210
22211
withIndent(function (indent) {
22212
var i, iz;
22213
result = [ '{', newline, indent, fragment ];
22214
22215
if (multiline) {
22216
result.push(',' + newline);
22217
for (i = 1, iz = expr.properties.length; i < iz; ++i) {
22218
result.push(indent);
22219
result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT));
22220
if (i + 1 < iz) {
22221
result.push(',' + newline);
22222
}
22223
}
22224
}
22225
});
22226
22227
if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
22228
result.push(newline);
22229
}
22230
result.push(base);
22231
result.push('}');
22232
return result;
22233
},
22234
22235
AssignmentPattern: function(expr, precedence, flags) {
22236
return this.generateAssignment(expr.left, expr.right, '=', precedence, flags);
22237
},
22238
22239
ObjectPattern: function (expr, precedence, flags) {
22240
var result, i, iz, multiline, property, that = this;
22241
if (!expr.properties.length) {
22242
return '{}';
22243
}
22244
22245
multiline = false;
22246
if (expr.properties.length === 1) {
22247
property = expr.properties[0];
22248
if (
22249
property.type === "Property"
22250
&& property.value.type !== "Identifier"
22251
) {
22252
multiline = true;
22253
}
22254
} else {
22255
for (i = 0, iz = expr.properties.length; i < iz; ++i) {
22256
property = expr.properties[i];
22257
if (
22258
property.type === "Property"
22259
&& !property.shorthand
22260
) {
22261
multiline = true;
22262
break;
22263
}
22264
}
22265
}
22266
result = ['{', multiline ? newline : '' ];
22267
22268
withIndent(function (indent) {
22269
var i, iz;
22270
for (i = 0, iz = expr.properties.length; i < iz; ++i) {
22271
result.push(multiline ? indent : '');
22272
result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT));
22273
if (i + 1 < iz) {
22274
result.push(',' + (multiline ? newline : space));
22275
}
22276
}
22277
});
22278
22279
if (multiline && !endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
22280
result.push(newline);
22281
}
22282
result.push(multiline ? base : '');
22283
result.push('}');
22284
return result;
22285
},
22286
22287
ThisExpression: function (expr, precedence, flags) {
22288
return 'this';
22289
},
22290
22291
Super: function (expr, precedence, flags) {
22292
return 'super';
22293
},
22294
22295
Identifier: function (expr, precedence, flags) {
22296
return generateIdentifier(expr);
22297
},
22298
22299
ImportDefaultSpecifier: function (expr, precedence, flags) {
22300
return generateIdentifier(expr.id || expr.local);
22301
},
22302
22303
ImportNamespaceSpecifier: function (expr, precedence, flags) {
22304
var result = ['*'];
22305
var id = expr.id || expr.local;
22306
if (id) {
22307
result.push(space + 'as' + noEmptySpace() + generateIdentifier(id));
22308
}
22309
return result;
22310
},
22311
22312
ImportSpecifier: function (expr, precedence, flags) {
22313
var imported = expr.imported;
22314
var result = [ imported.name ];
22315
var local = expr.local;
22316
if (local && local.name !== imported.name) {
22317
result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(local));
22318
}
22319
return result;
22320
},
22321
22322
ExportSpecifier: function (expr, precedence, flags) {
22323
var local = expr.local;
22324
var result = [ local.name ];
22325
var exported = expr.exported;
22326
if (exported && exported.name !== local.name) {
22327
result.push(noEmptySpace() + 'as' + noEmptySpace() + generateIdentifier(exported));
22328
}
22329
return result;
22330
},
22331
22332
Literal: function (expr, precedence, flags) {
22333
var raw;
22334
if (expr.hasOwnProperty('raw') && parse && extra.raw) {
22335
try {
22336
raw = parse(expr.raw).body[0].expression;
22337
if (raw.type === "Literal") {
22338
if (raw.value === expr.value) {
22339
return expr.raw;
22340
}
22341
}
22342
} catch (e) {
22343
// not use raw property
22344
}
22345
}
22346
22347
if (expr.regex) {
22348
return '/' + expr.regex.pattern + '/' + expr.regex.flags;
22349
}
22350
22351
if (typeof expr.value === 'bigint') {
22352
return expr.value.toString() + 'n';
22353
}
22354
22355
// `expr.value` can be null if `expr.bigint` exists. We need to check
22356
// `expr.bigint` first.
22357
if (expr.bigint) {
22358
return expr.bigint + 'n';
22359
}
22360
22361
if (expr.value === null) {
22362
return 'null';
22363
}
22364
22365
if (typeof expr.value === 'string') {
22366
return escapeString(expr.value);
22367
}
22368
22369
if (typeof expr.value === 'number') {
22370
return generateNumber(expr.value);
22371
}
22372
22373
if (typeof expr.value === 'boolean') {
22374
return expr.value ? 'true' : 'false';
22375
}
22376
22377
return generateRegExp(expr.value);
22378
},
22379
22380
GeneratorExpression: function (expr, precedence, flags) {
22381
return this.ComprehensionExpression(expr, precedence, flags);
22382
},
22383
22384
ComprehensionExpression: function (expr, precedence, flags) {
22385
// GeneratorExpression should be parenthesized with (...), ComprehensionExpression with [...]
22386
// Due to https://bugzilla.mozilla.org/show_bug.cgi?id=883468 position of expr.body can differ in Spidermonkey and ES6
22387
22388
var result, i, iz, fragment, that = this;
22389
result = (expr.type === "GeneratorExpression") ? ['('] : ['['];
22390
22391
if (extra.moz.comprehensionExpressionStartsWithAssignment) {
22392
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
22393
result.push(fragment);
22394
}
22395
22396
if (expr.blocks) {
22397
withIndent(function () {
22398
for (i = 0, iz = expr.blocks.length; i < iz; ++i) {
22399
fragment = that.generateExpression(expr.blocks[i], Precedence.Sequence, E_TTT);
22400
if (i > 0 || extra.moz.comprehensionExpressionStartsWithAssignment) {
22401
result = join(result, fragment);
22402
} else {
22403
result.push(fragment);
22404
}
22405
}
22406
});
22407
}
22408
22409
if (expr.filter) {
22410
result = join(result, 'if' + space);
22411
fragment = this.generateExpression(expr.filter, Precedence.Sequence, E_TTT);
22412
result = join(result, [ '(', fragment, ')' ]);
22413
}
22414
22415
if (!extra.moz.comprehensionExpressionStartsWithAssignment) {
22416
fragment = this.generateExpression(expr.body, Precedence.Assignment, E_TTT);
22417
22418
result = join(result, fragment);
22419
}
22420
22421
result.push((expr.type === "GeneratorExpression") ? ')' : ']');
22422
return result;
22423
},
22424
22425
ComprehensionBlock: function (expr, precedence, flags) {
22426
var fragment;
22427
if (expr.left.type === "VariableDeclaration") {
22428
fragment = [
22429
expr.left.kind, noEmptySpace(),
22430
this.generateStatement(expr.left.declarations[0], S_FFFF)
22431
];
22432
} else {
22433
fragment = this.generateExpression(expr.left, Precedence.Call, E_TTT);
22434
}
22435
22436
fragment = join(fragment, expr.of ? 'of' : 'in');
22437
fragment = join(fragment, this.generateExpression(expr.right, Precedence.Sequence, E_TTT));
22438
22439
return [ 'for' + space + '(', fragment, ')' ];
22440
},
22441
22442
SpreadElement: function (expr, precedence, flags) {
22443
return [
22444
'...',
22445
this.generateExpression(expr.argument, Precedence.Assignment, E_TTT)
22446
];
22447
},
22448
22449
TaggedTemplateExpression: function (expr, precedence, flags) {
22450
var itemFlags = E_TTF;
22451
if (!(flags & F_ALLOW_CALL)) {
22452
itemFlags = E_TFF;
22453
}
22454
var result = [
22455
this.generateExpression(expr.tag, Precedence.Call, itemFlags),
22456
this.generateExpression(expr.quasi, Precedence.Primary, E_FFT)
22457
];
22458
return parenthesize(result, Precedence.TaggedTemplate, precedence);
22459
},
22460
22461
TemplateElement: function (expr, precedence, flags) {
22462
// Don't use "cooked". Since tagged template can use raw template
22463
// representation. So if we do so, it breaks the script semantics.
22464
return expr.value.raw;
22465
},
22466
22467
TemplateLiteral: function (expr, precedence, flags) {
22468
var result, i, iz;
22469
result = [ '`' ];
22470
for (i = 0, iz = expr.quasis.length; i < iz; ++i) {
22471
result.push(this.generateExpression(expr.quasis[i], Precedence.Primary, E_TTT));
22472
if (i + 1 < iz) {
22473
result.push('${' + space);
22474
result.push(this.generateExpression(expr.expressions[i], Precedence.Sequence, E_TTT));
22475
result.push(space + '}');
22476
}
22477
}
22478
result.push('`');
22479
return result;
22480
},
22481
22482
ModuleSpecifier: function (expr, precedence, flags) {
22483
return this.Literal(expr, precedence, flags);
22484
},
22485
22486
ImportExpression: function(expr, precedence, flag) {
22487
return parenthesize([
22488
'import(',
22489
this.generateExpression(expr.source, Precedence.Assignment, E_TTT),
22490
')'
22491
], Precedence.Call, precedence);
22492
}
22493
};
22494
22495
merge(CodeGenerator.prototype, CodeGenerator.Expression);
22496
22497
CodeGenerator.prototype.generateExpression = function (expr, precedence, flags) {
22498
var result, type;
22499
22500
type = expr.type || "Property";
22501
22502
if (extra.verbatim && expr.hasOwnProperty(extra.verbatim)) {
22503
return generateVerbatim(expr, precedence);
22504
}
22505
22506
result = this[type](expr, precedence, flags);
22507
22508
22509
if (extra.comment) {
22510
result = addComments(expr, result);
22511
}
22512
return toSourceNodeWhenNeeded(result);
22513
};
22514
22515
CodeGenerator.prototype.generateStatement = function (stmt, flags) {
22516
var result,
22517
fragment;
22518
22519
result = this[stmt.type](stmt, flags);
22520
22521
// Attach comments
22522
22523
if (extra.comment) {
22524
result = addComments(stmt, result);
22525
}
22526
22527
fragment = toSourceNodeWhenNeeded(result).toString();
22528
if (stmt.type === "Program" && !safeConcatenation && newline === '' && fragment.charAt(fragment.length - 1) === '\n') {
22529
result = sourceMap ? toSourceNodeWhenNeeded(result).replaceRight(/\s+$/, '') : fragment.replace(/\s+$/, '');
22530
}
22531
22532
return toSourceNodeWhenNeeded(result);
22533
};
22534
22535
function generateInternal(node) {
22536
var codegen;
22537
22538
codegen = new CodeGenerator();
22539
if (isStatement(node)) {
22540
return codegen.generateStatement(node, S_TFFF);
22541
}
22542
22543
if (isExpression(node)) {
22544
return codegen.generateExpression(node, Precedence.Sequence, E_TTT);
22545
}
22546
22547
throw new Error('Unknown node type: ' + node.type);
22548
}
22549
22550
function generate(node, options) {
22551
var defaultOptions = getDefaultOptions();
22552
22553
if (options != null) {
22554
// Obsolete options
22555
//
22556
// `options.indent`
22557
// `options.base`
22558
//
22559
// Instead of them, we can use `option.format.indent`.
22560
if (typeof options.indent === 'string') {
22561
defaultOptions.format.indent.style = options.indent;
22562
}
22563
if (typeof options.base === 'number') {
22564
defaultOptions.format.indent.base = options.base;
22565
}
22566
options = updateDeeply(defaultOptions, options);
22567
indent = options.format.indent.style;
22568
if (typeof options.base === 'string') {
22569
base = options.base;
22570
} else {
22571
base = stringRepeat(indent, options.format.indent.base);
22572
}
22573
} else {
22574
options = defaultOptions;
22575
indent = options.format.indent.style;
22576
base = stringRepeat(indent, options.format.indent.base);
22577
}
22578
json = options.format.json;
22579
renumber = options.format.renumber;
22580
hexadecimal = json ? false : options.format.hexadecimal;
22581
quotes = json ? 'double' : options.format.quotes;
22582
escapeless = options.format.escapeless;
22583
newline = options.format.newline;
22584
space = options.format.space;
22585
if (options.format.compact) {
22586
newline = space = indent = base = '';
22587
}
22588
parentheses = options.format.parentheses;
22589
semicolons = options.format.semicolons;
22590
safeConcatenation = options.format.safeConcatenation;
22591
directive = options.directive;
22592
parse = json ? null : options.parse;
22593
sourceMap = false;
22594
sourceCode = options.sourceCode;
22595
preserveBlankLines = options.format.preserveBlankLines && sourceCode !== null;
22596
extra = options;
22597
22598
return generateInternal(node).toString();
22599
}
22600
22601
getDefaultOptions().format;
22602
22603
Precedence = updateDeeply({}, Precedence);
22604
22605
/*
22606
* ojs-code-transform.ts
22607
*
22608
* Copyright (C) 2021-2023 Posit Software, PBC
22609
*/
22610
22611
// we need to patch the base walker ourselves because OJS sometimes
22612
// emits Program nodes with "cells" rather than "body"
22613
const walkerBase = make({
22614
Import() {},
22615
// deno-lint-ignore no-explicit-any
22616
ViewExpression(node, st, c) {
22617
c(node.id, st, "Identifier");
22618
},
22619
// deno-lint-ignore no-explicit-any
22620
MutableExpression(node, st, c) {
22621
c(node.id, st, "Identifier");
22622
},
22623
// deno-lint-ignore no-explicit-any
22624
Cell(node, st, c) {
22625
c(node.body, st);
22626
},
22627
// deno-lint-ignore no-explicit-any
22628
Program(node, st, c) {
22629
if (node.body) {
22630
for (let i = 0, list = node.body; i < list.length; i += 1) {
22631
const stmt = list[i];
22632
c(stmt, st, "Statement");
22633
}
22634
} else if (node.cells) {
22635
for (let i = 0, list = node.cells; i < list.length; i += 1) {
22636
const stmt = list[i];
22637
c(stmt, st);
22638
}
22639
} else {
22640
throw new Error(
22641
`OJS traversal: I don't know how to walk this node: ${node}`,
22642
);
22643
}
22644
},
22645
});
22646
22647
// deno-lint-ignore no-explicit-any
22648
function ojsSimpleWalker(parse, visitor) {
22649
simple(parse, visitor, walkerBase);
22650
}
22651
22652
function isPlotPlotCall(node) {
22653
if (node.type !== "CallExpression") {
22654
return null;
22655
}
22656
const callee = node.callee;
22657
if (callee.type !== "MemberExpression") {
22658
return null;
22659
}
22660
if (callee.property.type !== "Identifier" ||
22661
callee.property.name !== "plot") {
22662
return null;
22663
}
22664
22665
let result = node.arguments;
22666
22667
node = callee.object;
22668
while (true) {
22669
if (node.type === "Identifier" &&
22670
node.name === "Plot") {
22671
return result;
22672
}
22673
if (node.type !== "CallExpression" ||
22674
node.callee.type !== "MemberExpression") {
22675
return null;
22676
}
22677
node = node.callee.object;
22678
}
22679
}
22680
22681
22682
/*
22683
Rewrites Plot.(method(...).method(...).)plot({
22684
...
22685
})
22686
to
22687
Plot.(method(...).method(...).)plot({
22688
width: card[$CARD_IN_SCOPE].width,
22689
height: card[$CARD_IN_SCOPE].height,
22690
...
22691
}) */
22692
const multipleOutputCellMap = {};
22693
function rewritePlotPlotCall(exp, cellName) {
22694
// First, check if cellName exists. If it doesn't,
22695
// then that's likely because we're on a multiple-output cell.
22696
// attempt to find a cell with the name cellName-1, cellName-2, etc.
22697
const fixupCellName = () => {
22698
if (document.getElementById(cellName) === null) {
22699
let index = 1;
22700
let subcellName;
22701
do {
22702
subcellName = `${cellName}-${index}`;
22703
index += 1;
22704
if (document.getElementById(subcellName) !== null && multipleOutputCellMap[subcellName] === undefined) {
22705
multipleOutputCellMap[subcellName] = true;
22706
return subcellName;
22707
}
22708
} while (document.getElementById(subcellName) !== null);
22709
return undefined;
22710
} else {
22711
return cellName;
22712
}
22713
};
22714
22715
const args = isPlotPlotCall(exp);
22716
if (args === null) {
22717
return false;
22718
}
22719
if (args.length > 1) {
22720
return false;
22721
}
22722
if (args.length === 0) {
22723
args.push({
22724
type: "ObjectExpression",
22725
properties: []
22726
});
22727
}
22728
if (args[0].type !== "ObjectExpression") {
22729
return false;
22730
}
22731
22732
const props = args[0].properties;
22733
// this will need to be more robust in the future.
22734
// deno-lint-ignore no-explicit-any
22735
if (!props.every((a) => a.type === "Property")) {
22736
return false;
22737
}
22738
// insert
22739
// width: cards[cardIndex].width property
22740
// and height: cards[cardIndex].height property
22741
22742
const cellNameToUse = fixupCellName();
22743
if (cellNameToUse === undefined) {
22744
return false;
22745
}
22746
const value = (field) => ({
22747
type: "MemberExpression",
22748
object: {
22749
type: "MemberExpression",
22750
computed: true,
22751
object: {
22752
type: "Identifier",
22753
name: "cards",
22754
},
22755
property: {
22756
type: "Literal",
22757
value: cellNameToUse,
22758
},
22759
},
22760
property: {
22761
type: "Identifier",
22762
name: field,
22763
},
22764
});
22765
const prop = (field) => ({
22766
type: "Property",
22767
key: {
22768
type: "Identifier",
22769
name: field,
22770
},
22771
value: value(field),
22772
});
22773
22774
props.unshift(prop("width"));
22775
props.unshift(prop("height"));
22776
return true;
22777
}
22778
22779
function autosizeOJSPlot(
22780
src,
22781
cellName,
22782
) {
22783
// deno-lint-ignore no-explicit-any
22784
let ast;
22785
try {
22786
ast = parseModule(src);
22787
} catch (e) {
22788
// if we fail to parse, don't do anything
22789
// FIXME warn?
22790
if (!(e instanceof SyntaxError)) throw e;
22791
return src;
22792
}
22793
ojsSimpleWalker(ast, {
22794
// deno-lint-ignore no-explicit-any
22795
CallExpression(exp) {
22796
if (rewritePlotPlotCall(exp, cellName)) {
22797
return;
22798
}
22799
}
22800
});
22801
22802
const result = ast.cells.map((cell) => {
22803
const bodySrc = generate(cell.body);
22804
if (cell.id === null) {
22805
return bodySrc;
22806
} else if (cell.id.type === "Identifier") {
22807
return `${cell.id.name} = ${bodySrc}`;
22808
} else if (cell.id.type === "ViewExpression") {
22809
return `viewof ${cell.id.id.name} = ${bodySrc}`;
22810
} else if (cell.id.type === "MutableExpression") {
22811
return `mutable ${cell.id.id.name} = ${bodySrc}`;
22812
} else {
22813
throw new Error(`OJS: I don't know how to handle this cell id: ${cell.id.type}`);
22814
}
22815
}).join("\n");
22816
return result;
22817
}
22818
22819
/**
22820
* @param typeMap [Object] Map of MIME type -> Array[extensions]
22821
* @param ...
22822
*/
22823
function Mime$1() {
22824
this._types = Object.create(null);
22825
this._extensions = Object.create(null);
22826
22827
for (let i = 0; i < arguments.length; i++) {
22828
this.define(arguments[i]);
22829
}
22830
22831
this.define = this.define.bind(this);
22832
this.getType = this.getType.bind(this);
22833
this.getExtension = this.getExtension.bind(this);
22834
}
22835
22836
/**
22837
* Define mimetype -> extension mappings. Each key is a mime-type that maps
22838
* to an array of extensions associated with the type. The first extension is
22839
* used as the default extension for the type.
22840
*
22841
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
22842
*
22843
* If a type declares an extension that has already been defined, an error will
22844
* be thrown. To suppress this error and force the extension to be associated
22845
* with the new type, pass `force`=true. Alternatively, you may prefix the
22846
* extension with "*" to map the type to extension, without mapping the
22847
* extension to the type.
22848
*
22849
* e.g. mime.define({'audio/wav', ['wav']}, {'audio/x-wav', ['*wav']});
22850
*
22851
*
22852
* @param map (Object) type definitions
22853
* @param force (Boolean) if true, force overriding of existing definitions
22854
*/
22855
Mime$1.prototype.define = function(typeMap, force) {
22856
for (let type in typeMap) {
22857
let extensions = typeMap[type].map(function(t) {
22858
return t.toLowerCase();
22859
});
22860
type = type.toLowerCase();
22861
22862
for (let i = 0; i < extensions.length; i++) {
22863
const ext = extensions[i];
22864
22865
// '*' prefix = not the preferred type for this extension. So fixup the
22866
// extension, and skip it.
22867
if (ext[0] === '*') {
22868
continue;
22869
}
22870
22871
if (!force && (ext in this._types)) {
22872
throw new Error(
22873
'Attempt to change mapping for "' + ext +
22874
'" extension from "' + this._types[ext] + '" to "' + type +
22875
'". Pass `force=true` to allow this, otherwise remove "' + ext +
22876
'" from the list of extensions for "' + type + '".'
22877
);
22878
}
22879
22880
this._types[ext] = type;
22881
}
22882
22883
// Use first extension as default
22884
if (force || !this._extensions[type]) {
22885
const ext = extensions[0];
22886
this._extensions[type] = (ext[0] !== '*') ? ext : ext.substr(1);
22887
}
22888
}
22889
};
22890
22891
/**
22892
* Lookup a mime type based on extension
22893
*/
22894
Mime$1.prototype.getType = function(path) {
22895
path = String(path);
22896
let last = path.replace(/^.*[/\\]/, '').toLowerCase();
22897
let ext = last.replace(/^.*\./, '').toLowerCase();
22898
22899
let hasPath = last.length < path.length;
22900
let hasDot = ext.length < last.length - 1;
22901
22902
return (hasDot || !hasPath) && this._types[ext] || null;
22903
};
22904
22905
/**
22906
* Return file extension associated with a mime type
22907
*/
22908
Mime$1.prototype.getExtension = function(type) {
22909
type = /^\s*([^;\s]*)/.test(type) && RegExp.$1;
22910
return type && this._extensions[type.toLowerCase()] || null;
22911
};
22912
22913
var Mime_1 = Mime$1;
22914
22915
var standard = {"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomdeleted+xml":["atomdeleted"],"application/atomsvc+xml":["atomsvc"],"application/atsc-dwd+xml":["dwd"],"application/atsc-held+xml":["held"],"application/atsc-rsat+xml":["rsat"],"application/bdoc":["bdoc"],"application/calendar+xml":["xcs"],"application/ccxml+xml":["ccxml"],"application/cdfx+xml":["cdfx"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["es","ecma"],"application/emma+xml":["emma"],"application/emotionml+xml":["emotionml"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/express":["exp"],"application/fdt+xml":["fdt"],"application/font-tdpfr":["pfr"],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hjson":["hjson"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/its+xml":["its"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lgr+xml":["lgr"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mmt-aei+xml":["maei"],"application/mmt-usd+xml":["musd"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/n-quads":["nq"],"application/n-triples":["nt"],"application/node":["cjs"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/p2p-overlay+xml":["relo"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/provenance+xml":["provx"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf","owl"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/route-apd+xml":["rapd"],"application/route-s-tsid+xml":["sls"],"application/route-usd+xml":["rusd"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/senml+xml":["senmlx"],"application/sensml+xml":["sensmlx"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/sieve":["siv","sieve"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/swid+xml":["swidtag"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/toml":["toml"],"application/trig":["trig"],"application/ttml+xml":["ttml"],"application/ubjson":["ubj"],"application/urc-ressheet+xml":["rsheet"],"application/urc-targetdesc+xml":["td"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/xaml+xml":["xaml"],"application/xcap-att+xml":["xav"],"application/xcap-caps+xml":["xca"],"application/xcap-diff+xml":["xdf"],"application/xcap-el+xml":["xel"],"application/xcap-ns+xml":["xns"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xliff+xml":["xlf"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["*xsl","xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":["*3gpp"],"audio/adpcm":["adp"],"audio/amr":["amr"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mobile-xmf":["mxmf"],"audio/mp3":["*mp3"],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx","opus"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/wav":["wav"],"audio/wave":["*wav"],"audio/webm":["weba"],"audio/xm":["xm"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/aces":["exr"],"image/apng":["apng"],"image/avif":["avif"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/dicom-rle":["drle"],"image/emf":["emf"],"image/fits":["fits"],"image/g3fax":["g3"],"image/gif":["gif"],"image/heic":["heic"],"image/heic-sequence":["heics"],"image/heif":["heif"],"image/heif-sequence":["heifs"],"image/hej2k":["hej2"],"image/hsj2":["hsj2"],"image/ief":["ief"],"image/jls":["jls"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jph":["jph"],"image/jphc":["jhc"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/jxr":["jxr"],"image/jxra":["jxra"],"image/jxrs":["jxrs"],"image/jxs":["jxs"],"image/jxsc":["jxsc"],"image/jxsi":["jxsi"],"image/jxss":["jxss"],"image/ktx":["ktx"],"image/ktx2":["ktx2"],"image/png":["png"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/t38":["t38"],"image/tiff":["tif","tiff"],"image/tiff-fx":["tfx"],"image/webp":["webp"],"image/wmf":["wmf"],"message/disposition-notification":["disposition-notification"],"message/global":["u8msg"],"message/global-delivery-status":["u8dsn"],"message/global-disposition-notification":["u8mdn"],"message/global-headers":["u8hdr"],"message/rfc822":["eml","mime"],"model/3mf":["3mf"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/mtl":["mtl"],"model/obj":["obj"],"model/step+xml":["stpx"],"model/step+zip":["stpz"],"model/step-xml+zip":["stpxz"],"model/stl":["stl"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["*x3db","x3dbz"],"model/x3d+fastinfoset":["x3db"],"model/x3d+vrml":["*x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"model/x3d-vrml":["x3dv"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/mdx":["mdx"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/richtext":["rtx"],"text/rtf":["*rtf"],"text/sgml":["sgml","sgm"],"text/shex":["shex"],"text/slim":["slim","slm"],"text/spdx":["spdx"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vtt":["vtt"],"text/xml":["*xml"],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/iso.segment":["m4s"],"video/jpeg":["jpgv"],"video/jpm":["*jpm","jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/webm":["webm"]};
22916
22917
var other = {"application/prs.cww":["cww"],"application/vnd.1000minds.decision-model+xml":["1km"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.keynote":["key"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.apple.numbers":["numbers"],"application/vnd.apple.pages":["pages"],"application/vnd.apple.pkpass":["pkpass"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.balsamiq.bmml+xml":["bmml"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.citationstyles.style+xml":["csl"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dbf":["dbf"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-apps.document":["gdoc"],"application/vnd.google-apps.presentation":["gslides"],"application/vnd.google-apps.spreadsheet":["gsheet"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.hydrostatix.sof-data":["sfd-hdstx"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mapbox-vector-tile":["mvt"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-outlook":["msg"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["*stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.ac+xml":["*ac"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.n-gage.symbian.install":["n-gage"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openblox.game+xml":["obgx"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openstreetmap.data+xml":["osm"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.rar":["rar"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.software602.filler.form+xml":["fo"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.wadl+xml":["wadl"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.syncml.dmddf+xml":["ddf"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":["*dmg"],"application/x-arj":["arj"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bdoc":["*bdoc"],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-cocoa":["cco"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["*deb","udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-httpd-php":["php"],"application/x-install-instructions":["install"],"application/x-iso9660-image":["*iso"],"application/x-iwork-keynote-sffkey":["*key"],"application/x-iwork-numbers-sffnumbers":["*numbers"],"application/x-iwork-pages-sffpages":["*pages"],"application/x-java-archive-diff":["jardiff"],"application/x-java-jnlp-file":["jnlp"],"application/x-keepass2":["kdbx"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-makeself":["run"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdos-program":["*exe"],"application/x-msdownload":["*exe","*dll","com","bat","*msi"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["*wmf","*wmz","*emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-ns-proxy-autoconfig":["pac"],"application/x-nzb":["nzb"],"application/x-perl":["pl","pm"],"application/x-pilot":["*prc","*pdb"],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["*rar"],"application/x-redhat-package-manager":["rpm"],"application/x-research-info-systems":["ris"],"application/x-sea":["sea"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl","tk"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["*obj"],"application/x-ustar":["ustar"],"application/x-virtualbox-hdd":["hdd"],"application/x-virtualbox-ova":["ova"],"application/x-virtualbox-ovf":["ovf"],"application/x-virtualbox-vbox":["vbox"],"application/x-virtualbox-vbox-extpack":["vbox-extpack"],"application/x-virtualbox-vdi":["vdi"],"application/x-virtualbox-vhd":["vhd"],"application/x-virtualbox-vmdk":["vmdk"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt","pem"],"application/x-xfig":["fig"],"application/x-xliff+xml":["*xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-m4a":["*m4a"],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-realaudio":["*ra"],"audio/x-wav":["*wav"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"image/prs.btif":["btif"],"image/prs.pti":["pti"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.airzip.accelerator.azv":["azv"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":["*sub"],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.microsoft.icon":["ico"],"image/vnd.ms-dds":["dds"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.pco.b16":["b16"],"image/vnd.tencent.tap":["tap"],"image/vnd.valve.source.texture":["vtf"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/vnd.zbrush.pcx":["pcx"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["*ico"],"image/x-jng":["jng"],"image/x-mrsid-image":["sid"],"image/x-ms-bmp":["*bmp"],"image/x-pcx":["*pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/vnd.wfa.wsc":["wsc"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.opengex":["ogex"],"model/vnd.parasolid.transmit.binary":["x_b"],"model/vnd.parasolid.transmit.text":["x_t"],"model/vnd.sap.vds":["vds"],"model/vnd.usdz+zip":["usdz"],"model/vnd.valve.source.compiled-map":["bsp"],"model/vnd.vtu":["vtu"],"text/prs.lines.tag":["dsc"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-org":["*org"],"text/x-pascal":["p","pas"],"text/x-processing":["pde"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-suse-ymp":["ymp"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]};
22918
22919
let Mime = Mime_1;
22920
var mime = new Mime(standard, other);
22921
22922
/*global Shiny, $, DOMParser, MutationObserver, URL
22923
*
22924
* quarto-ojs.js
22925
*
22926
* Copyright (C) 2021 RStudio, PBC
22927
*
22928
*/
22929
22930
//////////////////////////////////////////////////////////////////////////////
22931
22932
function displayOJSWarning(warning)
22933
{
22934
const cells = [];
22935
for (
22936
const content of document.querySelectorAll('script[type="ojs-module-contents"]')
22937
) {
22938
for (const cellJson of JSON.parse(base64ToStr(content.text)).contents) {
22939
let cell = document.getElementById(cellJson.cellName) || document.getElementById(`${cellJson.cellName}-1`);
22940
if (!cell) {
22941
// give up
22942
continue;
22943
}
22944
cells.push(cell);
22945
}
22946
}
22947
22948
debugger;
22949
cells.forEach((cell) => {
22950
debugger;
22951
cell.innerHTML = "";
22952
22953
const message = warning();
22954
22955
cell.appendChild(
22956
calloutBlock({
22957
heading: "Error",
22958
type: "error",
22959
message
22960
})
22961
);
22962
});
22963
}
22964
22965
function displayQtWebEngineError() {
22966
displayOJSWarning(() => {
22967
const message = document.createElement("div");
22968
message.appendChild(document.createTextNode("This document uses OJS, which requires JavaScript features not present in this version of QtWebEngine. If you're using RStudio IDE, please upgrade to a "));
22969
const link = document.createElement("a");
22970
link.appendChild(document.createTextNode("2022.12 build"));
22971
link.href = "https://dailies.rstudio.com/rstudio/elsbeth-geranium/";
22972
message.appendChild(link);
22973
message.appendChild(document.createTextNode("."));
22974
return message;
22975
});
22976
}
22977
22978
function displayFileProtocolError() {
22979
displayOJSWarning(() => {
22980
const message = document.createElement("div");
22981
message.appendChild(document.createTextNode("This document uses OJS, which requires JavaScript features disabled when running in file://... URLs. In order for these features to work, run this document in a web server."));
22982
return message;
22983
});
22984
}
22985
22986
22987
//////////////////////////////////////////////////////////////////////////////
22988
// Quarto-specific code starts here.
22989
22990
// For RStudio IDE integration
22991
/** creates a click handler to point the IDE to a given line and column */
22992
const makeDevhostErrorClickHandler = (line, column) => {
22993
return function () {
22994
if (!window.quartoDevhost) {
22995
return false;
22996
}
22997
window.quartoDevhost.openInputFile(line, column, true);
22998
return false;
22999
};
23000
};
23001
23002
// we cannot depend on Object.fromEntries because the IDE
23003
// doesn't support it. We minimally polyfill it
23004
if (Object.fromEntries === undefined) {
23005
Object.fromEntries = function (obj) {
23006
const result = {};
23007
for (const [key, value] of obj) {
23008
result[key] = value;
23009
}
23010
return result;
23011
};
23012
}
23013
23014
/** create a callout block with the given opts, currently to be used
23015
to signal a runtime error in the observable runtime.
23016
*/
23017
function calloutBlock(opts) {
23018
const { type, heading, message, onclick } = opts;
23019
23020
const outerBlock = document.createElement("div");
23021
outerBlock.classList.add(
23022
`callout-${type}`,
23023
"callout",
23024
"callout-style-default",
23025
"callout-captioned"
23026
);
23027
const header = document.createElement("div");
23028
header.classList.add("callout-header", "d-flex", "align-content-center");
23029
const iconContainer = document.createElement("div");
23030
iconContainer.classList.add("callout-icon-container");
23031
const icon = document.createElement("i");
23032
icon.classList.add("callout-icon");
23033
iconContainer.appendChild(icon);
23034
header.appendChild(iconContainer);
23035
23036
const headingDiv = document.createElement("div");
23037
headingDiv.classList.add("callout-caption-container", "flex-fill");
23038
// we assume heading is either a string or a span
23039
if (typeof heading === "string") {
23040
headingDiv.innerText = heading;
23041
} else {
23042
headingDiv.appendChild(heading);
23043
}
23044
header.appendChild(headingDiv);
23045
outerBlock.appendChild(header);
23046
23047
const container = document.createElement("div");
23048
container.classList.add("callout-body-container", "callout-body");
23049
if (typeof message === "string") {
23050
const p = document.createElement("p");
23051
p.innerText = message;
23052
container.appendChild(p);
23053
} else {
23054
container.append(message);
23055
}
23056
outerBlock.appendChild(container);
23057
23058
if (onclick) {
23059
outerBlock.onclick = onclick;
23060
outerBlock.style.cursor = "pointer";
23061
}
23062
23063
return outerBlock;
23064
}
23065
23066
const kQuartoModuleWaitClass = "ojs-in-a-box-waiting-for-module-import";
23067
23068
class QuartoOJSConnector extends OJSConnector {
23069
constructor(opts) {
23070
super(opts);
23071
}
23072
23073
////////////////////////////////////////////////////////////////////////////
23074
// handle import module waits
23075
23076
clearImportModuleWait() {
23077
const array = Array.from(
23078
document.querySelectorAll(`.${kQuartoModuleWaitClass}`)
23079
);
23080
for (const node of array) {
23081
node.classList.remove(kQuartoModuleWaitClass);
23082
}
23083
}
23084
23085
finishInterpreting() {
23086
return super.finishInterpreting().then(() => {
23087
if (this.mainModuleHasImports) {
23088
this.clearImportModuleWait();
23089
}
23090
});
23091
}
23092
23093
////////////////////////////////////////////////////////////////////////////
23094
// Error tracking/reporting
23095
23096
locatePreDiv(cellDiv, ojsDiv) {
23097
// locate the correct pre div with the pandocDecorator
23098
// of all potential divs, we need to find the one that most
23099
// immediately precedes `ojsDiv` in the DOM.
23100
let preDiv;
23101
for (const candidate of cellDiv.querySelectorAll("pre.sourceCode")) {
23102
if (
23103
candidate.compareDocumentPosition(ojsDiv) &
23104
ojsDiv.DOCUMENT_POSITION_FOLLOWING
23105
) {
23106
preDiv = candidate;
23107
} else {
23108
break;
23109
}
23110
}
23111
return preDiv;
23112
}
23113
23114
findCellOutputDisplay(ojsDiv) {
23115
while (ojsDiv && !ojsDiv.classList.contains("cell-output-display")) {
23116
ojsDiv = ojsDiv.parentElement;
23117
}
23118
if (!ojsDiv) {
23119
return null;
23120
}
23121
return ojsDiv;
23122
}
23123
23124
setPreDivClasses(preDiv, hasErrors) {
23125
if (!hasErrors) {
23126
preDiv.classList.remove("numberSource");
23127
if (preDiv._hidden === true) {
23128
const parent = preDiv.parentElement;
23129
parent.classList.add("hidden");
23130
// when code-tools is active (that is, when pre is inside a details tag), we also need to hide the details tag.
23131
if (parent.parentElement.tagName === "DETAILS") {
23132
parent.parentElement.classList.add("hidden");
23133
}
23134
}
23135
} else {
23136
preDiv.classList.add("numberSource");
23137
const parent = preDiv.parentElement;
23138
if (parent.classList.contains("hidden")) {
23139
preDiv._hidden = true; // signal that we used to be hidden so that when errors go away, we're hidden again.
23140
parent.classList.remove("hidden");
23141
23142
// when code-tools is active (that is, when pre is inside a details tag), we also need to unhide the details tag.
23143
if (parent.parentElement.tagName === "DETAILS") {
23144
parent.parentElement.classList.remove("hidden");
23145
// open the code-tools by default when error happens.
23146
parent.parentElement.setAttribute("open", "open");
23147
}
23148
}
23149
}
23150
}
23151
23152
clearErrorPinpoints(cellDiv, ojsDiv) {
23153
const preDiv = this.locatePreDiv(cellDiv, ojsDiv);
23154
if (preDiv === undefined) {
23155
return;
23156
}
23157
this.setPreDivClasses(preDiv, false);
23158
let startingOffset = 0;
23159
if (preDiv.parentElement.dataset.sourceOffset) {
23160
startingOffset = -Number(preDiv.parentElement.dataset.sourceOffset);
23161
}
23162
for (const entryPoint of preDiv._decorator.spanSelection(
23163
startingOffset,
23164
Infinity
23165
)) {
23166
const { node } = entryPoint;
23167
node.classList.remove("quarto-ojs-error-pinpoint");
23168
node.onclick = null;
23169
}
23170
}
23171
23172
decorateOjsDivWithErrorPinpoint(ojsDiv, start, end, line, column) {
23173
const cellOutputDisplay = this.findCellOutputDisplay(ojsDiv);
23174
// if ojs element is inline, there's no div.
23175
if (!cellOutputDisplay) {
23176
return;
23177
}
23178
if (cellOutputDisplay._errorSpans === undefined) {
23179
cellOutputDisplay._errorSpans = [];
23180
}
23181
cellOutputDisplay._errorSpans.push({
23182
start,
23183
end,
23184
line,
23185
column,
23186
});
23187
}
23188
23189
decorateSource(cellDiv, ojsDiv) {
23190
if (!cellDiv) {
23191
// no div in inline spans
23192
return;
23193
}
23194
this.clearErrorPinpoints(cellDiv, ojsDiv);
23195
const preDiv = this.locatePreDiv(cellDiv, ojsDiv);
23196
// sometimes the source code is not echoed.
23197
// FIXME: should ojs source always be "hidden" so we can show it
23198
// in case of runtime errors?
23199
if (preDiv === undefined) {
23200
return;
23201
}
23202
// now find all ojsDivs that contain errors that need to be decorated
23203
// on preDiv
23204
let parent = preDiv.parentElement;
23205
if (parent.parentElement.tagName === "DETAILS") {
23206
// we're in a code-tools setting, need to go one further up
23207
parent = parent.parentElement;
23208
}
23209
let div = parent.nextElementSibling;
23210
let foundErrors = false;
23211
while (div !== null && div.classList.contains("cell-output-display")) {
23212
for (const errorSpan of div._errorSpans || []) {
23213
for (const entryPoint of preDiv._decorator.spanSelection(
23214
errorSpan.start,
23215
errorSpan.end
23216
)) {
23217
const { node } = entryPoint;
23218
node.classList.add("quarto-ojs-error-pinpoint");
23219
node.onclick = makeDevhostErrorClickHandler(
23220
errorSpan.line,
23221
errorSpan.column
23222
);
23223
}
23224
foundErrors = true;
23225
}
23226
div = div.nextElementSibling;
23227
}
23228
this.setPreDivClasses(preDiv, foundErrors);
23229
}
23230
23231
clearError(ojsDiv) {
23232
const cellOutputDisplay = this.findCellOutputDisplay(ojsDiv);
23233
// if ojs element is inline, there's no div.
23234
if (cellOutputDisplay)
23235
cellOutputDisplay._errorSpans = [];
23236
}
23237
23238
signalError(cellDiv, ojsDiv, ojsAst) {
23239
const buildCallout = (ojsDiv) => {
23240
let onclick;
23241
const inspectChild = ojsDiv.querySelector(".observablehq--inspect");
23242
let [heading, message] = inspectChild.textContent.split(": ");
23243
if (heading === "RuntimeError") {
23244
heading = "OJS Runtime Error";
23245
if (message.match(/^(.+) is not defined$/)) {
23246
const [varName, ...rest] = message.split(" ");
23247
const p = document.createElement("p");
23248
const tt = document.createElement("tt");
23249
tt.innerText = varName;
23250
p.appendChild(tt);
23251
p.appendChild(document.createTextNode(" " + rest.join(" ")));
23252
message = p;
23253
23254
const preDiv = this.locatePreDiv(cellDiv, ojsDiv);
23255
// preDiv might not be exist in case source isn't echoed to HTML
23256
if (preDiv !== undefined) {
23257
// force line numbers to show
23258
preDiv.classList.add("numberSource");
23259
const missingRef = ojsAst.references.find(
23260
(n) => n.name === varName
23261
);
23262
// TODO when missingRef === undefined, it likely means an unresolved
23263
// import reference. For now we will leave things as is, but
23264
// this needs better handling.
23265
if (missingRef !== undefined) {
23266
const { line, column } = preDiv._decorator.offsetToLineColumn(
23267
missingRef.start
23268
);
23269
const headingSpan = document.createElement("span");
23270
const headingTextEl = document.createTextNode(
23271
`${heading} (line ${line}, column ${column}) `
23272
);
23273
headingSpan.appendChild(headingTextEl);
23274
if (window.quartoDevhost) {
23275
const clicker = document.createElement("a");
23276
clicker.href = "#"; // this forces the right CSS to apply
23277
clicker.innerText = "(source)";
23278
onclick = makeDevhostErrorClickHandler(line, column);
23279
headingSpan.appendChild(clicker);
23280
}
23281
heading = headingSpan;
23282
this.decorateOjsDivWithErrorPinpoint(
23283
ojsDiv,
23284
missingRef.start,
23285
missingRef.end,
23286
line,
23287
column
23288
);
23289
}
23290
}
23291
} else if (
23292
message.match(/^(.+) could not be resolved$/) ||
23293
message.match(/^(.+) is defined more than once$/)
23294
) {
23295
const [varName, ...rest] = message.split(" ");
23296
const p = document.createElement("p");
23297
const tt = document.createElement("tt");
23298
tt.innerText = varName;
23299
p.appendChild(tt);
23300
p.appendChild(document.createTextNode(" " + rest.join(" ")));
23301
message = p;
23302
} else {
23303
const p = document.createElement("p");
23304
p.appendChild(document.createTextNode(message));
23305
message = p;
23306
}
23307
} else {
23308
heading = "OJS Error";
23309
const p = document.createElement("p");
23310
p.appendChild(document.createTextNode(inspectChild.textContent));
23311
message = p;
23312
}
23313
const callout = calloutBlock({
23314
type: "important",
23315
heading,
23316
message,
23317
onclick,
23318
});
23319
ojsDiv.appendChild(callout);
23320
};
23321
23322
buildCallout(ojsDiv);
23323
}
23324
23325
interpret(src, elementGetter, elementCreator) {
23326
// deno-lint-ignore no-this-alias
23327
const that = this;
23328
const observer = (targetElement, ojsAst) => {
23329
return (name) => {
23330
const element =
23331
typeof elementCreator === "function"
23332
? elementCreator()
23333
: elementCreator;
23334
targetElement.appendChild(element);
23335
23336
// TODO the unofficial interpreter always calls viewexpression observers
23337
// twice, one with the name, and the next with 'viewof $name'.
23338
// we check for 'viewof ' here and hide the element we're creating.
23339
// this behavior appears inconsistent with OHQ's interpreter, so we
23340
// shouldn't be surprised to see this fail in the future.
23341
if (
23342
ojsAst.id &&
23343
ojsAst.id.type === "ViewExpression" &&
23344
!name.startsWith("viewof ")
23345
) {
23346
element.classList.add("quarto-ojs-hide");
23347
}
23348
23349
// handle output:all hiding
23350
//
23351
// if every output from a cell is is not displayed, then we
23352
// must also not display the cell output display element
23353
// itself.
23354
23355
// collect the cell element as well as the cell output display
23356
// element
23357
let cellDiv = targetElement;
23358
let cellOutputDisplay;
23359
while (cellDiv !== null && !cellDiv.classList.contains("cell")) {
23360
cellDiv = cellDiv.parentElement;
23361
if (cellDiv && cellDiv.classList.contains("cell-output-display")) {
23362
cellOutputDisplay = cellDiv;
23363
}
23364
}
23365
const forceShowDeclarations = (!cellDiv) || (cellDiv.dataset.output === "all");
23366
23367
const config = { childList: true };
23368
const callback = function (mutationsList) {
23369
// we may fail to find a cell in inline settings; but
23370
// inline cells won't have inspectors, so in that case
23371
// we never hide
23372
for (const mutation of mutationsList) {
23373
const ojsDiv = mutation.target;
23374
23375
if (!forceShowDeclarations) {
23376
const childNodes = Array.from(mutation.target.childNodes);
23377
for (const n of childNodes) {
23378
// hide the inner inspect outputs that aren't errors or
23379
// declarations
23380
if (
23381
n.classList.contains("observablehq--inspect") &&
23382
!n.parentNode.classList.contains("observablehq--error") &&
23383
n.parentNode.parentNode.dataset.nodetype !== "expression"
23384
) {
23385
n.classList.add("quarto-ojs-hide");
23386
}
23387
// show the inspect outputs that aren't errors and are
23388
// expressions (they might have been hidden in the past,
23389
// since errors can clear)
23390
if (
23391
n.classList.contains("observablehq--inspect") &&
23392
!n.parentNode.classList.contains("observablehq--error") &&
23393
n.parentNode.parentNode.dataset.nodetype === "expression"
23394
) {
23395
n.classList.remove("quarto-ojs-hide");
23396
}
23397
}
23398
}
23399
23400
// if the ojsDiv shows an error, display a callout block instead of it.
23401
if (ojsDiv.classList.contains("observablehq--error")) {
23402
// we don't use quarto-ojs-hide here because that would confuse
23403
// the code which depends on that class for its logic.
23404
ojsDiv.querySelector(".observablehq--inspect").style.display =
23405
"none";
23406
23407
if (ojsDiv.querySelectorAll(".callout-important").length === 0) {
23408
that.signalError(cellDiv, ojsDiv, ojsAst);
23409
}
23410
} else {
23411
that.clearError(ojsDiv);
23412
if (
23413
ojsDiv.parentNode.dataset.nodetype !== "expression" &&
23414
!forceShowDeclarations &&
23415
Array.from(ojsDiv.childNodes).every((n) =>
23416
n.classList.contains("observablehq--inspect")
23417
)
23418
) {
23419
// if every child is an inspect output, hide the ojsDiv
23420
ojsDiv.classList.add("quarto-ojs-hide");
23421
}
23422
}
23423
23424
that.decorateSource(cellDiv, ojsDiv);
23425
23426
for (const added of mutation.addedNodes) {
23427
23428
// https://github.com/quarto-dev/quarto-cli/issues/7426
23429
// ObservableHQ.Plot fixup:
23430
// remove "background: white" from style declaration
23431
if (added.tagName === "svg" &&
23432
Array.from(added.classList)
23433
.some(x => x.match(/plot-[0-9a-f]+/))) {
23434
// this overrides the style CSS inside.
23435
added.style.background = "none";
23436
}
23437
23438
if (
23439
added.tagName === "FORM" &&
23440
Array.from(added.classList).some(
23441
(x) => x.endsWith("table") && x.startsWith("oi-")
23442
)
23443
) {
23444
// add quarto-specific classes to OJS-generated tables
23445
added.classList.add("quarto-ojs-table-fixup");
23446
23447
// in dashboard, change styles so that autosizing works
23448
if (window._ojs.isDashboard) {
23449
const table = added.querySelector("table");
23450
if (table) {
23451
table.style.width = "100%";
23452
}
23453
added.style.maxHeight = null;
23454
added.style.margin = "0 0 0 0";
23455
added.style.padding = "0 0 0 0";
23456
23457
// find parentElement with class cell-output-display or cell
23458
let parent = added.parentElement;
23459
while (parent && !parent.classList.contains("cell-output-display") && !parent.classList.contains("cell")) {
23460
parent = parent.parentElement;
23461
}
23462
if (parent !== null && added.clientHeight > parent.clientHeight) {
23463
added.style.maxHeight = `${parent.clientHeight}px`;
23464
}
23465
}
23466
}
23467
23468
// add quarto-specific classes to OJS-generated buttons
23469
const addedButtons = added.querySelectorAll("button");
23470
for (const button of Array.from(addedButtons)) {
23471
button.classList.add("btn");
23472
button.classList.add("btn-quarto");
23473
}
23474
23475
// hide import statements even if output === "all"
23476
//// Hide imports that aren't javascript code
23477
//
23478
// We search here for code.javascript and node span.hljs-... because
23479
// at this point in the DOM, observable's runtime hasn't called
23480
// HLJS yet. if you inspect the DOM yourself, you're likely to see
23481
// HLJS, so this comment is here to prevent future confusion.
23482
const result = added.querySelectorAll("code.javascript");
23483
if (result.length !== 1) {
23484
continue;
23485
}
23486
if (result[0].textContent.trim().startsWith("import")) {
23487
ojsDiv.classList.add("quarto-ojs-hide");
23488
}
23489
}
23490
}
23491
23492
// cellOutputDisplay doesn't exist in inline spans, so we must check it explicitly
23493
if (cellOutputDisplay) {
23494
const children = Array.from(
23495
cellOutputDisplay.querySelectorAll("div.observablehq")
23496
);
23497
// after all mutations are handled, we check the full cell for hiding
23498
if (
23499
children.every((n) => {
23500
return n.classList.contains("quarto-ojs-hide");
23501
})
23502
) {
23503
cellOutputDisplay.classList.add("quarto-ojs-hide");
23504
} else {
23505
cellOutputDisplay.classList.remove("quarto-ojs-hide");
23506
}
23507
}
23508
};
23509
new MutationObserver(callback).observe(element, config);
23510
// 'element' is the outer div given to observable's runtime to insert their output
23511
// every quarto cell will have either one or two such divs.
23512
// The parent of these divs should always be a div corresponding to an ojs "cell"
23513
// (with ids "ojs-cell-*")
23514
23515
element.classList.add(kQuartoModuleWaitClass);
23516
23517
return new this.inspectorClass(element, ojsAst);
23518
};
23519
};
23520
const runCell = (cell) => {
23521
const targetElement =
23522
typeof elementGetter === "function" ? elementGetter() : elementGetter;
23523
const cellSrc = src.slice(cell.start, cell.end);
23524
const promise = this.interpreter.module(
23525
cellSrc,
23526
undefined,
23527
observer(targetElement, cell)
23528
);
23529
return this.waitOnImports(cell, promise);
23530
};
23531
return this.interpretWithRunner(src, runCell);
23532
}
23533
}
23534
23535
//////////////////////////////////////////////////////////////////////////////
23536
// previously quarto-observable-shiny.js
23537
23538
function createRuntime() {
23539
const quartoOjsGlobal = window._ojs;
23540
const isShiny = window.Shiny !== undefined;
23541
23542
// Are we QtWebEngine? bail
23543
if (window.navigator.userAgent.includes("QtWebEngine")) {
23544
displayQtWebEngineError();
23545
return;
23546
}
23547
23548
// Are we file://? bail
23549
if (window.location.protocol === "file:") {
23550
displayFileProtocolError();
23551
return;
23552
}
23553
23554
// Are we shiny?
23555
if (isShiny) {
23556
quartoOjsGlobal.hasShiny = true;
23557
initOjsShinyRuntime();
23558
23559
const span = document.createElement("span");
23560
window._ojs.shinyElementRoot = span;
23561
document.body.appendChild(span);
23562
}
23563
23564
// we use the trick described here to extend observable runtime's standard library
23565
// https://talk.observablehq.com/t/embedded-width/1063
23566
23567
// stdlib from our fork, which uses the safe d3-require
23568
const lib = new Library();
23569
if (isShiny) {
23570
extendObservableStdlib(lib);
23571
}
23572
23573
function transpose(df) {
23574
const keys = Object.keys(df);
23575
return df[keys[0]]
23576
.map((v, i) =>
23577
Object.fromEntries(keys.map((key) => {
23578
const v = df[key][i];
23579
const result = v === null ? undefined : v;
23580
return [key, result];
23581
})))
23582
.filter((v) => !Object.values(v).every((e) => e === undefined));
23583
}
23584
lib.transpose = () => transpose;
23585
23586
// TODO this should be user-configurable, so that we can actually
23587
// make it work in arbitrary layouts.
23588
// There's probably a slick reactive trick to make the element
23589
// user settable.
23590
//
23591
// Right now we support quarto's standard HTML formats
23592
23593
const mainEl = (document.querySelector("main") // html
23594
|| document.querySelector("div.reveal") // reveal
23595
|| document.querySelector("body")); // fall-through
23596
23597
function cards() {
23598
if (mainEl === null) {
23599
return lib.Generators.observe((change) => {
23600
change(undefined);
23601
});
23602
}
23603
return lib.Generators.observe(function(change) {
23604
let previous = undefined;
23605
function resized() {
23606
let changed = false;
23607
const result = {};
23608
let cellIndex = 0;
23609
const handle = (card) => {
23610
const cardInfo = {
23611
card,
23612
width: card.clientWidth,
23613
height: card.clientHeight,
23614
};
23615
result[cellIndex] = cardInfo;
23616
if (previous === undefined ||
23617
previous[cellIndex].width !== cardInfo.width ||
23618
previous[cellIndex].height !== cardInfo.height) {
23619
changed = true;
23620
}
23621
cellIndex++;
23622
23623
// there can be an id in the card itself, allow that as a key
23624
if (card.id) {
23625
result[card.id] = cardInfo;
23626
}
23627
};
23628
for (const card of document.querySelectorAll("div.card")) {
23629
for (const cell of card.querySelectorAll("div.cell-output-display")) {
23630
handle(cell);
23631
}
23632
for (const cell of card.querySelectorAll("div.quarto-layout-cell")) {
23633
handle(cell);
23634
}
23635
}
23636
for (const card of document.querySelectorAll("div")) {
23637
if (!(card.id.startsWith("ojs-cell-"))) {
23638
continue;
23639
}
23640
let cardInfoCard;
23641
// many possible cases:
23642
23643
if (card.parentElement.classList.contains("cell-output-display")) {
23644
// single cell: card parent is cell-output-display
23645
cardInfoCard = card.parentElement;
23646
} else if (card.parentElement.classList.contains("quarto-layout-cell")) {
23647
// subcell of layout
23648
cardInfoCard = card.parentElement;
23649
} else if (card.parentElement.parentElement.classList.contains("cell-output-display")) {
23650
// subcell of cell-output-display
23651
cardInfoCard = card.parentElement.parentElement;
23652
} else {
23653
continue;
23654
}
23655
const cardInfo = {
23656
card: cardInfoCard,
23657
width: card.clientWidth,
23658
height: card.clientHeight,
23659
};
23660
result[card.id] = cardInfo;
23661
if (previous === undefined ||
23662
previous[card.id].width !== cardInfo.width ||
23663
previous[card.id].height !== cardInfo.height) {
23664
changed = true;
23665
}
23666
if (card.parentElement.id !== "") {
23667
result[card.parentElement.id] = cardInfo;
23668
}
23669
}
23670
23671
if (changed) {
23672
previous = result;
23673
change(result);
23674
}
23675
}
23676
resized();
23677
window.addEventListener("resize", resized);
23678
return function() {
23679
window.removeEventListener("resize", resized);
23680
}
23681
});
23682
}
23683
23684
function width() {
23685
if (mainEl === null) {
23686
return lib.Generators.observe((change) => {
23687
change(undefined);
23688
});
23689
}
23690
return lib.Generators.observe(function (change) {
23691
var width = change(mainEl.clientWidth);
23692
function resized() {
23693
var w = mainEl.clientWidth;
23694
if (w !== width) change((width = w));
23695
}
23696
window.addEventListener("resize", resized);
23697
return function () {
23698
window.removeEventListener("resize", resized);
23699
};
23700
});
23701
}
23702
lib.width = width;
23703
lib.cards = cards;
23704
23705
// hack for "echo: fenced": remove all "//| echo: fenced" lines the hard way, but keep
23706
// the right line numbers around.
23707
Array.from(document.querySelectorAll("span.co"))
23708
.filter((n) => n.textContent === "//| echo: fenced")
23709
.forEach((n) => {
23710
const lineSpan = n.parentElement;
23711
const lineBreak = lineSpan.nextSibling;
23712
if (lineBreak) {
23713
const nextLineSpan = lineBreak.nextSibling;
23714
if (nextLineSpan) {
23715
const lineNumber = Number(nextLineSpan.id.split("-")[1]);
23716
nextLineSpan.style = `counter-reset: source-line ${lineNumber - 1}`;
23717
}
23718
}
23719
23720
// update the source offset variable with the new right amount
23721
const sourceDiv = lineSpan.parentElement.parentElement.parentElement;
23722
const oldOffset = Number(sourceDiv.dataset.sourceOffset);
23723
sourceDiv.dataset.sourceOffset = oldOffset - "//| echo: fenced\n".length;
23724
23725
lineSpan.remove();
23726
lineBreak.remove();
23727
});
23728
23729
// select all elements to track:
23730
// panel elements with ids, and divs with ids and .ojs-track-layout
23731
23732
const layoutDivs = [...Array.from(
23733
document.querySelectorAll("div.quarto-layout-panel div[id]")
23734
),
23735
...Array.from(
23736
document.querySelectorAll('div.ojs-track-layout[id]')
23737
)];
23738
23739
function layoutWidth() {
23740
return lib.Generators.observe(function (change) {
23741
const ourWidths = Object.fromEntries(
23742
layoutDivs.map((div) => [div.id, div.clientWidth])
23743
);
23744
change(ourWidths);
23745
function resized() {
23746
let changed = false;
23747
for (const div of layoutDivs) {
23748
const w = div.clientWidth;
23749
if (w !== ourWidths[div.id]) {
23750
ourWidths[div.id] = w;
23751
changed = true;
23752
}
23753
}
23754
if (changed) {
23755
change(ourWidths);
23756
}
23757
}
23758
window.addEventListener("resize", resized);
23759
return function () {
23760
window.removeEventListener("resize", resized);
23761
};
23762
});
23763
}
23764
lib.layoutWidth = layoutWidth;
23765
let localResolver = {};
23766
23767
function fileAttachmentPathResolver(n) {
23768
if (localResolver[n]) {
23769
return localResolver[n];
23770
}
23771
23772
let name;
23773
23774
// we need to remove the hash from the current path
23775
// for this to work in revealjs
23776
const currentPath = window.location.href.split("#")[0].replace(/[^/]*$/, '');
23777
23778
if (n.startsWith("/")) {
23779
// docToRoot can be empty, in which case naive concatenation creates
23780
// an absolute path.
23781
if (quartoOjsGlobal.paths.docToRoot === "") {
23782
name = `${currentPath}.${n}`;
23783
} else {
23784
name = `${currentPath}${quartoOjsGlobal.paths.docToRoot}${n}`;
23785
}
23786
} else if (n.startsWith("http")) {
23787
name = n;
23788
} else {
23789
name = `${currentPath}${n}`;
23790
}
23791
23792
const mimeType = mime.getType(name);
23793
23794
return {
23795
url: name,
23796
mimeType: mimeType,
23797
}
23798
23799
}
23800
lib.FileAttachment = () => FileAttachments(fileAttachmentPathResolver);
23801
23802
const ojsConnector = new QuartoOJSConnector({
23803
paths: quartoOjsGlobal.paths,
23804
inspectorClass: isShiny ? ShinyInspector : QuartoInspector,
23805
library: lib,
23806
allowPendingGlobals: isShiny,
23807
});
23808
quartoOjsGlobal.ojsConnector = ojsConnector;
23809
if (isShiny) {
23810
// When isShiny, OJSConnector is constructed with allowPendingGlobals:true.
23811
// Our guess is that most shiny-to-ojs exports will have been defined
23812
// by the time the server function finishes executing (i.e. session init
23813
// completion); so we call `killPendingGlobals()` to show errors for
23814
// variables that are still undefined.
23815
$(document).one("shiny:idle", () => {
23816
// "shiny:idle" is not late enough; it is raised before the resulting
23817
// outputs are received from the server.
23818
$(document).one("shiny:message", () => {
23819
// "shiny:message" is not late enough; it is raised after the message
23820
// is received, but before it is processed (i.e. variables are still
23821
// not actually defined).
23822
setTimeout(() => {
23823
ojsConnector.killPendingGlobals();
23824
}, 0);
23825
});
23826
});
23827
}
23828
23829
const subfigIdMap = new Map();
23830
function getSubfigId(elementId) {
23831
if (!subfigIdMap.has(elementId)) {
23832
subfigIdMap.set(elementId, 0);
23833
}
23834
let nextIx = subfigIdMap.get(elementId);
23835
nextIx++;
23836
subfigIdMap.set(elementId, nextIx);
23837
return `${elementId}-${nextIx}`;
23838
}
23839
23840
const sourceNodes = document.querySelectorAll(
23841
"pre.sourceCode code.sourceCode"
23842
);
23843
const decorators = Array.from(sourceNodes).map((n) => {
23844
n = n.parentElement;
23845
const decorator = new PandocCodeDecorator(n);
23846
n._decorator = decorator;
23847
return decorator;
23848
});
23849
// handle build-time syntax error
23850
decorators.forEach((n) => {
23851
if (n._node.parentElement.dataset.syntaxErrorPosition === undefined) {
23852
return;
23853
}
23854
const offset = Number(n._node.parentElement.dataset.syntaxErrorPosition);
23855
n.decorateSpan(offset, offset + 1, ["quarto-ojs-error-pinpoint"]);
23856
});
23857
23858
const result = {
23859
setLocalResolver(obj) {
23860
localResolver = obj;
23861
ojsConnector.setLocalResolver(obj);
23862
},
23863
finishInterpreting() {
23864
return ojsConnector.finishInterpreting();
23865
},
23866
23867
// return the latest value of the named reactive variable in the main module
23868
async value(name) {
23869
await this.finishInterpreting();
23870
const result = await ojsConnector.value(name);
23871
return result;
23872
},
23873
23874
// fixme clarify what's the expected behavior of the 'error' option
23875
// when evaluation is at client-time
23876
interpretLenient(src, targetElementId, inline) {
23877
return result.interpret(src, targetElementId, inline).catch(() => {});
23878
},
23879
interpret(src, targetElementId, inline) {
23880
// we capture the result here so that the error handler doesn't
23881
// grab a new id accidentally.
23882
let targetElement;
23883
const getElement = () => {
23884
targetElement = document.getElementById(targetElementId);
23885
let subFigId;
23886
if (!targetElement) {
23887
// this is a subfigure
23888
subFigId = getSubfigId(targetElementId);
23889
targetElement = document.getElementById(subFigId);
23890
if (!targetElement) {
23891
// console.error("Ran out of subfigures for element", targetElementId);
23892
// console.error("This will fail.");
23893
throw new Error("Ran out of quarto subfigures.");
23894
}
23895
}
23896
return targetElement;
23897
};
23898
23899
const makeElement = () => {
23900
return document.createElement(inline ? "span" : "div");
23901
};
23902
23903
return ojsConnector.interpret(src, getElement, makeElement).catch((e) => {
23904
// to the best of our knowledge, we only get here
23905
// on import statement failures. So we report those
23906
// in a callout
23907
23908
let cellDiv = targetElement;
23909
while (cellDiv !== null && !cellDiv.classList.contains("cell")) {
23910
cellDiv = cellDiv.parentElement;
23911
}
23912
23913
const ojsDiv = targetElement.querySelector(".observablehq");
23914
if (!ojsDiv) {
23915
// we failed to find an observablehq div inside the targetElement.
23916
// This is an internal error and we have no way to report it
23917
// except throwing the original exception.
23918
throw e;
23919
}
23920
// because this is in an exception handler, we might need
23921
// to clear some of the garbage that other pieces of code
23922
// won't have the chance to
23923
//
23924
for (const div of ojsDiv.querySelectorAll(".callout")) {
23925
div.remove();
23926
}
23927
23928
const messagePre = document.createElement("pre");
23929
messagePre.innerText = e.stack;
23930
23931
const callout = calloutBlock({
23932
type: "important",
23933
heading: `${e.name}: ${e.message}`,
23934
message: messagePre,
23935
});
23936
ojsDiv.appendChild(callout);
23937
ojsConnector.clearError(ojsDiv);
23938
ojsConnector.clearErrorPinpoints(cellDiv, ojsDiv);
23939
23940
return e;
23941
});
23942
},
23943
interpretQuiet(src) {
23944
return ojsConnector.interpretQuiet(src);
23945
},
23946
interpretFromScriptTags() {
23947
// source definitions
23948
for (const el of document.querySelectorAll(
23949
"script[type='ojs-module-contents']"
23950
)) {
23951
for (const call of JSON.parse(base64ToStr(el.text)).contents) {
23952
let source = window._ojs.isDashboard ? autosizeOJSPlot(call.source, call.cellName) : call.source;
23953
switch (call.methodName) {
23954
case "interpret":
23955
this.interpret(source, call.cellName, call.inline);
23956
break;
23957
case "interpretLenient":
23958
this.interpretLenient(source, call.cellName, call.inline);
23959
break;
23960
case "interpretQuiet":
23961
this.interpretQuiet(source);
23962
break;
23963
default:
23964
throw new Error(
23965
`Don't know how to call method ${call.methodName}`
23966
);
23967
}
23968
}
23969
}
23970
23971
// static data definitions
23972
for (const el of document.querySelectorAll("script[type='ojs-define']")) {
23973
for (const { name, value } of JSON.parse(el.text).contents) {
23974
ojsConnector.define(name)(value);
23975
}
23976
}
23977
},
23978
};
23979
23980
return result;
23981
}
23982
23983
23984
function initializeRuntime()
23985
{
23986
// TODO "obs" or "ojs"? Inconsistent naming.
23987
window._ojs = {
23988
ojsConnector: undefined,
23989
23990
paths: {}, // placeholder for per-quarto-file paths
23991
// necessary for module resolution
23992
23993
hasShiny: false, // true if we have the quarto-ojs-shiny runtime
23994
23995
isDashboard: document.body.classList.contains("quarto-dashboard"), // true if we are a dashboard format
23996
23997
shinyElementRoot: undefined, // root element for the communication with shiny
23998
// via DOM
23999
};
24000
window._ojs.runtime = createRuntime();
24001
window._ojs.jsx = createQuartoJsxShim();
24002
}
24003
24004
initializeRuntime();
24005
// export default init;
24006
24007