// @quarto/quarto-ojs-runtime v0.0.7 Copyright 2022 undefined
var EOL = {},
EOF = {},
QUOTE = 34,
NEWLINE = 10,
RETURN = 13;
function objectConverter(columns) {
return new Function("d", "return {" + columns.map(function(name, i) {
return JSON.stringify(name) + ": d[" + i + "] || \"\"";
}).join(",") + "}");
}
function customConverter(columns, f) {
var object = objectConverter(columns);
return function(row, i) {
return f(object(row), i, columns);
};
}
// Compute unique columns in order of discovery.
function inferColumns(rows) {
var columnSet = Object.create(null),
columns = [];
rows.forEach(function(row) {
for (var column in row) {
if (!(column in columnSet)) {
columns.push(columnSet[column] = column);
}
}
});
return columns;
}
function pad$1(value, width) {
var s = value + "", length = s.length;
return length < width ? new Array(width - length + 1).join(0) + s : s;
}
function formatYear$1(year) {
return year < 0 ? "-" + pad$1(-year, 6)
: year > 9999 ? "+" + pad$1(year, 6)
: pad$1(year, 4);
}
function formatDate$2(date) {
var hours = date.getUTCHours(),
minutes = date.getUTCMinutes(),
seconds = date.getUTCSeconds(),
milliseconds = date.getUTCMilliseconds();
return isNaN(date) ? "Invalid Date"
: formatYear$1(date.getUTCFullYear()) + "-" + pad$1(date.getUTCMonth() + 1, 2) + "-" + pad$1(date.getUTCDate(), 2)
+ (milliseconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "." + pad$1(milliseconds, 3) + "Z"
: seconds ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + ":" + pad$1(seconds, 2) + "Z"
: minutes || hours ? "T" + pad$1(hours, 2) + ":" + pad$1(minutes, 2) + "Z"
: "");
}
function dsv$1(delimiter) {
var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
DELIMITER = delimiter.charCodeAt(0);
function parse(text, f) {
var convert, columns, rows = parseRows(text, function(row, i) {
if (convert) return convert(row, i - 1);
columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
});
rows.columns = columns || [];
return rows;
}
function parseRows(text, f) {
var rows = [], // output rows
N = text.length,
I = 0, // current character index
n = 0, // current line number
t, // current token
eof = N <= 0, // current token followed by EOF?
eol = false; // current token followed by EOL?
// Strip the trailing newline.
if (text.charCodeAt(N - 1) === NEWLINE) --N;
if (text.charCodeAt(N - 1) === RETURN) --N;
function token() {
if (eof) return EOF;
if (eol) return eol = false, EOL;
// Unescape quotes.
var i, j = I, c;
if (text.charCodeAt(j) === QUOTE) {
while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
if ((i = I) >= N) eof = true;
else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
return text.slice(j + 1, i - 1).replace(/""/g, "\"");
}
// Find next delimiter or newline.
while (I < N) {
if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
else if (c !== DELIMITER) continue;
return text.slice(j, i);
}
// Return last token before EOF.
return eof = true, text.slice(j, N);
}
while ((t = token()) !== EOF) {
var row = [];
while (t !== EOL && t !== EOF) row.push(t), t = token();
if (f && (row = f(row, n++)) == null) continue;
rows.push(row);
}
return rows;
}
function preformatBody(rows, columns) {
return rows.map(function(row) {
return columns.map(function(column) {
return formatValue(row[column]);
}).join(delimiter);
});
}
function format(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join("\n");
}
function formatBody(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return preformatBody(rows, columns).join("\n");
}
function formatRows(rows) {
return rows.map(formatRow).join("\n");
}
function formatRow(row) {
return row.map(formatValue).join(delimiter);
}
function formatValue(value) {
return value == null ? ""
: value instanceof Date ? formatDate$2(value)
: reFormat.test(value += "") ? "\"" + value.replace(/"/g, "\"\"") + "\""
: value;
}
return {
parse: parse,
parseRows: parseRows,
format: format,
formatBody: formatBody,
formatRows: formatRows,
formatRow: formatRow,
formatValue: formatValue
};
}
var csv = dsv$1(",");
var csvParse = csv.parse;
var csvParseRows = csv.parseRows;
var tsv = dsv$1("\t");
var tsvParse = tsv.parse;
var tsvParseRows = tsv.parseRows;
function autoType(object) {
for (var key in object) {
var value = object[key].trim(), number, m;
if (!value) value = null;
else if (value === "true") value = true;
else if (value === "false") value = false;
else if (value === "NaN") value = NaN;
else if (!isNaN(number = +value)) value = number;
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})?)?$/)) {
if (fixtz && !!m[4] && !m[7]) value = value.replace(/-/g, "/").replace(/T/, " ");
value = new Date(value);
}
else continue;
object[key] = value;
}
return object;
}
// https://github.com/d3/d3-dsv/issues/45
const fixtz = new Date("2019-01-01T00:00").getHours() || new Date("2019-07-01T00:00").getHours();
const metas = new Map;
const queue$1 = [];
const map$2 = queue$1.map;
const some = queue$1.some;
const hasOwnProperty$2 = queue$1.hasOwnProperty;
const origin = "https://cdn.jsdelivr.net/npm/";
const identifierRe = /^((?:@[^/@]+\/)?[^/@]+)(?:@([^/]+))?(?:\/(.*))?$/;
const versionRe = /^\d+\.\d+\.\d+(-[\w-.+]+)?$/;
const extensionRe = /\.[^/]*$/;
const mains = ["unpkg", "jsdelivr", "browser", "main"];
class RequireError extends Error {
constructor(message) {
super(message);
}
}
RequireError.prototype.name = RequireError.name;
function main(meta) {
for (const key of mains) {
const value = meta[key];
if (typeof value === "string") {
return extensionRe.test(value) ? value : `${value}.js`;
}
}
}
function parseIdentifier(identifier) {
const match = identifierRe.exec(identifier);
return match && {
name: match[1],
version: match[2],
path: match[3]
};
}
function resolveMeta(target) {
const url = `${origin}${target.name}${target.version ? `@${target.version}` : ""}/package.json`;
let meta = metas.get(url);
if (!meta) metas.set(url, meta = fetch(url).then(response => {
if (!response.ok) throw new RequireError("unable to load package.json");
if (response.redirected && !metas.has(response.url)) metas.set(response.url, meta);
return response.json();
}));
return meta;
}
async function resolve$1(name, base) {
if (name.startsWith(origin)) name = name.substring(origin.length);
if (/^(\w+:)|\/\//i.test(name)) return name;
if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href;
if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new RequireError("illegal name");
const target = parseIdentifier(name);
if (!target) return `${origin}${name}`;
if (!target.version && base != null && base.startsWith(origin)) {
const meta = await resolveMeta(parseIdentifier(base.substring(origin.length)));
target.version = meta.dependencies && meta.dependencies[target.name] || meta.peerDependencies && meta.peerDependencies[target.name];
}
if (target.path && !extensionRe.test(target.path)) target.path += ".js";
if (target.path && target.version && versionRe.test(target.version)) return `${origin}${target.name}@${target.version}/${target.path}`;
const meta = await resolveMeta(target);
return `${origin}${meta.name}@${meta.version}/${target.path || main(meta) || "index.js"}`;
}
var require = requireFrom(resolve$1);
let requestsInFlight = 0;
let prevDefine = undefined;
function requireFrom(resolver) {
const cache = new Map;
const requireBase = requireRelative(null);
function requireAbsolute(url) {
if (typeof url !== "string") return url;
let module = cache.get(url);
if (!module) cache.set(url, module = new Promise((resolve, reject) => {
const script = document.createElement("script");
script.onload = () => {
try { resolve(queue$1.pop()(requireRelative(url))); }
catch (error) { reject(new RequireError("invalid module")); }
script.remove();
requestsInFlight--;
if (requestsInFlight === 0) {
window.define = prevDefine;
}
};
script.onerror = () => {
reject(new RequireError("unable to load module"));
script.remove();
requestsInFlight--;
if (requestsInFlight === 0) {
window.define = prevDefine;
}
};
script.async = true;
script.src = url;
if (requestsInFlight === 0) {
prevDefine = window.define;
window.define = define;
}
requestsInFlight++;
document.head.appendChild(script);
}));
return module;
}
function requireRelative(base) {
return name => Promise.resolve(resolver(name, base)).then(requireAbsolute);
}
function requireAlias(aliases) {
return requireFrom((name, base) => {
if (name in aliases) {
name = aliases[name], base = null;
if (typeof name !== "string") return name;
}
return resolver(name, base);
});
}
function require(name) {
return arguments.length > 1
? Promise.all(map$2.call(arguments, requireBase)).then(merge)
: requireBase(name);
}
require.alias = requireAlias;
require.resolve = resolver;
return require;
}
function merge(modules) {
const o = {};
for (const m of modules) {
for (const k in m) {
if (hasOwnProperty$2.call(m, k)) {
if (m[k] == null) Object.defineProperty(o, k, {get: getter(m, k)});
else o[k] = m[k];
}
}
}
return o;
}
function getter(object, name) {
return () => object[name];
}
function isbuiltin(name) {
name = name + "";
return name === "exports" || name === "module";
}
function define(name, dependencies, factory) {
const n = arguments.length;
if (n < 2) factory = name, dependencies = [];
else if (n < 3) factory = dependencies, dependencies = typeof name === "string" ? [] : name;
queue$1.push(some.call(dependencies, isbuiltin) ? require => {
const exports = {};
const module = {exports};
return Promise.all(map$2.call(dependencies, name => {
name = name + "";
return name === "exports" ? exports : name === "module" ? module : require(name);
})).then(dependencies => {
factory.apply(null, dependencies);
return module.exports;
});
} : require => {
return Promise.all(map$2.call(dependencies, require)).then(dependencies => {
return typeof factory === "function" ? factory.apply(null, dependencies) : factory;
});
});
}
define.amd = {};
function dependency(name, version, main) {
return {
resolve(path = main) {
return `https://cdn.jsdelivr.net/npm/${name}@${version}/${path}`;
}
};
}
const d3 = dependency("d3", "7.4.4", "dist/d3.min.js");
const inputs = dependency("@observablehq/inputs", "0.10.4", "dist/inputs.min.js");
const plot = dependency("@observablehq/plot", "0.4.3", "dist/plot.umd.min.js");
const graphviz = dependency("@observablehq/graphviz", "0.2.1", "dist/graphviz.min.js");
const highlight = dependency("@observablehq/highlight.js", "2.0.0", "highlight.min.js");
const katex = dependency("@observablehq/katex", "0.11.1", "dist/katex.min.js");
const lodash = dependency("lodash", "4.17.21", "lodash.min.js");
const htl = dependency("htl", "0.3.1", "dist/htl.min.js");
const jszip = dependency("jszip", "3.9.1", "dist/jszip.min.js");
const marked = dependency("marked", "0.3.12", "marked.min.js");
const sql = dependency("sql.js", "1.6.2", "dist/sql-wasm.js");
const vega = dependency("vega", "5.22.1", "build/vega.min.js");
const vegalite = dependency("vega-lite", "5.2.0", "build/vega-lite.min.js");
const vegaliteApi = dependency("vega-lite-api", "5.0.0", "build/vega-lite-api.min.js");
const arrow = dependency("apache-arrow", "4.0.1", "Arrow.es2015.min.js");
const arquero = dependency("arquero", "4.8.8", "dist/arquero.min.js");
const topojson = dependency("topojson-client", "3.1.0", "dist/topojson-client.min.js");
const exceljs = dependency("exceljs", "4.3.0", "dist/exceljs.min.js");
const mermaid$1 = dependency("mermaid", "9.0.0", "dist/mermaid.min.js");
function fromEntries(obj) {
const result = {};
for (const [key, value] of obj) {
result[key] = value;
}
return result;
}
async function sqlite(require) {
const init = await require(sql.resolve());
return init({locateFile: file => sql.resolve(`dist/${file}`)});
}
class SQLiteDatabaseClient {
constructor(db) {
Object.defineProperties(this, {
_db: {value: db}
});
}
static async open(source) {
const [SQL, buffer] = await Promise.all([sqlite(require), Promise.resolve(source).then(load$1)]);
return new SQLiteDatabaseClient(new SQL.Database(buffer));
}
async query(query, params) {
return await exec(this._db, query, params);
}
async queryRow(query, params) {
return (await this.query(query, params))[0] || null;
}
async explain(query, params) {
const rows = await this.query(`EXPLAIN QUERY PLAN ${query}`, params);
return element$1("pre", {className: "observablehq--inspect"}, [
text$2(rows.map(row => row.detail).join("\n"))
]);
}
async describe(object) {
const rows = await (object === undefined
? this.query(`SELECT name FROM sqlite_master WHERE type = 'table'`)
: this.query(`SELECT * FROM pragma_table_info(?)`, [object]));
if (!rows.length) throw new Error("Not found");
const {columns} = rows;
return element$1("table", {value: rows}, [
element$1("thead", [element$1("tr", columns.map(c => element$1("th", [text$2(c)])))]),
element$1("tbody", rows.map(r => element$1("tr", columns.map(c => element$1("td", [text$2(r[c])])))))
]);
}
async sql(strings, ...args) {
return this.query(strings.join("?"), args);
}
}
Object.defineProperty(SQLiteDatabaseClient.prototype, "dialect", {
value: "sqlite"
});
function load$1(source) {
return typeof source === "string" ? fetch(source).then(load$1)
: source instanceof Response || source instanceof Blob ? source.arrayBuffer().then(load$1)
: source instanceof ArrayBuffer ? new Uint8Array(source)
: source;
}
async function exec(db, query, params) {
const [result] = await db.exec(query, params);
if (!result) return [];
const {columns, values} = result;
const rows = values.map(row => fromEntries(row.map((value, i) => [columns[i], value])));
rows.columns = columns;
return rows;
}
function element$1(name, props, children) {
if (arguments.length === 2) children = props, props = undefined;
const element = document.createElement(name);
if (props !== undefined) for (const p in props) element[p] = props[p];
if (children !== undefined) for (const c of children) element.appendChild(c);
return element;
}
function text$2(value) {
return document.createTextNode(value);
}
class Workbook {
constructor(workbook) {
Object.defineProperties(this, {
_: {value: workbook},
sheetNames: {
value: workbook.worksheets.map((s) => s.name),
enumerable: true,
},
});
}
sheet(name, options) {
const sname =
typeof name === "number"
? this.sheetNames[name]
: this.sheetNames.includes((name += ""))
? name
: null;
if (sname == null) throw new Error(`Sheet not found: ${name}`);
const sheet = this._.getWorksheet(sname);
return extract(sheet, options);
}
}
function extract(sheet, {range, headers} = {}) {
let [[c0, r0], [c1, r1]] = parseRange(range, sheet);
const headerRow = headers ? sheet._rows[r0++] : null;
let names = new Set(["#"]);
for (let n = c0; n <= c1; n++) {
const value = headerRow ? valueOf(headerRow.findCell(n + 1)) : null;
let name = (value && value + "") || toColumn(n);
while (names.has(name)) name += "_";
names.add(name);
}
names = new Array(c0).concat(Array.from(names));
const output = new Array(r1 - r0 + 1);
for (let r = r0; r <= r1; r++) {
const row = (output[r - r0] = Object.create(null, {"#": {value: r + 1}}));
const _row = sheet.getRow(r + 1);
if (_row.hasValues)
for (let c = c0; c <= c1; c++) {
const value = valueOf(_row.findCell(c + 1));
if (value != null) row[names[c + 1]] = value;
}
}
output.columns = names.filter(() => true); // Filter sparse columns
return output;
}
function valueOf(cell) {
if (!cell) return;
const {value} = cell;
if (value && typeof value === "object" && !(value instanceof Date)) {
if (value.formula || value.sharedFormula) {
return value.result && value.result.error ? NaN : value.result;
}
if (value.richText) {
return richText(value);
}
if (value.text) {
let {text} = value;
if (text.richText) text = richText(text);
return value.hyperlink && value.hyperlink !== text
? `${value.hyperlink} ${text}`
: text;
}
return value;
}
return value;
}
function richText(value) {
return value.richText.map((d) => d.text).join("");
}
function parseRange(specifier = ":", {columnCount, rowCount}) {
specifier += "";
if (!specifier.match(/^[A-Z]*\d*:[A-Z]*\d*$/))
throw new Error("Malformed range specifier");
const [[c0 = 0, r0 = 0], [c1 = columnCount - 1, r1 = rowCount - 1]] =
specifier.split(":").map(fromCellReference);
return [
[c0, r0],
[c1, r1],
];
}
// Returns the default column name for a zero-based column index.
// For example: 0 -> "A", 1 -> "B", 25 -> "Z", 26 -> "AA", 27 -> "AB".
function toColumn(c) {
let sc = "";
c++;
do {
sc = String.fromCharCode(64 + (c % 26 || 26)) + sc;
} while ((c = Math.floor((c - 1) / 26)));
return sc;
}
// Returns the zero-based indexes from a cell reference.
// For example: "A1" -> [0, 0], "B2" -> [1, 1], "AA10" -> [26, 9].
function fromCellReference(s) {
const [, sc, sr] = s.match(/^([A-Z]*)(\d*)$/);
let c = 0;
if (sc)
for (let i = 0; i < sc.length; i++)
c += Math.pow(26, sc.length - i - 1) * (sc.charCodeAt(i) - 64);
return [c ? c - 1 : undefined, sr ? +sr - 1 : undefined];
}
async function remote_fetch(file) {
const response = await fetch(await file.url());
if (!response.ok) throw new Error(`Unable to load file: ${file.name}`);
return response;
}
async function dsv(file, delimiter, {array = false, typed = false} = {}) {
const text = await file.text();
return (delimiter === "\t"
? (array ? tsvParseRows : tsvParse)
: (array ? csvParseRows : csvParse))(text, typed && autoType);
}
class AbstractFile {
constructor(name, mimeType) {
Object.defineProperty(this, "name", {value: name, enumerable: true});
if (mimeType !== undefined) Object.defineProperty(this, "mimeType", {value: mimeType + "", enumerable: true});
}
async blob() {
return (await remote_fetch(this)).blob();
}
async arrayBuffer() {
return (await remote_fetch(this)).arrayBuffer();
}
async text() {
return (await remote_fetch(this)).text();
}
async json() {
return (await remote_fetch(this)).json();
}
async stream() {
return (await remote_fetch(this)).body;
}
async csv(options) {
return dsv(this, ",", options);
}
async tsv(options) {
return dsv(this, "\t", options);
}
async image(props) {
const url = await this.url();
return new Promise((resolve, reject) => {
const i = new Image();
if (new URL(url, document.baseURI).origin !== new URL(location).origin) {
i.crossOrigin = "anonymous";
}
Object.assign(i, props);
i.onload = () => resolve(i);
i.onerror = () => reject(new Error(`Unable to load file: ${this.name}`));
i.src = url;
});
}
async arrow() {
const [Arrow, response] = await Promise.all([require(arrow.resolve()), remote_fetch(this)]);
return Arrow.Table.from(response);
}
async sqlite() {
return SQLiteDatabaseClient.open(remote_fetch(this));
}
async zip() {
const [JSZip, buffer] = await Promise.all([require(jszip.resolve()), this.arrayBuffer()]);
return new ZipArchive(await JSZip.loadAsync(buffer));
}
async xml(mimeType = "application/xml") {
return (new DOMParser).parseFromString(await this.text(), mimeType);
}
async html() {
return this.xml("text/html");
}
async xlsx() {
const [ExcelJS, buffer] = await Promise.all([require(exceljs.resolve()), this.arrayBuffer()]);
return new Workbook(await new ExcelJS.Workbook().xlsx.load(buffer));
}
}
class FileAttachment extends AbstractFile {
constructor(url, name, mimeType) {
super(name, mimeType);
Object.defineProperty(this, "_url", {value: url});
}
async url() {
return (await this._url) + "";
}
}
function NoFileAttachments(name) {
throw new Error(`File not found: ${name}`);
}
function FileAttachments(resolve) {
return Object.assign(
name => {
const result = resolve(name += "");
if (result == null) throw new Error(`File not found: ${name}`);
if (typeof result === "object" && "url" in result) {
const {url, mimeType} = result;
return new FileAttachment(url, name, mimeType);
}
return new FileAttachment(result, name);
},
{prototype: FileAttachment.prototype} // instanceof
);
}
class ZipArchive {
constructor(archive) {
Object.defineProperty(this, "_", {value: archive});
this.filenames = Object.keys(archive.files).filter(name => !archive.files[name].dir);
}
file(path) {
const object = this._.file(path += "");
if (!object || object.dir) throw new Error(`file not found: ${path}`);
return new ZipArchiveEntry(object);
}
}
class ZipArchiveEntry extends AbstractFile {
constructor(object) {
super(object.name);
Object.defineProperty(this, "_", {value: object});
Object.defineProperty(this, "_url", {writable: true});
}
async url() {
return this._url || (this._url = this.blob().then(URL.createObjectURL));
}
async blob() {
return this._.async("blob");
}
async arrayBuffer() {
return this._.async("arraybuffer");
}
async text() {
return this._.async("text");
}
async json() {
return JSON.parse(await this.text());
}
}
function canvas(width, height) {
var canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
return canvas;
}
function context2d(width, height, dpi) {
if (dpi == null) dpi = devicePixelRatio;
var canvas = document.createElement("canvas");
canvas.width = width * dpi;
canvas.height = height * dpi;
canvas.style.width = width + "px";
var context = canvas.getContext("2d");
context.scale(dpi, dpi);
return context;
}
function download(value, name = "untitled", label = "Save") {
const a = document.createElement("a");
const b = a.appendChild(document.createElement("button"));
b.textContent = label;
a.download = name;
async function reset() {
await new Promise(requestAnimationFrame);
URL.revokeObjectURL(a.href);
a.removeAttribute("href");
b.textContent = label;
b.disabled = false;
}
a.onclick = async event => {
b.disabled = true;
if (a.href) return reset(); // Already saved.
b.textContent = "Saving…";
try {
const object = await (typeof value === "function" ? value() : value);
b.textContent = "Download";
a.href = URL.createObjectURL(object); // eslint-disable-line require-atomic-updates
} catch (ignore) {
b.textContent = label;
}
if (event.eventPhase) return reset(); // Already downloaded.
b.disabled = false;
};
return a;
}
var namespaces = {
math: "http://www.w3.org/1998/Math/MathML",
svg: "http://www.w3.org/2000/svg",
xhtml: "http://www.w3.org/1999/xhtml",
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
};
function element(name, attributes) {
var prefix = name += "", i = prefix.indexOf(":"), value;
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
var element = namespaces.hasOwnProperty(prefix) // eslint-disable-line no-prototype-builtins
? document.createElementNS(namespaces[prefix], name)
: document.createElement(name);
if (attributes) for (var key in attributes) {
prefix = key, i = prefix.indexOf(":"), value = attributes[key];
if (i >= 0 && (prefix = key.slice(0, i)) !== "xmlns") key = key.slice(i + 1);
if (namespaces.hasOwnProperty(prefix)) element.setAttributeNS(namespaces[prefix], key, value); // eslint-disable-line no-prototype-builtins
else element.setAttribute(key, value);
}
return element;
}
function input$1(type) {
var input = document.createElement("input");
if (type != null) input.type = type;
return input;
}
function range$1(min, max, step) {
if (arguments.length === 1) max = min, min = null;
var input = document.createElement("input");
input.min = min = min == null ? 0 : +min;
input.max = max = max == null ? 1 : +max;
input.step = step == null ? "any" : step = +step;
input.type = "range";
return input;
}
function select(values) {
var select = document.createElement("select");
Array.prototype.forEach.call(values, function(value) {
var option = document.createElement("option");
option.value = option.textContent = value;
select.appendChild(option);
});
return select;
}
function svg$1(width, height) {
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("viewBox", [0, 0, width, height]);
svg.setAttribute("width", width);
svg.setAttribute("height", height);
return svg;
}
function text$1(value) {
return document.createTextNode(value);
}
var count$1 = 0;
function uid(name) {
return new Id("O-" + (name == null ? "" : name + "-") + ++count$1);
}
function Id(id) {
this.id = id;
this.href = new URL(`#${id}`, location) + "";
}
Id.prototype.toString = function() {
return "url(" + this.href + ")";
};
var DOM = {
canvas: canvas,
context2d: context2d,
download: download,
element: element,
input: input$1,
range: range$1,
select: select,
svg: svg$1,
text: text$1,
uid: uid
};
function buffer(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader;
reader.onload = function() { resolve(reader.result); };
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}
function text(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader;
reader.onload = function() { resolve(reader.result); };
reader.onerror = reject;
reader.readAsText(file);
});
}
function url(file) {
return new Promise(function(resolve, reject) {
var reader = new FileReader;
reader.onload = function() { resolve(reader.result); };
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
var Files = {
buffer: buffer,
text: text,
url: url
};
function that() {
return this;
}
function disposable(value, dispose) {
let done = false;
if (typeof dispose !== "function") {
throw new Error("dispose is not a function");
}
return {
[Symbol.iterator]: that,
next: () => done ? {done: true} : (done = true, {done: false, value}),
return: () => (done = true, dispose(value), {done: true}),
throw: () => ({done: done = true})
};
}
function* filter(iterator, test) {
var result, index = -1;
while (!(result = iterator.next()).done) {
if (test(result.value, ++index)) {
yield result.value;
}
}
}
function observe(initialize) {
let stale = false;
let value;
let resolve;
const dispose = initialize(change);
if (dispose != null && typeof dispose !== "function") {
throw new Error(typeof dispose.then === "function"
? "async initializers are not supported"
: "initializer returned something, but not a dispose function");
}
function change(x) {
if (resolve) resolve(x), resolve = null;
else stale = true;
return value = x;
}
function next() {
return {done: false, value: stale
? (stale = false, Promise.resolve(value))
: new Promise(_ => (resolve = _))};
}
return {
[Symbol.iterator]: that,
throw: () => ({done: true}),
return: () => (dispose != null && dispose(), {done: true}),
next
};
}
function input(input) {
return observe(function(change) {
var event = eventof(input), value = valueof$1(input);
function inputted() { change(valueof$1(input)); }
input.addEventListener(event, inputted);
if (value !== undefined) change(value);
return function() { input.removeEventListener(event, inputted); };
});
}
function valueof$1(input) {
switch (input.type) {
case "range":
case "number": return input.valueAsNumber;
case "date": return input.valueAsDate;
case "checkbox": return input.checked;
case "file": return input.multiple ? input.files : input.files[0];
case "select-multiple": return Array.from(input.selectedOptions, o => o.value);
default: return input.value;
}
}
function eventof(input) {
switch (input.type) {
case "button":
case "submit":
case "checkbox": return "click";
case "file": return "change";
default: return "input";
}
}
function* map$1(iterator, transform) {
var result, index = -1;
while (!(result = iterator.next()).done) {
yield transform(result.value, ++index);
}
}
function queue(initialize) {
let resolve;
const queue = [];
const dispose = initialize(push);
if (dispose != null && typeof dispose !== "function") {
throw new Error(typeof dispose.then === "function"
? "async initializers are not supported"
: "initializer returned something, but not a dispose function");
}
function push(x) {
queue.push(x);
if (resolve) resolve(queue.shift()), resolve = null;
return x;
}
function next() {
return {done: false, value: queue.length
? Promise.resolve(queue.shift())
: new Promise(_ => (resolve = _))};
}
return {
[Symbol.iterator]: that,
throw: () => ({done: true}),
return: () => (dispose != null && dispose(), {done: true}),
next
};
}
function* range(start, stop, step) {
start = +start;
stop = +stop;
step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
var i = -1, n = Math.max(0, Math.ceil((stop - start) / step)) | 0;
while (++i < n) {
yield start + i * step;
}
}
function valueAt(iterator, i) {
if (!isFinite(i = +i) || i < 0 || i !== i | 0) return;
var result, index = -1;
while (!(result = iterator.next()).done) {
if (++index === i) {
return result.value;
}
}
}
function worker(source) {
const url = URL.createObjectURL(new Blob([source], {type: "text/javascript"}));
const worker = new Worker(url);
return disposable(worker, () => {
worker.terminate();
URL.revokeObjectURL(url);
});
}
var Generators$1 = {
disposable: disposable,
filter: filter,
input: input,
map: map$1,
observe: observe,
queue: queue,
range: range,
valueAt: valueAt,
worker: worker
};
function template(render, wrapper) {
return function(strings) {
var string = strings[0],
parts = [], part,
root = null,
node, nodes,
walker,
i, n, j, m, k = -1;
// Concatenate the text using comments as placeholders.
for (i = 1, n = arguments.length; i < n; ++i) {
part = arguments[i];
if (part instanceof Node) {
parts[++k] = part;
string += "";
} else if (Array.isArray(part)) {
for (j = 0, m = part.length; j < m; ++j) {
node = part[j];
if (node instanceof Node) {
if (root === null) {
parts[++k] = root = document.createDocumentFragment();
string += "";
}
root.appendChild(node);
} else {
root = null;
string += node;
}
}
root = null;
} else {
string += part;
}
string += strings[i];
}
// Render the text.
root = render(string);
// Walk the rendered content to replace comment placeholders.
if (++k > 0) {
nodes = new Array(k);
walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT, null, false);
while (walker.nextNode()) {
node = walker.currentNode;
if (/^o:/.test(node.nodeValue)) {
nodes[+node.nodeValue.slice(2)] = node;
}
}
for (i = 0; i < k; ++i) {
if (node = nodes[i]) {
node.parentNode.replaceChild(parts[i], node);
}
}
}
// Is the rendered content
// … a parent of a single child? Detach and return the child.
// … a document fragment? Replace the fragment with an element.
// … some other node? Return it.
return root.childNodes.length === 1 ? root.removeChild(root.firstChild)
: root.nodeType === 11 ? ((node = wrapper()).appendChild(root), node)
: root;
};
}
var html$1 = template(function(string) {
var template = document.createElement("template");
template.innerHTML = string.trim();
return document.importNode(template.content, true);
}, function() {
return document.createElement("span");
});
function md(require) {
return require(marked.resolve()).then(function(marked) {
return template(
function(string) {
var root = document.createElement("div");
root.innerHTML = marked(string, {langPrefix: ""}).trim();
var code = root.querySelectorAll("pre code[class]");
if (code.length > 0) {
require(highlight.resolve()).then(function(hl) {
code.forEach(function(block) {
function done() {
hl.highlightBlock(block);
block.parentNode.classList.add("observablehq--md-pre");
}
if (hl.getLanguage(block.className)) {
done();
} else {
require(highlight.resolve("async-languages/index.js"))
.then(index => {
if (index.has(block.className)) {
return require(highlight.resolve("async-languages/" + index.get(block.className))).then(language => {
hl.registerLanguage(block.className, language);
});
}
})
.then(done, done);
}
});
});
}
return root;
},
function() {
return document.createElement("div");
}
);
});
}
async function mermaid(require) {
const mer = await require(mermaid$1.resolve());
mer.initialize({securityLevel: "loose", theme: "neutral"});
return function mermaid() {
const root = document.createElement("div");
root.innerHTML = mer.render(uid().id, String.raw.apply(String, arguments));
return root.removeChild(root.firstChild);
};
}
function Mutable(value) {
let change;
Object.defineProperties(this, {
generator: {value: observe(_ => void (change = _))},
value: {get: () => value, set: x => change(value = x)} // eslint-disable-line no-setter-return
});
if (value !== undefined) change(value);
}
function* now() {
while (true) {
yield Date.now();
}
}
function delay(duration, value) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve(value);
}, duration);
});
}
var timeouts = new Map;
function timeout(now, time) {
var t = new Promise(function(resolve) {
timeouts.delete(time);
var delay = time - now;
if (!(delay > 0)) throw new Error("invalid time");
if (delay > 0x7fffffff) throw new Error("too long to wait");
setTimeout(resolve, delay);
});
timeouts.set(time, t);
return t;
}
function when(time, value) {
var now;
return (now = timeouts.get(time = +time)) ? now.then(() => value)
: (now = Date.now()) >= time ? Promise.resolve(value)
: timeout(now, time).then(() => value);
}
function tick(duration, value) {
return when(Math.ceil((Date.now() + 1) / duration) * duration, value);
}
var Promises = {
delay: delay,
tick: tick,
when: when
};
function resolve(name, base) {
if (/^(\w+:)|\/\//i.test(name)) return name;
if (/^[.]{0,2}\//i.test(name)) return new URL(name, base == null ? location : base).href;
if (!name.length || /^[\s._]/.test(name) || /\s$/.test(name)) throw new Error("illegal name");
return "https://unpkg.com/" + name;
}
function requirer(resolve) {
return resolve == null ? require : requireFrom(resolve);
}
var svg = template(function(string) {
var root = document.createElementNS("http://www.w3.org/2000/svg", "g");
root.innerHTML = string.trim();
return root;
}, function() {
return document.createElementNS("http://www.w3.org/2000/svg", "g");
});
var raw = String.raw;
function style(href) {
return new Promise(function(resolve, reject) {
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = href;
link.onerror = reject;
link.onload = resolve;
document.head.appendChild(link);
});
}
function tex(require) {
return Promise.all([
require(katex.resolve()),
style(katex.resolve("dist/katex.min.css"))
]).then(function(values) {
var katex = values[0], tex = renderer();
function renderer(options) {
return function() {
var root = document.createElement("div");
katex.render(raw.apply(String, arguments), root, options);
return root.removeChild(root.firstChild);
};
}
tex.options = renderer;
tex.block = renderer({displayMode: true});
return tex;
});
}
async function vl(require) {
const [v, vl, api] = await Promise.all([vega, vegalite, vegaliteApi].map(d => require(d.resolve())));
return api.register(v, vl);
}
function width() {
return observe(function(change) {
var width = change(document.body.clientWidth);
function resized() {
var w = document.body.clientWidth;
if (w !== width) change(width = w);
}
window.addEventListener("resize", resized);
return function() {
window.removeEventListener("resize", resized);
};
});
}
var Library = Object.assign(function Library(resolver) {
const require = requirer(resolver);
Object.defineProperties(this, properties({
FileAttachment: () => NoFileAttachments,
Arrow: () => require(arrow.resolve()),
Inputs: () => require(inputs.resolve()).then(Inputs => ({...Inputs, file: Inputs.fileOf(AbstractFile)})),
Mutable: () => Mutable,
Plot: () => require(plot.resolve()),
SQLite: () => sqlite(require),
SQLiteDatabaseClient: () => SQLiteDatabaseClient,
_: () => require(lodash.resolve()),
aq: () => require.alias({"apache-arrow": arrow.resolve()})(arquero.resolve()),
d3: () => require(d3.resolve()),
dot: () => require(graphviz.resolve()),
htl: () => require(htl.resolve()),
html: () => html$1,
md: () => md(require),
mermaid: () => mermaid(require),
now,
require: () => require,
resolve: () => resolve,
svg: () => svg,
tex: () => tex(require),
topojson: () => require(topojson.resolve()),
vl: () => vl(require),
width,
// Note: these are namespace objects, and thus exposed directly rather than
// being wrapped in a function. This allows library.Generators to resolve,
// rather than needing module.value.
DOM,
Files,
Generators: Generators$1,
Promises
}));
}, {resolve: require.resolve});
function properties(values) {
return fromEntries(Object.entries(values).map(property));
// return Object.fromEntries(Object.entries(values).map(property));
}
function property([key, value]) {
return [key, ({value, writable: true, enumerable: true})];
}
// src/main.js
class PandocCodeDecorator {
constructor(node) {
this._node = node;
this._spans = [];
this.normalizeCodeRange();
this.initializeEntryPoints();
}
normalizeCodeRange() {
const n = this._node;
const lines = n.querySelectorAll("code > span");
for (const line of lines) {
Array.from(line.childNodes).filter((n2) => n2.nodeType === n2.TEXT_NODE).forEach((n2) => {
const newSpan = document.createElement("span");
newSpan.textContent = n2.wholeText;
n2.replaceWith(newSpan);
});
}
}
initializeEntryPoints() {
const lines = this._node.querySelectorAll("code > span");
let result = [];
let offset = this._node.parentElement.dataset.sourceOffset && -Number(this._node.parentElement.dataset.sourceOffset) || 0;
for (const line of lines) {
let lineNumber = Number(line.id.split("-").pop());
let column = 1;
Array.from(line.childNodes).filter((n) => n.nodeType === n.ELEMENT_NODE && n.nodeName === "SPAN").forEach((n) => {
result.push({
offset,
line: lineNumber,
column,
node: n
});
offset += n.textContent.length;
column += n.textContent.length;
});
offset += 1;
}
this._elementEntryPoints = result;
}
locateEntry(offset) {
let candidate;
if (offset === Infinity)
return void 0;
for (let i = 0; i < this._elementEntryPoints.length; ++i) {
const entry = this._elementEntryPoints[i];
if (entry.offset > offset) {
return { entry: candidate, index: i - 1 };
}
candidate = entry;
}
if (offset < candidate.offset + candidate.node.textContent.length) {
return { entry: candidate, index: this._elementEntryPoints.length - 1 };
} else {
return void 0;
}
}
offsetToLineColumn(offset) {
let entry = this.locateEntry(offset);
if (entry === void 0) {
const entries = this._elementEntryPoints;
const last = entries[entries.length - 1];
return {
line: last.line,
column: last.column + Math.min(last.node.textContent.length, offset - last.offset)
};
}
return {
line: entry.entry.line,
column: entry.entry.column + offset - entry.entry.offset
};
}
*spanSelection(start, end) {
this.ensureExactSpan(start, end);
const startEntry = this.locateEntry(start);
const endEntry = this.locateEntry(end);
if (startEntry === void 0) {
return;
}
const startIndex = startEntry.index;
const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length;
for (let i = startIndex; i < endIndex; ++i) {
yield this._elementEntryPoints[i];
}
}
decorateSpan(start, end, classes) {
for (const entryPoint of this.spanSelection(start, end)) {
for (const cssClass of classes) {
entryPoint.node.classList.add(cssClass);
}
}
}
clearSpan(start, end, classes) {
for (const entryPoint of this.spanSelection(start, end)) {
for (const cssClass of classes) {
entryPoint.node.classList.remove(cssClass);
}
}
}
ensureExactSpan(start, end) {
const splitEntry = (entry, offset) => {
const newSpan = document.createElement("span");
for (const cssClass of entry.node.classList) {
newSpan.classList.add(cssClass);
}
const beforeText = entry.node.textContent.slice(0, offset - entry.offset);
const afterText = entry.node.textContent.slice(offset - entry.offset);
entry.node.textContent = beforeText;
newSpan.textContent = afterText;
entry.node.after(newSpan);
this._elementEntryPoints.push({
column: entry.column + offset - entry.offset,
line: entry.line,
node: newSpan,
offset
});
this._elementEntryPoints.sort((a, b) => a.offset - b.offset);
};
const startEntry = this.locateEntry(start);
if (startEntry !== void 0 && startEntry.entry.offset != start) {
splitEntry(startEntry.entry, start);
}
const endEntry = this.locateEntry(end);
if (endEntry !== void 0 && endEntry.entry.offset !== end) {
splitEntry(endEntry.entry, end);
}
}
clearSpan(start, end, classes) {
this.ensureExactSpan(start, end);
const startEntry = this.locateEntry(start);
const endEntry = this.locateEntry(end);
if (startEntry === void 0) {
return;
}
const startIndex = startEntry.index;
const endIndex = endEntry && endEntry.index || this._elementEntryPoints.length;
for (let i = startIndex; i < endIndex; ++i) {
for (const cssClass of classes) {
this._elementEntryPoints[i].node.classList.remove(cssClass);
}
}
}
}
function dispatch(node, type, detail) {
detail = detail || {};
var document = node.ownerDocument, event = document.defaultView.CustomEvent;
if (typeof event === "function") {
event = new event(type, {detail: detail});
} else {
event = document.createEvent("Event");
event.initEvent(type, false, false);
event.detail = detail;
}
node.dispatchEvent(event);
}
// TODO https://twitter.com/mbostock/status/702737065121742848
function isarray(value) {
return Array.isArray(value)
|| value instanceof Int8Array
|| value instanceof Int16Array
|| value instanceof Int32Array
|| value instanceof Uint8Array
|| value instanceof Uint8ClampedArray
|| value instanceof Uint16Array
|| value instanceof Uint32Array
|| value instanceof Float32Array
|| value instanceof Float64Array;
}
// Non-integer keys in arrays, e.g. [1, 2, 0.5: "value"].
function isindex(key) {
return key === (key | 0) + "";
}
function inspectName(name) {
const n = document.createElement("span");
n.className = "observablehq--cellname";
n.textContent = `${name} = `;
return n;
}
const symbolToString = Symbol.prototype.toString;
// Symbols do not coerce to strings; they must be explicitly converted.
function formatSymbol(symbol) {
return symbolToString.call(symbol);
}
const {getOwnPropertySymbols, prototype: {hasOwnProperty: hasOwnProperty$1}} = Object;
const {toStringTag} = Symbol;
const FORBIDDEN = {};
const symbolsof = getOwnPropertySymbols;
function isown(object, key) {
return hasOwnProperty$1.call(object, key);
}
function tagof(object) {
return object[toStringTag]
|| (object.constructor && object.constructor.name)
|| "Object";
}
function valueof(object, key) {
try {
const value = object[key];
if (value) value.constructor; // Test for SecurityError.
return value;
} catch (ignore) {
return FORBIDDEN;
}
}
const SYMBOLS = [
{ symbol: "@@__IMMUTABLE_INDEXED__@@", name: "Indexed", modifier: true },
{ symbol: "@@__IMMUTABLE_KEYED__@@", name: "Keyed", modifier: true },
{ symbol: "@@__IMMUTABLE_LIST__@@", name: "List", arrayish: true },
{ symbol: "@@__IMMUTABLE_MAP__@@", name: "Map" },
{
symbol: "@@__IMMUTABLE_ORDERED__@@",
name: "Ordered",
modifier: true,
prefix: true
},
{ symbol: "@@__IMMUTABLE_RECORD__@@", name: "Record" },
{
symbol: "@@__IMMUTABLE_SET__@@",
name: "Set",
arrayish: true,
setish: true
},
{ symbol: "@@__IMMUTABLE_STACK__@@", name: "Stack", arrayish: true }
];
function immutableName(obj) {
try {
let symbols = SYMBOLS.filter(({ symbol }) => obj[symbol] === true);
if (!symbols.length) return;
const name = symbols.find(s => !s.modifier);
const prefix =
name.name === "Map" && symbols.find(s => s.modifier && s.prefix);
const arrayish = symbols.some(s => s.arrayish);
const setish = symbols.some(s => s.setish);
return {
name: `${prefix ? prefix.name : ""}${name.name}`,
symbols,
arrayish: arrayish && !setish,
setish
};
} catch (e) {
return null;
}
}
const {getPrototypeOf, getOwnPropertyDescriptors} = Object;
const objectPrototype = getPrototypeOf({});
function inspectExpanded(object, _, name, proto) {
let arrayish = isarray(object);
let tag, fields, next, n;
if (object instanceof Map) {
if (object instanceof object.constructor) {
tag = `Map(${object.size})`;
fields = iterateMap$1;
} else { // avoid incompatible receiver error for prototype
tag = "Map()";
fields = iterateObject$1;
}
} else if (object instanceof Set) {
if (object instanceof object.constructor) {
tag = `Set(${object.size})`;
fields = iterateSet$1;
} else { // avoid incompatible receiver error for prototype
tag = "Set()";
fields = iterateObject$1;
}
} else if (arrayish) {
tag = `${object.constructor.name}(${object.length})`;
fields = iterateArray$1;
} else if ((n = immutableName(object))) {
tag = `Immutable.${n.name}${n.name === "Record" ? "" : `(${object.size})`}`;
arrayish = n.arrayish;
fields = n.arrayish
? iterateImArray$1
: n.setish
? iterateImSet$1
: iterateImObject$1;
} else if (proto) {
tag = tagof(object);
fields = iterateProto;
} else {
tag = tagof(object);
fields = iterateObject$1;
}
const span = document.createElement("span");
span.className = "observablehq--expanded";
if (name) {
span.appendChild(inspectName(name));
}
const a = span.appendChild(document.createElement("a"));
a.innerHTML = ``;
a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`));
a.addEventListener("mouseup", function(event) {
event.stopPropagation();
replace(span, inspectCollapsed(object, null, name, proto));
});
fields = fields(object);
for (let i = 0; !(next = fields.next()).done && i < 20; ++i) {
span.appendChild(next.value);
}
if (!next.done) {
const a = span.appendChild(document.createElement("a"));
a.className = "observablehq--field";
a.style.display = "block";
a.appendChild(document.createTextNode(` … more`));
a.addEventListener("mouseup", function(event) {
event.stopPropagation();
span.insertBefore(next.value, span.lastChild.previousSibling);
for (let i = 0; !(next = fields.next()).done && i < 19; ++i) {
span.insertBefore(next.value, span.lastChild.previousSibling);
}
if (next.done) span.removeChild(span.lastChild.previousSibling);
dispatch(span, "load");
});
}
span.appendChild(document.createTextNode(arrayish ? "]" : "}"));
return span;
}
function* iterateMap$1(map) {
for (const [key, value] of map) {
yield formatMapField$1(key, value);
}
yield* iterateObject$1(map);
}
function* iterateSet$1(set) {
for (const value of set) {
yield formatSetField(value);
}
yield* iterateObject$1(set);
}
function* iterateImSet$1(set) {
for (const value of set) {
yield formatSetField(value);
}
}
function* iterateArray$1(array) {
for (let i = 0, n = array.length; i < n; ++i) {
if (i in array) {
yield formatField$1(i, valueof(array, i), "observablehq--index");
}
}
for (const key in array) {
if (!isindex(key) && isown(array, key)) {
yield formatField$1(key, valueof(array, key), "observablehq--key");
}
}
for (const symbol of symbolsof(array)) {
yield formatField$1(
formatSymbol(symbol),
valueof(array, symbol),
"observablehq--symbol"
);
}
}
function* iterateImArray$1(array) {
let i1 = 0;
for (const n = array.size; i1 < n; ++i1) {
yield formatField$1(i1, array.get(i1), true);
}
}
function* iterateProto(object) {
for (const key in getOwnPropertyDescriptors(object)) {
yield formatField$1(key, valueof(object, key), "observablehq--key");
}
for (const symbol of symbolsof(object)) {
yield formatField$1(
formatSymbol(symbol),
valueof(object, symbol),
"observablehq--symbol"
);
}
const proto = getPrototypeOf(object);
if (proto && proto !== objectPrototype) {
yield formatPrototype(proto);
}
}
function* iterateObject$1(object) {
for (const key in object) {
if (isown(object, key)) {
yield formatField$1(key, valueof(object, key), "observablehq--key");
}
}
for (const symbol of symbolsof(object)) {
yield formatField$1(
formatSymbol(symbol),
valueof(object, symbol),
"observablehq--symbol"
);
}
const proto = getPrototypeOf(object);
if (proto && proto !== objectPrototype) {
yield formatPrototype(proto);
}
}
function* iterateImObject$1(object) {
for (const [key, value] of object) {
yield formatField$1(key, value, "observablehq--key");
}
}
function formatPrototype(value) {
const item = document.createElement("div");
const span = item.appendChild(document.createElement("span"));
item.className = "observablehq--field";
span.className = "observablehq--prototype-key";
span.textContent = ` `;
item.appendChild(document.createTextNode(": "));
item.appendChild(inspect(value, undefined, undefined, undefined, true));
return item;
}
function formatField$1(key, value, className) {
const item = document.createElement("div");
const span = item.appendChild(document.createElement("span"));
item.className = "observablehq--field";
span.className = className;
span.textContent = ` ${key}`;
item.appendChild(document.createTextNode(": "));
item.appendChild(inspect(value));
return item;
}
function formatMapField$1(key, value) {
const item = document.createElement("div");
item.className = "observablehq--field";
item.appendChild(document.createTextNode(" "));
item.appendChild(inspect(key));
item.appendChild(document.createTextNode(" => "));
item.appendChild(inspect(value));
return item;
}
function formatSetField(value) {
const item = document.createElement("div");
item.className = "observablehq--field";
item.appendChild(document.createTextNode(" "));
item.appendChild(inspect(value));
return item;
}
function hasSelection(elem) {
const sel = window.getSelection();
return (
sel.type === "Range" &&
(sel.containsNode(elem, true) ||
sel.anchorNode.isSelfOrDescendant(elem) ||
sel.focusNode.isSelfOrDescendant(elem))
);
}
function inspectCollapsed(object, shallow, name, proto) {
let arrayish = isarray(object);
let tag, fields, next, n;
if (object instanceof Map) {
if (object instanceof object.constructor) {
tag = `Map(${object.size})`;
fields = iterateMap;
} else { // avoid incompatible receiver error for prototype
tag = "Map()";
fields = iterateObject;
}
} else if (object instanceof Set) {
if (object instanceof object.constructor) {
tag = `Set(${object.size})`;
fields = iterateSet;
} else { // avoid incompatible receiver error for prototype
tag = "Set()";
fields = iterateObject;
}
} else if (arrayish) {
tag = `${object.constructor.name}(${object.length})`;
fields = iterateArray;
} else if ((n = immutableName(object))) {
tag = `Immutable.${n.name}${n.name === 'Record' ? '' : `(${object.size})`}`;
arrayish = n.arrayish;
fields = n.arrayish ? iterateImArray : n.setish ? iterateImSet : iterateImObject;
} else {
tag = tagof(object);
fields = iterateObject;
}
if (shallow) {
const span = document.createElement("span");
span.className = "observablehq--shallow";
if (name) {
span.appendChild(inspectName(name));
}
span.appendChild(document.createTextNode(tag));
span.addEventListener("mouseup", function(event) {
if (hasSelection(span)) return;
event.stopPropagation();
replace(span, inspectCollapsed(object));
});
return span;
}
const span = document.createElement("span");
span.className = "observablehq--collapsed";
if (name) {
span.appendChild(inspectName(name));
}
const a = span.appendChild(document.createElement("a"));
a.innerHTML = ``;
a.appendChild(document.createTextNode(`${tag}${arrayish ? " [" : " {"}`));
span.addEventListener("mouseup", function(event) {
if (hasSelection(span)) return;
event.stopPropagation();
replace(span, inspectExpanded(object, null, name, proto));
}, true);
fields = fields(object);
for (let i = 0; !(next = fields.next()).done && i < 20; ++i) {
if (i > 0) span.appendChild(document.createTextNode(", "));
span.appendChild(next.value);
}
if (!next.done) span.appendChild(document.createTextNode(", …"));
span.appendChild(document.createTextNode(arrayish ? "]" : "}"));
return span;
}
function* iterateMap(map) {
for (const [key, value] of map) {
yield formatMapField(key, value);
}
yield* iterateObject(map);
}
function* iterateSet(set) {
for (const value of set) {
yield inspect(value, true);
}
yield* iterateObject(set);
}
function* iterateImSet(set) {
for (const value of set) {
yield inspect(value, true);
}
}
function* iterateImArray(array) {
let i0 = -1, i1 = 0;
for (const n = array.size; i1 < n; ++i1) {
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
yield inspect(array.get(i1), true);
i0 = i1;
}
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
}
function* iterateArray(array) {
let i0 = -1, i1 = 0;
for (const n = array.length; i1 < n; ++i1) {
if (i1 in array) {
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
yield inspect(valueof(array, i1), true);
i0 = i1;
}
}
if (i1 > i0 + 1) yield formatEmpty(i1 - i0 - 1);
for (const key in array) {
if (!isindex(key) && isown(array, key)) {
yield formatField(key, valueof(array, key), "observablehq--key");
}
}
for (const symbol of symbolsof(array)) {
yield formatField(formatSymbol(symbol), valueof(array, symbol), "observablehq--symbol");
}
}
function* iterateObject(object) {
for (const key in object) {
if (isown(object, key)) {
yield formatField(key, valueof(object, key), "observablehq--key");
}
}
for (const symbol of symbolsof(object)) {
yield formatField(formatSymbol(symbol), valueof(object, symbol), "observablehq--symbol");
}
}
function* iterateImObject(object) {
for (const [key, value] of object) {
yield formatField(key, value, "observablehq--key");
}
}
function formatEmpty(e) {
const span = document.createElement("span");
span.className = "observablehq--empty";
span.textContent = e === 1 ? "empty" : `empty × ${e}`;
return span;
}
function formatField(key, value, className) {
const fragment = document.createDocumentFragment();
const span = fragment.appendChild(document.createElement("span"));
span.className = className;
span.textContent = key;
fragment.appendChild(document.createTextNode(": "));
fragment.appendChild(inspect(value, true));
return fragment;
}
function formatMapField(key, value) {
const fragment = document.createDocumentFragment();
fragment.appendChild(inspect(key, true));
fragment.appendChild(document.createTextNode(" => "));
fragment.appendChild(inspect(value, true));
return fragment;
}
function format(date, fallback) {
if (!(date instanceof Date)) date = new Date(+date);
if (isNaN(date)) return typeof fallback === "function" ? fallback(date) : fallback;
const hours = date.getUTCHours();
const minutes = date.getUTCMinutes();
const seconds = date.getUTCSeconds();
const milliseconds = date.getUTCMilliseconds();
return `${formatYear(date.getUTCFullYear())}-${pad(date.getUTCMonth() + 1, 2)}-${pad(date.getUTCDate(), 2)}${
hours || minutes || seconds || milliseconds ? `T${pad(hours, 2)}:${pad(minutes, 2)}${
seconds || milliseconds ? `:${pad(seconds, 2)}${
milliseconds ? `.${pad(milliseconds, 3)}` : ``
}` : ``
}Z` : ``
}`;
}
function formatYear(year) {
return year < 0 ? `-${pad(-year, 6)}`
: year > 9999 ? `+${pad(year, 6)}`
: pad(year, 4);
}
function pad(value, width) {
return `${value}`.padStart(width, "0");
}
function formatDate$1(date) {
return format(date, "Invalid Date");
}
var errorToString = Error.prototype.toString;
function formatError(value) {
return value.stack || errorToString.call(value);
}
var regExpToString = RegExp.prototype.toString;
function formatRegExp(value) {
return regExpToString.call(value);
}
/* eslint-disable no-control-regex */
const NEWLINE_LIMIT = 20;
function formatString(string, shallow, expanded, name) {
if (shallow === false) {
// String has fewer escapes displayed with double quotes
if (count(string, /["\n]/g) <= count(string, /`|\${/g)) {
const span = document.createElement("span");
if (name) span.appendChild(inspectName(name));
const textValue = span.appendChild(document.createElement("span"));
textValue.className = "observablehq--string";
textValue.textContent = JSON.stringify(string);
return span;
}
const lines = string.split("\n");
if (lines.length > NEWLINE_LIMIT && !expanded) {
const div = document.createElement("div");
if (name) div.appendChild(inspectName(name));
const textValue = div.appendChild(document.createElement("span"));
textValue.className = "observablehq--string";
textValue.textContent = "`" + templatify(lines.slice(0, NEWLINE_LIMIT).join("\n"));
const splitter = div.appendChild(document.createElement("span"));
const truncatedCount = lines.length - NEWLINE_LIMIT;
splitter.textContent = `Show ${truncatedCount} truncated line${truncatedCount > 1 ? "s": ""}`; splitter.className = "observablehq--string-expand";
splitter.addEventListener("mouseup", function (event) {
event.stopPropagation();
replace(div, inspect(string, shallow, true, name));
});
return div;
}
const span = document.createElement("span");
if (name) span.appendChild(inspectName(name));
const textValue = span.appendChild(document.createElement("span"));
textValue.className = `observablehq--string${expanded ? " observablehq--expanded" : ""}`;
textValue.textContent = "`" + templatify(string) + "`";
return span;
}
const span = document.createElement("span");
if (name) span.appendChild(inspectName(name));
const textValue = span.appendChild(document.createElement("span"));
textValue.className = "observablehq--string";
textValue.textContent = JSON.stringify(string.length > 100 ?
`${string.slice(0, 50)}…${string.slice(-49)}` : string);
return span;
}
function templatify(string) {
return string.replace(/[\\`\x00-\x09\x0b-\x19]|\${/g, templatifyChar);
}
function templatifyChar(char) {
var code = char.charCodeAt(0);
switch (code) {
case 0x8: return "\\b";
case 0x9: return "\\t";
case 0xb: return "\\v";
case 0xc: return "\\f";
case 0xd: return "\\r";
}
return code < 0x10 ? "\\x0" + code.toString(16)
: code < 0x20 ? "\\x" + code.toString(16)
: "\\" + char;
}
function count(string, re) {
var n = 0;
while (re.exec(string)) ++n;
return n;
}
var toString$2 = Function.prototype.toString,
TYPE_ASYNC = {prefix: "async ƒ"},
TYPE_ASYNC_GENERATOR = {prefix: "async ƒ*"},
TYPE_CLASS = {prefix: "class"},
TYPE_FUNCTION = {prefix: "ƒ"},
TYPE_GENERATOR = {prefix: "ƒ*"};
function inspectFunction(f, name) {
var type, m, t = toString$2.call(f);
switch (f.constructor && f.constructor.name) {
case "AsyncFunction": type = TYPE_ASYNC; break;
case "AsyncGeneratorFunction": type = TYPE_ASYNC_GENERATOR; break;
case "GeneratorFunction": type = TYPE_GENERATOR; break;
default: type = /^class\b/.test(t) ? TYPE_CLASS : TYPE_FUNCTION; break;
}
// A class, possibly named.
// class Name
if (type === TYPE_CLASS) {
return formatFunction(type, "", name);
}
// An arrow function with a single argument.
// foo =>
// async foo =>
if ((m = /^(?:async\s*)?(\w+)\s*=>/.exec(t))) {
return formatFunction(type, "(" + m[1] + ")", name);
}
// An arrow function with parenthesized arguments.
// (…)
// async (…)
if ((m = /^(?:async\s*)?\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) {
return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name);
}
// A function, possibly: async, generator, anonymous, simply arguments.
// function name(…)
// function* name(…)
// async function name(…)
// async function* name(…)
if ((m = /^(?:async\s*)?function(?:\s*\*)?(?:\s*\w+)?\s*\(\s*(\w+(?:\s*,\s*\w+)*)?\s*\)/.exec(t))) {
return formatFunction(type, m[1] ? "(" + m[1].replace(/\s*,\s*/g, ", ") + ")" : "()", name);
}
// Something else, like destructuring, comments or default values.
return formatFunction(type, "(…)", name);
}
function formatFunction(type, args, cellname) {
var span = document.createElement("span");
span.className = "observablehq--function";
if (cellname) {
span.appendChild(inspectName(cellname));
}
var spanType = span.appendChild(document.createElement("span"));
spanType.className = "observablehq--keyword";
spanType.textContent = type.prefix;
span.appendChild(document.createTextNode(args));
return span;
}
const {prototype: {toString: toString$1}} = Object;
function inspect(value, shallow, expand, name, proto) {
let type = typeof value;
switch (type) {
case "boolean":
case "undefined": { value += ""; break; }
case "number": { value = value === 0 && 1 / value < 0 ? "-0" : value + ""; break; }
case "bigint": { value = value + "n"; break; }
case "symbol": { value = formatSymbol(value); break; }
case "function": { return inspectFunction(value, name); }
case "string": { return formatString(value, shallow, expand, name); }
default: {
if (value === null) { type = null, value = "null"; break; }
if (value instanceof Date) { type = "date", value = formatDate$1(value); break; }
if (value === FORBIDDEN) { type = "forbidden", value = "[forbidden]"; break; }
switch (toString$1.call(value)) {
case "[object RegExp]": { type = "regexp", value = formatRegExp(value); break; }
case "[object Error]": // https://github.com/lodash/lodash/blob/master/isError.js#L26
case "[object DOMException]": { type = "error", value = formatError(value); break; }
default: return (expand ? inspectExpanded : inspectCollapsed)(value, shallow, name, proto);
}
break;
}
}
const span = document.createElement("span");
if (name) span.appendChild(inspectName(name));
const n = span.appendChild(document.createElement("span"));
n.className = `observablehq--${type}`;
n.textContent = value;
return span;
}
function replace(spanOld, spanNew) {
if (spanOld.classList.contains("observablehq--inspect")) spanNew.classList.add("observablehq--inspect");
spanOld.parentNode.replaceChild(spanNew, spanOld);
dispatch(spanNew, "load");
}
const LOCATION_MATCH = /\s+\(\d+:\d+\)$/m;
class Inspector {
constructor(node) {
if (!node) throw new Error("invalid node");
this._node = node;
node.classList.add("observablehq");
}
pending() {
const {_node} = this;
_node.classList.remove("observablehq--error");
_node.classList.add("observablehq--running");
}
fulfilled(value, name) {
const {_node} = this;
if (!isnode(value) || (value.parentNode && value.parentNode !== _node)) {
value = inspect(value, false, _node.firstChild // TODO Do this better.
&& _node.firstChild.classList
&& _node.firstChild.classList.contains("observablehq--expanded"), name);
value.classList.add("observablehq--inspect");
}
_node.classList.remove("observablehq--running", "observablehq--error");
if (_node.firstChild !== value) {
if (_node.firstChild) {
while (_node.lastChild !== _node.firstChild) _node.removeChild(_node.lastChild);
_node.replaceChild(value, _node.firstChild);
} else {
_node.appendChild(value);
}
}
dispatch(_node, "update");
}
rejected(error, name) {
const {_node} = this;
_node.classList.remove("observablehq--running");
_node.classList.add("observablehq--error");
while (_node.lastChild) _node.removeChild(_node.lastChild);
var div = document.createElement("div");
div.className = "observablehq--inspect";
if (name) div.appendChild(inspectName(name));
div.appendChild(document.createTextNode((error + "").replace(LOCATION_MATCH, "")));
_node.appendChild(div);
dispatch(_node, "error", {error: error});
}
}
Inspector.into = function(container) {
if (typeof container === "string") {
container = document.querySelector(container);
if (container == null) throw new Error("container not found");
}
return function() {
return new Inspector(container.appendChild(document.createElement("div")));
};
};
// Returns true if the given value is something that should be added to the DOM
// by the inspector, rather than being inspected. This deliberately excludes
// DocumentFragment since appending a fragment “dissolves” (mutates) the
// fragment, and we wish for the inspector to not have side-effects. Also,
// HTMLElement.prototype is an instanceof Element, but not an element!
function isnode(value) {
return (value instanceof Element || value instanceof Text)
&& (value instanceof value.constructor);
}
function RuntimeError(message, input) {
this.message = message + "";
this.input = input;
}
RuntimeError.prototype = Object.create(Error.prototype);
RuntimeError.prototype.name = "RuntimeError";
RuntimeError.prototype.constructor = RuntimeError;
function generatorish(value) {
return value
&& typeof value.next === "function"
&& typeof value.return === "function";
}
function load(notebook, library, observer) {
if (typeof library == "function") observer = library, library = null;
if (typeof observer !== "function") throw new Error("invalid observer");
if (library == null) library = new Library();
const {modules, id} = notebook;
const map = new Map;
const runtime = new Runtime(library);
const main = runtime_module(id);
function runtime_module(id) {
let module = map.get(id);
if (!module) map.set(id, module = runtime.module());
return module;
}
for (const m of modules) {
const module = runtime_module(m.id);
let i = 0;
for (const v of m.variables) {
if (v.from) module.import(v.remote, v.name, runtime_module(v.from));
else if (module === main) module.variable(observer(v, i, m.variables)).define(v.name, v.inputs, v.value);
else module.define(v.name, v.inputs, v.value);
++i;
}
}
return runtime;
}
var prototype = Array.prototype;
var map = prototype.map;
var forEach = prototype.forEach;
function constant(x) {
return function() {
return x;
};
}
function identity$1(x) {
return x;
}
function rethrow(e) {
return function() {
throw e;
};
}
function noop() {}
var TYPE_NORMAL = 1; // a normal variable
var TYPE_IMPLICIT = 2; // created on reference
var TYPE_DUPLICATE = 3; // created on duplicate definition
var no_observer = {};
function Variable(type, module, observer) {
if (!observer) observer = no_observer;
Object.defineProperties(this, {
_observer: {value: observer, writable: true},
_definition: {value: variable_undefined, writable: true},
_duplicate: {value: undefined, writable: true},
_duplicates: {value: undefined, writable: true},
_indegree: {value: NaN, writable: true}, // The number of computing inputs.
_inputs: {value: [], writable: true},
_invalidate: {value: noop, writable: true},
_module: {value: module},
_name: {value: null, writable: true},
_outputs: {value: new Set, writable: true},
_promise: {value: Promise.resolve(undefined), writable: true},
_reachable: {value: observer !== no_observer, writable: true}, // Is this variable transitively visible?
_rejector: {value: variable_rejector(this)},
_type: {value: type},
_value: {value: undefined, writable: true},
_version: {value: 0, writable: true}
});
}
Object.defineProperties(Variable.prototype, {
_pending: {value: variable_pending, writable: true, configurable: true},
_fulfilled: {value: variable_fulfilled, writable: true, configurable: true},
_rejected: {value: variable_rejected, writable: true, configurable: true},
define: {value: variable_define, writable: true, configurable: true},
delete: {value: variable_delete, writable: true, configurable: true},
import: {value: variable_import, writable: true, configurable: true}
});
function variable_attach(variable) {
variable._module._runtime._dirty.add(variable);
variable._outputs.add(this);
}
function variable_detach(variable) {
variable._module._runtime._dirty.add(variable);
variable._outputs.delete(this);
}
function variable_undefined() {
throw variable_undefined;
}
function variable_rejector(variable) {
return function(error) {
if (error === variable_undefined) throw new RuntimeError(variable._name + " is not defined", variable._name);
if (error instanceof Error && error.message) throw new RuntimeError(error.message, variable._name);
throw new RuntimeError(variable._name + " could not be resolved", variable._name);
};
}
function variable_duplicate(name) {
return function() {
throw new RuntimeError(name + " is defined more than once");
};
}
function variable_define(name, inputs, definition) {
switch (arguments.length) {
case 1: {
definition = name, name = inputs = null;
break;
}
case 2: {
definition = inputs;
if (typeof name === "string") inputs = null;
else inputs = name, name = null;
break;
}
}
return variable_defineImpl.call(this,
name == null ? null : name + "",
inputs == null ? [] : map.call(inputs, this._module._resolve, this._module),
typeof definition === "function" ? definition : constant(definition)
);
}
function variable_defineImpl(name, inputs, definition) {
var scope = this._module._scope, runtime = this._module._runtime;
this._inputs.forEach(variable_detach, this);
inputs.forEach(variable_attach, this);
this._inputs = inputs;
this._definition = definition;
this._value = undefined;
// Is this an active variable (that may require disposal)?
if (definition === noop) runtime._variables.delete(this);
else runtime._variables.add(this);
// Did the variable’s name change? Time to patch references!
if (name !== this._name || scope.get(name) !== this) {
var error, found;
if (this._name) { // Did this variable previously have a name?
if (this._outputs.size) { // And did other variables reference this variable?
scope.delete(this._name);
found = this._module._resolve(this._name);
found._outputs = this._outputs, this._outputs = new Set;
found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(this)] = found; }, this);
found._outputs.forEach(runtime._updates.add, runtime._updates);
runtime._dirty.add(found).add(this);
scope.set(this._name, found);
} else if ((found = scope.get(this._name)) === this) { // Do no other variables reference this variable?
scope.delete(this._name); // It’s safe to delete!
} else if (found._type === TYPE_DUPLICATE) { // Do other variables assign this name?
found._duplicates.delete(this); // This variable no longer assigns this name.
this._duplicate = undefined;
if (found._duplicates.size === 1) { // Is there now only one variable assigning this name?
found = found._duplicates.keys().next().value; // Any references are now fixed!
error = scope.get(this._name);
found._outputs = error._outputs, error._outputs = new Set;
found._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(error)] = found; });
found._definition = found._duplicate, found._duplicate = undefined;
runtime._dirty.add(error).add(found);
runtime._updates.add(found);
scope.set(this._name, found);
}
} else {
throw new Error;
}
}
if (this._outputs.size) throw new Error;
if (name) { // Does this variable have a new name?
if (found = scope.get(name)) { // Do other variables reference or assign this name?
if (found._type === TYPE_DUPLICATE) { // Do multiple other variables already define this name?
this._definition = variable_duplicate(name), this._duplicate = definition;
found._duplicates.add(this);
} else if (found._type === TYPE_IMPLICIT) { // Are the variable references broken?
this._outputs = found._outputs, found._outputs = new Set; // Now they’re fixed!
this._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = this; }, this);
runtime._dirty.add(found).add(this);
scope.set(name, this);
} else { // Does another variable define this name?
found._duplicate = found._definition, this._duplicate = definition; // Now they’re duplicates.
error = new Variable(TYPE_DUPLICATE, this._module);
error._name = name;
error._definition = this._definition = found._definition = variable_duplicate(name);
error._outputs = found._outputs, found._outputs = new Set;
error._outputs.forEach(function(output) { output._inputs[output._inputs.indexOf(found)] = error; });
error._duplicates = new Set([this, found]);
runtime._dirty.add(found).add(error);
runtime._updates.add(found).add(error);
scope.set(name, error);
}
} else {
scope.set(name, this);
}
}
this._name = name;
}
runtime._updates.add(this);
runtime._compute();
return this;
}
function variable_import(remote, name, module) {
if (arguments.length < 3) module = name, name = remote;
return variable_defineImpl.call(this, name + "", [module._resolve(remote + "")], identity$1);
}
function variable_delete() {
return variable_defineImpl.call(this, null, [], noop);
}
function variable_pending() {
if (this._observer.pending) this._observer.pending();
}
function variable_fulfilled(value) {
if (this._observer.fulfilled) this._observer.fulfilled(value, this._name);
}
function variable_rejected(error) {
if (this._observer.rejected) this._observer.rejected(error, this._name);
}
function Module(runtime, builtins = []) {
Object.defineProperties(this, {
_runtime: {value: runtime},
_scope: {value: new Map},
_builtins: {value: new Map([
["invalidation", variable_invalidation],
["visibility", variable_visibility],
...builtins
])},
_source: {value: null, writable: true}
});
}
Object.defineProperties(Module.prototype, {
_copy: {value: module_copy, writable: true, configurable: true},
_resolve: {value: module_resolve, writable: true, configurable: true},
redefine: {value: module_redefine, writable: true, configurable: true},
define: {value: module_define, writable: true, configurable: true},
derive: {value: module_derive, writable: true, configurable: true},
import: {value: module_import, writable: true, configurable: true},
value: {value: module_value, writable: true, configurable: true},
variable: {value: module_variable, writable: true, configurable: true},
builtin: {value: module_builtin, writable: true, configurable: true}
});
function module_redefine(name) {
var v = this._scope.get(name);
if (!v) throw new RuntimeError(name + " is not defined");
if (v._type === TYPE_DUPLICATE) throw new RuntimeError(name + " is defined more than once");
return v.define.apply(v, arguments);
}
function module_define() {
var v = new Variable(TYPE_NORMAL, this);
return v.define.apply(v, arguments);
}
function module_import() {
var v = new Variable(TYPE_NORMAL, this);
return v.import.apply(v, arguments);
}
function module_variable(observer) {
return new Variable(TYPE_NORMAL, this, observer);
}
async function module_value(name) {
var v = this._scope.get(name);
if (!v) throw new RuntimeError(name + " is not defined");
if (v._observer === no_observer) {
v._observer = true;
this._runtime._dirty.add(v);
}
await this._runtime._compute();
return v._promise;
}
function module_derive(injects, injectModule) {
var copy = new Module(this._runtime, this._builtins);
copy._source = this;
forEach.call(injects, function(inject) {
if (typeof inject !== "object") inject = {name: inject + ""};
if (inject.alias == null) inject.alias = inject.name;
copy.import(inject.name, inject.alias, injectModule);
});
Promise.resolve().then(() => {
const modules = new Set([this]);
for (const module of modules) {
for (const variable of module._scope.values()) {
if (variable._definition === identity$1) { // import
const module = variable._inputs[0]._module;
const source = module._source || module;
if (source === this) { // circular import-with!
console.warn("circular module definition; ignoring"); // eslint-disable-line no-console
return;
}
modules.add(source);
}
}
}
this._copy(copy, new Map);
});
return copy;
}
function module_copy(copy, map) {
copy._source = this;
map.set(this, copy);
for (const [name, source] of this._scope) {
var target = copy._scope.get(name);
if (target && target._type === TYPE_NORMAL) continue; // injection
if (source._definition === identity$1) { // import
var sourceInput = source._inputs[0],
sourceModule = sourceInput._module;
copy.import(sourceInput._name, name, map.get(sourceModule)
|| (sourceModule._source
? sourceModule._copy(new Module(copy._runtime, copy._builtins), map) // import-with
: sourceModule));
} else {
copy.define(name, source._inputs.map(variable_name), source._definition);
}
}
return copy;
}
function module_resolve(name) {
var variable = this._scope.get(name), value;
if (!variable) {
variable = new Variable(TYPE_IMPLICIT, this);
if (this._builtins.has(name)) {
variable.define(name, constant(this._builtins.get(name)));
} else if (this._runtime._builtin._scope.has(name)) {
variable.import(name, this._runtime._builtin);
} else {
try {
value = this._runtime._global(name);
} catch (error) {
return variable.define(name, rethrow(error));
}
if (value === undefined) {
this._scope.set(variable._name = name, variable);
} else {
variable.define(name, constant(value));
}
}
}
return variable;
}
function module_builtin(name, value) {
this._builtins.set(name, value);
}
function variable_name(variable) {
return variable._name;
}
const frame = typeof requestAnimationFrame === "function" ? requestAnimationFrame
: typeof setImmediate === "function" ? setImmediate
: f => setTimeout(f, 0);
var variable_invalidation = {};
var variable_visibility = {};
function Runtime(builtins = new Library, global = window_global) {
var builtin = this.module();
Object.defineProperties(this, {
_dirty: {value: new Set},
_updates: {value: new Set},
_precomputes: {value: [], writable: true},
_computing: {value: null, writable: true},
_init: {value: null, writable: true},
_modules: {value: new Map},
_variables: {value: new Set},
_disposed: {value: false, writable: true},
_builtin: {value: builtin},
_global: {value: global}
});
if (builtins) for (var name in builtins) {
(new Variable(TYPE_IMPLICIT, builtin)).define(name, [], builtins[name]);
}
}
Object.defineProperties(Runtime, {
load: {value: load, writable: true, configurable: true}
});
Object.defineProperties(Runtime.prototype, {
_precompute: {value: runtime_precompute, writable: true, configurable: true},
_compute: {value: runtime_compute, writable: true, configurable: true},
_computeSoon: {value: runtime_computeSoon, writable: true, configurable: true},
_computeNow: {value: runtime_computeNow, writable: true, configurable: true},
dispose: {value: runtime_dispose, writable: true, configurable: true},
module: {value: runtime_module, writable: true, configurable: true},
fileAttachments: {value: FileAttachments, writable: true, configurable: true}
});
function runtime_dispose() {
this._computing = Promise.resolve();
this._disposed = true;
this._variables.forEach(v => {
v._invalidate();
v._version = NaN;
});
}
function runtime_module(define, observer = noop) {
let module;
if (define === undefined) {
if (module = this._init) {
this._init = null;
return module;
}
return new Module(this);
}
module = this._modules.get(define);
if (module) return module;
this._init = module = new Module(this);
this._modules.set(define, module);
try {
define(this, observer);
} finally {
this._init = null;
}
return module;
}
function runtime_precompute(callback) {
this._precomputes.push(callback);
this._compute();
}
function runtime_compute() {
return this._computing || (this._computing = this._computeSoon());
}
function runtime_computeSoon() {
return new Promise(frame).then(() => this._disposed ? undefined : this._computeNow());
}
async function runtime_computeNow() {
var queue = [],
variables,
variable,
precomputes = this._precomputes;
// If there are any paused generators, resume them before computing so they
// can update (if synchronous) before computing downstream variables.
if (precomputes.length) {
this._precomputes = [];
for (const callback of precomputes) callback();
await runtime_defer(3);
}
// Compute the reachability of the transitive closure of dirty variables.
// Any newly-reachable variable must also be recomputed.
// Any no-longer-reachable variable must be terminated.
variables = new Set(this._dirty);
variables.forEach(function(variable) {
variable._inputs.forEach(variables.add, variables);
const reachable = variable_reachable(variable);
if (reachable > variable._reachable) {
this._updates.add(variable);
} else if (reachable < variable._reachable) {
variable._invalidate();
}
variable._reachable = reachable;
}, this);
// Compute the transitive closure of updating, reachable variables.
variables = new Set(this._updates);
variables.forEach(function(variable) {
if (variable._reachable) {
variable._indegree = 0;
variable._outputs.forEach(variables.add, variables);
} else {
variable._indegree = NaN;
variables.delete(variable);
}
});
this._computing = null;
this._updates.clear();
this._dirty.clear();
// Compute the indegree of updating variables.
variables.forEach(function(variable) {
variable._outputs.forEach(variable_increment);
});
do {
// Identify the root variables (those with no updating inputs).
variables.forEach(function(variable) {
if (variable._indegree === 0) {
queue.push(variable);
}
});
// Compute the variables in topological order.
while (variable = queue.pop()) {
variable_compute(variable);
variable._outputs.forEach(postqueue);
variables.delete(variable);
}
// Any remaining variables are circular, or depend on them.
variables.forEach(function(variable) {
if (variable_circular(variable)) {
variable_error(variable, new RuntimeError("circular definition"));
variable._outputs.forEach(variable_decrement);
variables.delete(variable);
}
});
} while (variables.size);
function postqueue(variable) {
if (--variable._indegree === 0) {
queue.push(variable);
}
}
}
// We want to give generators, if they’re defined synchronously, a chance to
// update before computing downstream variables. This creates a synchronous
// promise chain of the given depth that we’ll await before recomputing
// downstream variables.
function runtime_defer(depth = 0) {
let p = Promise.resolve();
for (let i = 0; i < depth; ++i) p = p.then(() => {});
return p;
}
function variable_circular(variable) {
const inputs = new Set(variable._inputs);
for (const i of inputs) {
if (i === variable) return true;
i._inputs.forEach(inputs.add, inputs);
}
return false;
}
function variable_increment(variable) {
++variable._indegree;
}
function variable_decrement(variable) {
--variable._indegree;
}
function variable_value(variable) {
return variable._promise.catch(variable._rejector);
}
function variable_invalidator(variable) {
return new Promise(function(resolve) {
variable._invalidate = resolve;
});
}
function variable_intersector(invalidation, variable) {
let node = typeof IntersectionObserver === "function" && variable._observer && variable._observer._node;
let visible = !node, resolve = noop, reject = noop, promise, observer;
if (node) {
observer = new IntersectionObserver(([entry]) => (visible = entry.isIntersecting) && (promise = null, resolve()));
observer.observe(node);
invalidation.then(() => (observer.disconnect(), observer = null, reject()));
}
return function(value) {
if (visible) return Promise.resolve(value);
if (!observer) return Promise.reject();
if (!promise) promise = new Promise((y, n) => (resolve = y, reject = n));
return promise.then(() => value);
};
}
function variable_compute(variable) {
variable._invalidate();
variable._invalidate = noop;
variable._pending();
const value0 = variable._value;
const version = ++variable._version;
// Lazily-constructed invalidation variable; only constructed if referenced as an input.
let invalidation = null;
// If the variable doesn’t have any inputs, we can optimize slightly.
const promise = variable._promise = (variable._inputs.length
? Promise.all(variable._inputs.map(variable_value)).then(define)
: new Promise(resolve => resolve(variable._definition.call(value0))))
.then(generate);
// Compute the initial value of the variable.
function define(inputs) {
if (variable._version !== version) return;
// Replace any reference to invalidation with the promise, lazily.
for (var i = 0, n = inputs.length; i < n; ++i) {
switch (inputs[i]) {
case variable_invalidation: {
inputs[i] = invalidation = variable_invalidator(variable);
break;
}
case variable_visibility: {
if (!invalidation) invalidation = variable_invalidator(variable);
inputs[i] = variable_intersector(invalidation, variable);
break;
}
}
}
return variable._definition.apply(value0, inputs);
}
// If the value is a generator, then retrieve its first value, and dispose of
// the generator if the variable is invalidated. Note that the cell may
// already have been invalidated here, in which case we need to terminate the
// generator immediately!
function generate(value) {
if (generatorish(value)) {
if (variable._version !== version) return void value.return();
(invalidation || variable_invalidator(variable)).then(variable_return(value));
return variable_generate(variable, version, value);
}
return value;
}
promise.then((value) => {
if (variable._version !== version) return;
variable._value = value;
variable._fulfilled(value);
}, (error) => {
if (variable._version !== version) return;
variable._value = undefined;
variable._rejected(error);
});
}
function variable_generate(variable, version, generator) {
const runtime = variable._module._runtime;
let currentValue; // so that yield resolves to the yielded value
// Retrieve the next value from the generator; if successful, invoke the
// specified callback. The returned promise resolves to the yielded value, or
// to undefined if the generator is done.
function compute(onfulfilled) {
return new Promise(resolve => resolve(generator.next(currentValue))).then(({done, value}) => {
return done ? undefined : Promise.resolve(value).then(onfulfilled);
});
}
// Retrieve the next value from the generator; if successful, fulfill the
// variable, compute downstream variables, and schedule the next value to be
// pulled from the generator at the start of the next animation frame. If not
// successful, reject the variable, compute downstream variables, and return.
function recompute() {
const promise = compute((value) => {
if (variable._version !== version) return;
currentValue = value;
postcompute(value, promise).then(() => runtime._precompute(recompute));
variable._fulfilled(value);
return value;
});
promise.catch((error) => {
if (variable._version !== version) return;
postcompute(undefined, promise);
variable._rejected(error);
});
}
// After the generator fulfills or rejects, set its current value, promise,
// and schedule any downstream variables for update.
function postcompute(value, promise) {
variable._value = value;
variable._promise = promise;
variable._outputs.forEach(runtime._updates.add, runtime._updates);
return runtime._compute();
}
// When retrieving the first value from the generator, the promise graph is
// already established, so we only need to queue the next pull.
return compute((value) => {
if (variable._version !== version) return;
currentValue = value;
runtime._precompute(recompute);
return value;
});
}
function variable_error(variable, error) {
variable._invalidate();
variable._invalidate = noop;
variable._pending();
++variable._version;
variable._indegree = NaN;
(variable._promise = Promise.reject(error)).catch(noop);
variable._value = undefined;
variable._rejected(error);
}
function variable_return(generator) {
return function() {
generator.return();
};
}
function variable_reachable(variable) {
if (variable._observer !== no_observer) return true; // Directly reachable.
var outputs = new Set(variable._outputs);
for (const output of outputs) {
if (output._observer !== no_observer) return true;
output._outputs.forEach(outputs.add, outputs);
}
return false;
}
function window_global(name) {
return window[name];
}
function renderHtml(string) {
const template = document.createElement("template");
template.innerHTML = string;
return document.importNode(template.content, true);
}
function renderSvg(string) {
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.innerHTML = string;
return g;
}
const html = Object.assign(hypertext(renderHtml, fragment => {
if (fragment.firstChild === null) return null;
if (fragment.firstChild === fragment.lastChild) return fragment.removeChild(fragment.firstChild);
const span = document.createElement("span");
span.appendChild(fragment);
return span;
}), {fragment: hypertext(renderHtml, fragment => fragment)});
Object.assign(hypertext(renderSvg, g => {
if (g.firstChild === null) return null;
if (g.firstChild === g.lastChild) return g.removeChild(g.firstChild);
return g;
}), {fragment: hypertext(renderSvg, g => {
const fragment = document.createDocumentFragment();
while (g.firstChild) fragment.appendChild(g.firstChild);
return fragment;
})});
const
CODE_TAB = 9,
CODE_LF = 10,
CODE_FF = 12,
CODE_CR = 13,
CODE_SPACE = 32,
CODE_UPPER_A = 65,
CODE_UPPER_Z = 90,
CODE_LOWER_A = 97,
CODE_LOWER_Z = 122,
CODE_LT = 60,
CODE_GT = 62,
CODE_SLASH = 47,
CODE_DASH = 45,
CODE_BANG = 33,
CODE_EQ = 61,
CODE_DQUOTE = 34,
CODE_SQUOTE = 39,
CODE_QUESTION = 63,
STATE_DATA = 1,
STATE_TAG_OPEN = 2,
STATE_END_TAG_OPEN = 3,
STATE_TAG_NAME = 4,
STATE_BOGUS_COMMENT = 5,
STATE_BEFORE_ATTRIBUTE_NAME = 6,
STATE_AFTER_ATTRIBUTE_NAME = 7,
STATE_ATTRIBUTE_NAME = 8,
STATE_BEFORE_ATTRIBUTE_VALUE = 9,
STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED = 10,
STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED = 11,
STATE_ATTRIBUTE_VALUE_UNQUOTED = 12,
STATE_AFTER_ATTRIBUTE_VALUE_QUOTED = 13,
STATE_SELF_CLOSING_START_TAG = 14,
STATE_COMMENT_START = 15,
STATE_COMMENT_START_DASH = 16,
STATE_COMMENT = 17,
STATE_COMMENT_LESS_THAN_SIGN = 18,
STATE_COMMENT_LESS_THAN_SIGN_BANG = 19,
STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH = 20,
STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH = 21,
STATE_COMMENT_END_DASH = 22,
STATE_COMMENT_END = 23,
STATE_COMMENT_END_BANG = 24,
STATE_MARKUP_DECLARATION_OPEN = 25,
STATE_RAWTEXT = 26,
STATE_RAWTEXT_LESS_THAN_SIGN = 27,
STATE_RAWTEXT_END_TAG_OPEN = 28,
STATE_RAWTEXT_END_TAG_NAME = 29,
SHOW_COMMENT = 128,
SHOW_ELEMENT = 1,
TYPE_COMMENT = 8,
TYPE_ELEMENT = 1,
NS_SVG = "http://www.w3.org/2000/svg",
NS_XLINK = "http://www.w3.org/1999/xlink",
NS_XML = "http://www.w3.org/XML/1998/namespace",
NS_XMLNS = "http://www.w3.org/2000/xmlns/";
const svgAdjustAttributes = new Map([
"attributeName",
"attributeType",
"baseFrequency",
"baseProfile",
"calcMode",
"clipPathUnits",
"diffuseConstant",
"edgeMode",
"filterUnits",
"glyphRef",
"gradientTransform",
"gradientUnits",
"kernelMatrix",
"kernelUnitLength",
"keyPoints",
"keySplines",
"keyTimes",
"lengthAdjust",
"limitingConeAngle",
"markerHeight",
"markerUnits",
"markerWidth",
"maskContentUnits",
"maskUnits",
"numOctaves",
"pathLength",
"patternContentUnits",
"patternTransform",
"patternUnits",
"pointsAtX",
"pointsAtY",
"pointsAtZ",
"preserveAlpha",
"preserveAspectRatio",
"primitiveUnits",
"refX",
"refY",
"repeatCount",
"repeatDur",
"requiredExtensions",
"requiredFeatures",
"specularConstant",
"specularExponent",
"spreadMethod",
"startOffset",
"stdDeviation",
"stitchTiles",
"surfaceScale",
"systemLanguage",
"tableValues",
"targetX",
"targetY",
"textLength",
"viewBox",
"viewTarget",
"xChannelSelector",
"yChannelSelector",
"zoomAndPan"
].map(name => [name.toLowerCase(), name]));
const svgForeignAttributes = new Map([
["xlink:actuate", NS_XLINK],
["xlink:arcrole", NS_XLINK],
["xlink:href", NS_XLINK],
["xlink:role", NS_XLINK],
["xlink:show", NS_XLINK],
["xlink:title", NS_XLINK],
["xlink:type", NS_XLINK],
["xml:lang", NS_XML],
["xml:space", NS_XML],
["xmlns", NS_XMLNS],
["xmlns:xlink", NS_XMLNS]
]);
function hypertext(render, postprocess) {
return function({raw: strings}) {
let state = STATE_DATA;
let string = "";
let tagNameStart; // either an open tag or an end tag
let tagName; // only open; beware nesting! used only for rawtext
let attributeNameStart;
let attributeNameEnd;
let nodeFilter = 0;
for (let j = 0, m = arguments.length; j < m; ++j) {
const input = strings[j];
if (j > 0) {
const value = arguments[j];
switch (state) {
case STATE_RAWTEXT: {
if (value != null) {
const text = `${value}`;
if (isEscapableRawText(tagName)) {
string += text.replace(/[<]/g, entity);
} else if (new RegExp(`${tagName}[\\s>/]`, "i").test(string.slice(-tagName.length - 2) + text)) {
throw new Error("unsafe raw text"); // appropriate end tag
} else {
string += text;
}
}
break;
}
case STATE_DATA: {
if (value == null) ; else if (value instanceof Node
|| (typeof value !== "string" && value[Symbol.iterator])
|| (/(?:^|>)$/.test(strings[j - 1]) && /^(?:<|$)/.test(input))) {
string += "";
nodeFilter |= SHOW_COMMENT;
} else {
string += `${value}`.replace(/[<&]/g, entity);
}
break;
}
case STATE_BEFORE_ATTRIBUTE_VALUE: {
state = STATE_ATTRIBUTE_VALUE_UNQUOTED;
let text;
if (/^[\s>]/.test(input)) {
if (value == null || value === false) {
string = string.slice(0, attributeNameStart - strings[j - 1].length);
break;
}
if (value === true || (text = `${value}`) === "") {
string += "''";
break;
}
const name = strings[j - 1].slice(attributeNameStart, attributeNameEnd);
if ((name === "style" && isObjectLiteral(value)) || typeof value === "function") {
string += "::" + j;
nodeFilter |= SHOW_ELEMENT;
break;
}
}
if (text === undefined) text = `${value}`;
if (text === "") throw new Error("unsafe unquoted empty string");
string += text.replace(/^['"]|[\s>&]/g, entity);
break;
}
case STATE_ATTRIBUTE_VALUE_UNQUOTED: {
string += `${value}`.replace(/[\s>&]/g, entity);
break;
}
case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
string += `${value}`.replace(/['&]/g, entity);
break;
}
case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
string += `${value}`.replace(/["&]/g, entity);
break;
}
case STATE_BEFORE_ATTRIBUTE_NAME: {
if (isObjectLiteral(value)) {
string += "::" + j + "=''";
nodeFilter |= SHOW_ELEMENT;
break;
}
throw new Error("invalid binding");
}
case STATE_COMMENT: break;
default: throw new Error("invalid binding");
}
}
for (let i = 0, n = input.length; i < n; ++i) {
const code = input.charCodeAt(i);
switch (state) {
case STATE_DATA: {
if (code === CODE_LT) {
state = STATE_TAG_OPEN;
}
break;
}
case STATE_TAG_OPEN: {
if (code === CODE_BANG) {
state = STATE_MARKUP_DECLARATION_OPEN;
} else if (code === CODE_SLASH) {
state = STATE_END_TAG_OPEN;
} else if (isAsciiAlphaCode(code)) {
tagNameStart = i, tagName = undefined;
state = STATE_TAG_NAME, --i;
} else if (code === CODE_QUESTION) {
state = STATE_BOGUS_COMMENT, --i;
} else {
state = STATE_DATA, --i;
}
break;
}
case STATE_END_TAG_OPEN: {
if (isAsciiAlphaCode(code)) {
state = STATE_TAG_NAME, --i;
} else if (code === CODE_GT) {
state = STATE_DATA;
} else {
state = STATE_BOGUS_COMMENT, --i;
}
break;
}
case STATE_TAG_NAME: {
if (isSpaceCode(code)) {
state = STATE_BEFORE_ATTRIBUTE_NAME;
tagName = lower(input, tagNameStart, i);
} else if (code === CODE_SLASH) {
state = STATE_SELF_CLOSING_START_TAG;
} else if (code === CODE_GT) {
tagName = lower(input, tagNameStart, i);
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
}
break;
}
case STATE_BEFORE_ATTRIBUTE_NAME: {
if (isSpaceCode(code)) ; else if (code === CODE_SLASH || code === CODE_GT) {
state = STATE_AFTER_ATTRIBUTE_NAME, --i;
} else if (code === CODE_EQ) {
state = STATE_ATTRIBUTE_NAME;
attributeNameStart = i + 1, attributeNameEnd = undefined;
} else {
state = STATE_ATTRIBUTE_NAME, --i;
attributeNameStart = i + 1, attributeNameEnd = undefined;
}
break;
}
case STATE_ATTRIBUTE_NAME: {
if (isSpaceCode(code) || code === CODE_SLASH || code === CODE_GT) {
state = STATE_AFTER_ATTRIBUTE_NAME, --i;
attributeNameEnd = i;
} else if (code === CODE_EQ) {
state = STATE_BEFORE_ATTRIBUTE_VALUE;
attributeNameEnd = i;
}
break;
}
case STATE_AFTER_ATTRIBUTE_NAME: {
if (isSpaceCode(code)) ; else if (code === CODE_SLASH) {
state = STATE_SELF_CLOSING_START_TAG;
} else if (code === CODE_EQ) {
state = STATE_BEFORE_ATTRIBUTE_VALUE;
} else if (code === CODE_GT) {
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
} else {
state = STATE_ATTRIBUTE_NAME, --i;
attributeNameStart = i + 1, attributeNameEnd = undefined;
}
break;
}
case STATE_BEFORE_ATTRIBUTE_VALUE: {
if (isSpaceCode(code)) ; else if (code === CODE_DQUOTE) {
state = STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED;
} else if (code === CODE_SQUOTE) {
state = STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED;
} else if (code === CODE_GT) {
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
} else {
state = STATE_ATTRIBUTE_VALUE_UNQUOTED, --i;
}
break;
}
case STATE_ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
if (code === CODE_DQUOTE) {
state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
}
break;
}
case STATE_ATTRIBUTE_VALUE_SINGLE_QUOTED: {
if (code === CODE_SQUOTE) {
state = STATE_AFTER_ATTRIBUTE_VALUE_QUOTED;
}
break;
}
case STATE_ATTRIBUTE_VALUE_UNQUOTED: {
if (isSpaceCode(code)) {
state = STATE_BEFORE_ATTRIBUTE_NAME;
} else if (code === CODE_GT) {
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
}
break;
}
case STATE_AFTER_ATTRIBUTE_VALUE_QUOTED: {
if (isSpaceCode(code)) {
state = STATE_BEFORE_ATTRIBUTE_NAME;
} else if (code === CODE_SLASH) {
state = STATE_SELF_CLOSING_START_TAG;
} else if (code === CODE_GT) {
state = isRawText(tagName) ? STATE_RAWTEXT : STATE_DATA;
} else {
state = STATE_BEFORE_ATTRIBUTE_NAME, --i;
}
break;
}
case STATE_SELF_CLOSING_START_TAG: {
if (code === CODE_GT) {
state = STATE_DATA;
} else {
state = STATE_BEFORE_ATTRIBUTE_NAME, --i;
}
break;
}
case STATE_BOGUS_COMMENT: {
if (code === CODE_GT) {
state = STATE_DATA;
}
break;
}
case STATE_COMMENT_START: {
if (code === CODE_DASH) {
state = STATE_COMMENT_START_DASH;
} else if (code === CODE_GT) {
state = STATE_DATA;
} else {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT_START_DASH: {
if (code === CODE_DASH) {
state = STATE_COMMENT_END;
} else if (code === CODE_GT) {
state = STATE_DATA;
} else {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT: {
if (code === CODE_LT) {
state = STATE_COMMENT_LESS_THAN_SIGN;
} else if (code === CODE_DASH) {
state = STATE_COMMENT_END_DASH;
}
break;
}
case STATE_COMMENT_LESS_THAN_SIGN: {
if (code === CODE_BANG) {
state = STATE_COMMENT_LESS_THAN_SIGN_BANG;
} else if (code !== CODE_LT) {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT_LESS_THAN_SIGN_BANG: {
if (code === CODE_DASH) {
state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH;
} else {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH: {
if (code === CODE_DASH) {
state = STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
} else {
state = STATE_COMMENT_END, --i;
}
break;
}
case STATE_COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: {
state = STATE_COMMENT_END, --i;
break;
}
case STATE_COMMENT_END_DASH: {
if (code === CODE_DASH) {
state = STATE_COMMENT_END;
} else {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT_END: {
if (code === CODE_GT) {
state = STATE_DATA;
} else if (code === CODE_BANG) {
state = STATE_COMMENT_END_BANG;
} else if (code !== CODE_DASH) {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_COMMENT_END_BANG: {
if (code === CODE_DASH) {
state = STATE_COMMENT_END_DASH;
} else if (code === CODE_GT) {
state = STATE_DATA;
} else {
state = STATE_COMMENT, --i;
}
break;
}
case STATE_MARKUP_DECLARATION_OPEN: {
if (code === CODE_DASH && input.charCodeAt(i + 1) === CODE_DASH) {
state = STATE_COMMENT_START, ++i;
} else { // Note: CDATA and DOCTYPE unsupported!
state = STATE_BOGUS_COMMENT, --i;
}
break;
}
case STATE_RAWTEXT: {
if (code === CODE_LT) {
state = STATE_RAWTEXT_LESS_THAN_SIGN;
}
break;
}
case STATE_RAWTEXT_LESS_THAN_SIGN: {
if (code === CODE_SLASH) {
state = STATE_RAWTEXT_END_TAG_OPEN;
} else {
state = STATE_RAWTEXT, --i;
}
break;
}
case STATE_RAWTEXT_END_TAG_OPEN: {
if (isAsciiAlphaCode(code)) {
tagNameStart = i;
state = STATE_RAWTEXT_END_TAG_NAME, --i;
} else {
state = STATE_RAWTEXT, --i;
}
break;
}
case STATE_RAWTEXT_END_TAG_NAME: {
if (isSpaceCode(code) && tagName === lower(input, tagNameStart, i)) {
state = STATE_BEFORE_ATTRIBUTE_NAME;
} else if (code === CODE_SLASH && tagName === lower(input, tagNameStart, i)) {
state = STATE_SELF_CLOSING_START_TAG;
} else if (code === CODE_GT && tagName === lower(input, tagNameStart, i)) {
state = STATE_DATA;
} else if (!isAsciiAlphaCode(code)) {
state = STATE_RAWTEXT, --i;
}
break;
}
default: {
state = undefined;
break;
}
}
}
string += input;
}
const root = render(string);
const walker = document.createTreeWalker(root, nodeFilter, null, false);
const removeNodes = [];
while (walker.nextNode()) {
const node = walker.currentNode;
switch (node.nodeType) {
case TYPE_ELEMENT: {
const attributes = node.attributes;
for (let i = 0, n = attributes.length; i < n; ++i) {
const {name, value: currentValue} = attributes[i];
if (/^::/.test(name)) {
const value = arguments[+name.slice(2)];
removeAttribute(node, name), --i, --n;
for (const key in value) {
const subvalue = value[key];
if (subvalue == null || subvalue === false) ; else if (typeof subvalue === "function") {
node[key] = subvalue;
} else if (key === "style" && isObjectLiteral(subvalue)) {
setStyles(node[key], subvalue);
} else {
setAttribute(node, key, subvalue === true ? "" : subvalue);
}
}
} else if (/^::/.test(currentValue)) {
const value = arguments[+currentValue.slice(2)];
removeAttribute(node, name), --i, --n;
if (typeof value === "function") {
node[name] = value;
} else { // style
setStyles(node[name], value);
}
}
}
break;
}
case TYPE_COMMENT: {
if (/^::/.test(node.data)) {
const parent = node.parentNode;
const value = arguments[+node.data.slice(2)];
if (value instanceof Node) {
parent.insertBefore(value, node);
} else if (typeof value !== "string" && value[Symbol.iterator]) {
if (value instanceof NodeList || value instanceof HTMLCollection) {
for (let i = value.length - 1, r = node; i >= 0; --i) {
r = parent.insertBefore(value[i], r);
}
} else {
for (const subvalue of value) {
if (subvalue == null) continue;
parent.insertBefore(subvalue instanceof Node ? subvalue : document.createTextNode(subvalue), node);
}
}
} else {
parent.insertBefore(document.createTextNode(value), node);
}
removeNodes.push(node);
}
break;
}
}
}
for (const node of removeNodes) {
node.parentNode.removeChild(node);
}
return postprocess(root);
};
}
function entity(character) {
return `${character.charCodeAt(0).toString()};`;
}
function isAsciiAlphaCode(code) {
return (CODE_UPPER_A <= code && code <= CODE_UPPER_Z)
|| (CODE_LOWER_A <= code && code <= CODE_LOWER_Z);
}
function isSpaceCode(code) {
return code === CODE_TAB
|| code === CODE_LF
|| code === CODE_FF
|| code === CODE_SPACE
|| code === CODE_CR; // normalize newlines
}
function isObjectLiteral(value) {
return value && value.toString === Object.prototype.toString;
}
function isRawText(tagName) {
return tagName === "script" || tagName === "style" || isEscapableRawText(tagName);
}
function isEscapableRawText(tagName) {
return tagName === "textarea" || tagName === "title";
}
function lower(input, start, end) {
return input.slice(start, end).toLowerCase();
}
function setAttribute(node, name, value) {
if (node.namespaceURI === NS_SVG) {
name = name.toLowerCase();
name = svgAdjustAttributes.get(name) || name;
if (svgForeignAttributes.has(name)) {
node.setAttributeNS(svgForeignAttributes.get(name), name, value);
return;
}
}
node.setAttribute(name, value);
}
function removeAttribute(node, name) {
if (node.namespaceURI === NS_SVG) {
name = name.toLowerCase();
name = svgAdjustAttributes.get(name) || name;
if (svgForeignAttributes.has(name)) {
node.removeAttributeNS(svgForeignAttributes.get(name), name);
return;
}
}
node.removeAttribute(name);
}
// We can’t use Object.assign because custom properties…
function setStyles(style, values) {
for (const name in values) {
const value = values[name];
if (name.startsWith("--")) style.setProperty(name, value);
else style[name] = value;
}
}
function length(x) {
return x == null ? null : typeof x === "number" ? `${x}px` : `${x}`;
}
const bubbles = {bubbles: true};
function preventDefault(event) {
event.preventDefault();
}
function dispatchInput({currentTarget}) {
(currentTarget.form || currentTarget).dispatchEvent(new Event("input", bubbles));
}
function identity(x) {
return x;
}
let nextId = 0;
function newId() {
return `__ns__-${++nextId}`;
}
function maybeLabel(label, input) {
if (!label) return;
label = html`