"use strict";
(() => {
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
    get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
  }) : x)(function(x) {
    if (typeof require !== "undefined") return require.apply(this, arguments);
    throw Error('Dynamic require of "' + x + '" is not supported');
  });
  var __commonJS = (cb, mod) => function __require2() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };

  // modules/javascript.js
  var require_javascript = __commonJS({
    "modules/javascript.js"(exports2, module2) {
      "use strict";
      function isPlainObject2(value) {
        return value != null && typeof value === "object" && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
      }
      function decorateDict(value) {
        if (!isPlainObject2(value)) {
          return value;
        }
        for (const [name2, fn2] of [
          ["length", function _length() {
            return Object.keys(this).length;
          }],
          ["count", function _count() {
            return Object.keys(this).length;
          }],
          ["empty", function _empty() {
            return Object.keys(this).length === 0 ? 1 : 0;
          }],
          ["keys", function _keys() {
            return Object.keys(this);
          }],
          ["values", function _values() {
            return Object.keys(this).map((key) => this[key]);
          }],
          ["has", function _has(key) {
            return Object.prototype.hasOwnProperty.call(this, String(key)) ? 1 : 0;
          }],
          ["contains", function _contains(key) {
            return this.has(key);
          }],
          ["exists", function _exists(key) {
            return this.has(key);
          }],
          ["defined", function _defined(key) {
            return this.has(key) && this[String(key)] != null ? 1 : 0;
          }],
          ["get", function _get(key, fallback = null) {
            return this.has(key) ? this[String(key)] : fallback;
          }],
          ["add", function _add(key, inner) {
            this[String(key)] = inner;
            return this;
          }],
          ["set", function _set(key, inner) {
            return this.add(key, inner);
          }],
          ["to_Iterator", function _to_iterator() {
            return this.keys()[Symbol.iterator]();
          }]
        ]) {
          if (!Object.prototype.hasOwnProperty.call(value, name2)) {
            Object.defineProperty(value, name2, {
              value: fn2,
              enumerable: false,
              configurable: true,
              writable: true
            });
          }
        }
        for (const key of Object.keys(value)) {
          value[key] = convertSafeValue(value[key]);
        }
        return value;
      }
      function convertSafeValue(value) {
        if (value == null) {
          return null;
        }
        if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
          return value;
        }
        if (Array.isArray(value)) {
          for (let i = 0; i < value.length; i++) {
            value[i] = convertSafeValue(value[i]);
          }
          return value;
        }
        if (isPlainObject2(value)) {
          return decorateDict(value);
        }
        return value;
      }
      function isSafeValue(value, seen = /* @__PURE__ */ new Set()) {
        if (value == null) {
          return true;
        }
        if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
          return true;
        }
        if (typeof value === "bigint" || typeof value === "function" || typeof value === "symbol") {
          return false;
        }
        if (seen.has(value)) {
          return false;
        }
        seen.add(value);
        try {
          if (Array.isArray(value)) {
            return value.every((item) => isSafeValue(item, seen));
          }
          if (isPlainObject2(value)) {
            return Object.values(value).every((item) => isSafeValue(item, seen));
          }
          return false;
        } finally {
          seen.delete(value);
        }
      }
      function jsonValue(value, seen = /* @__PURE__ */ new Set()) {
        if (value == null) {
          return null;
        }
        if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
          return value;
        }
        if (typeof value === "bigint") {
          return value.toString();
        }
        if (typeof value === "function" || typeof value === "symbol") {
          return null;
        }
        if (seen.has(value)) {
          throw new Error("Exception: circular JavaScript value cannot be encoded as JSON");
        }
        seen.add(value);
        try {
          if (Array.isArray(value)) {
            return value.map((item) => jsonValue(item, seen));
          }
          if (isPlainObject2(value)) {
            const out = {};
            for (const [key, inner] of Object.entries(value)) {
              out[key] = jsonValue(inner, seen);
            }
            return out;
          }
          if (typeof value.toJSON === "function") {
            return jsonValue(value.toJSON(), seen);
          }
          return String(value);
        } finally {
          seen.delete(value);
        }
      }
      function evaluate(code, thisValue) {
        const src = String(code ?? "");
        return Function(
          "code",
          "return (function () { return eval( code ); }).call( this );"
        ).call(thisValue, src);
      }
      var JSResult = class _JSResult {
        constructor(value) {
          this._value = value;
        }
        eval(code) {
          return new _JSResult(evaluate(code, this._value));
        }
        isSafe() {
          return isSafeValue(this._value) ? 1 : 0;
        }
        value() {
          if (!this.isSafe()) {
            throw new Error("Exception: JavaScript value is not safely representable in Zuzu");
          }
          return convertSafeValue(this._value);
        }
        toJSON() {
          return JSON.stringify(jsonValue(this._value));
        }
        to_String() {
          if (this._value == null) {
            return "null";
          }
          return String(this._value);
        }
      };
      var JS = {
        eval(code) {
          return new JSResult(evaluate(code, globalThis));
        },
        version() {
          return String(globalThis.process && globalThis.process.version ? globalThis.process.version : "javascript");
        }
      };
      module2.exports = {
        JS,
        JSResult
      };
    }
  });

  // modules/std/string.js
  var require_string = __commonJS({
    "modules/std/string.js"(exports2, module2) {
      "use strict";
      function toStringValue(value) {
        if (value instanceof RegExp) {
          return value.source;
        }
        if (value && typeof value.to_String === "function") {
          return String(value.to_String());
        }
        if (value instanceof Error) {
          return value.message || value.name || String(value);
        }
        return value == null ? "" : String(value);
      }
      function isRegexLike(value) {
        if (value == null) {
          return false;
        }
        if (value instanceof RegExp) {
          return true;
        }
        return Object.prototype.toString.call(value) === "[object RegExp]";
      }
      function index(text, needle, start = 0) {
        const haystack = [...toStringValue(text)];
        const find = [...toStringValue(needle)];
        const offset = Math.max(0, Math.trunc(Number(start ?? 0)));
        if (find.length === 0) {
          return Math.min(offset, haystack.length);
        }
        for (let i = offset; i <= haystack.length - find.length; i++) {
          let matched = true;
          for (let j = 0; j < find.length; j++) {
            if (haystack[i + j] !== find[j]) {
              matched = false;
              break;
            }
          }
          if (matched) {
            return i;
          }
        }
        return -1;
      }
      function rindex(text, needle, start = null) {
        const haystack = [...toStringValue(text)];
        const find = [...toStringValue(needle)];
        if (start == null) {
          start = haystack.length - find.length;
        } else {
          start = Math.trunc(Number(start));
        }
        if (find.length === 0) {
          return Math.min(Math.max(0, start), haystack.length);
        }
        start = Math.min(Math.max(0, start), haystack.length - find.length);
        for (let i = start; i >= 0; i--) {
          let matched = true;
          for (let j = 0; j < find.length; j++) {
            if (haystack[i + j] !== find[j]) {
              matched = false;
              break;
            }
          }
          if (matched) {
            return i;
          }
        }
        return -1;
      }
      function contains(text, needle) {
        return index(text, needle) >= 0;
      }
      function integerValue(value, label) {
        const number = Number(value ?? 0);
        if (!Number.isInteger(number)) {
          throw new Error(`${label} expects an integer`);
        }
        return number;
      }
      function chr(codepoint) {
        if (arguments.length !== 1) {
          throw new Error("chr() expects one argument");
        }
        const value = integerValue(codepoint, "chr()");
        if (value < 0 || value > 1114111) {
          throw new Error("chr() expects a Unicode code point in 0..0x10FFFF");
        }
        if (value >= 55296 && value <= 57343) {
          throw new Error("chr() rejects surrogate code points");
        }
        return String.fromCodePoint(value);
      }
      function ord(text, index2 = 0) {
        if (arguments.length < 1 || arguments.length > 2) {
          throw new Error("ord() expects one or two arguments");
        }
        const chars = [...toStringValue(text)];
        const offset = integerValue(index2, "ord()");
        if (offset < 0 || offset >= chars.length) {
          throw new Error("ord() index out of range");
        }
        return chars[offset].codePointAt(0);
      }
      function substr(text, offset, length = null) {
        const chars = [...toStringValue(text)];
        const from = Number(offset ?? 0);
        if (length == null) {
          return chars.slice(from).join("");
        }
        return chars.slice(from, from + Number(length)).join("");
      }
      function pattern_to_regexp(pattern, caseInsensitive = false) {
        return new RegExp(String(pattern ?? ""), caseInsensitive ? "i" : "");
      }
      var REGEXP_META_CHARS = /* @__PURE__ */ new Set([
        "\\",
        "/",
        "^",
        "$",
        ".",
        "|",
        "?",
        "*",
        "+",
        "(",
        ")",
        "[",
        "]",
        "{",
        "}",
        '"',
        "'"
      ]);
      function quotemeta(text) {
        return [...toStringValue(text)].map((ch) => REGEXP_META_CHARS.has(ch) ? `\\${ch}` : ch).join("");
      }
      function normalizePattern(pattern, flags = "") {
        if (isRegexLike(pattern)) {
          const mergedFlags = [...pattern.flags || "", ...flags || ""];
          const uniqFlags = [...new Set(mergedFlags)].join("");
          return new RegExp(pattern.source, uniqFlags);
        }
        return new RegExp(String(pattern ?? ""), flags);
      }
      function search(text, pattern, flags = "") {
        const match = toStringValue(text).match(normalizePattern(pattern, flags));
        return match ? match[0] : null;
      }
      function matches(text, pattern, flags = "") {
        return normalizePattern(pattern, flags).test(toStringValue(text));
      }
      function replace(text, pattern, replacement, flags = "") {
        return toStringValue(text).replace(normalizePattern(pattern, flags), toStringValue(replacement));
      }
      function sprint(format, ...args) {
        let idx = 0;
        return toStringValue(format).replace(/%([0-9]+)?(?:\.([0-9]+))?([sdfc])/gu, (_token, width, precision, kind) => {
          const value = args[idx++];
          let out = "";
          if (kind === "d") {
            out = String(Math.trunc(Number(value ?? 0)));
          } else if (kind === "f") {
            const num = Number(value ?? 0);
            out = precision != null ? num.toFixed(Number(precision)) : String(num);
          } else if (kind === "c") {
            out = String.fromCharCode(Number(value ?? 0));
          } else {
            out = toStringValue(value);
          }
          if (width != null) {
            const target = Number(width);
            if (out.length < target) {
              out = `${" ".repeat(target - out.length)}${out}`;
            }
          }
          return out;
        });
      }
      function join(separator, values) {
        const sep = toStringValue(separator);
        if (Array.isArray(values)) {
          return values.map((value) => toStringValue(value)).join(sep);
        }
        if (values == null) {
          return "";
        }
        if (typeof values.to_Iterator === "function") {
          const out = [];
          for (const value of values.to_Iterator()) {
            out.push(toStringValue(value));
          }
          return out.join(sep);
        }
        if (typeof values.to_Array === "function") {
          return join(sep, values.to_Array());
        }
        if (typeof values[Symbol.iterator] === "function") {
          return Array.from(values, (value) => toStringValue(value)).join(sep);
        }
        return toStringValue(values);
      }
      function split(text, pattern) {
        return toStringValue(text).split(pattern);
      }
      function starts_with(text, prefix) {
        return toStringValue(text).startsWith(toStringValue(prefix));
      }
      function ends_with(text, suffix) {
        return toStringValue(text).endsWith(toStringValue(suffix));
      }
      function trim(text) {
        return toStringValue(text).trim();
      }
      function pad(text, width, ch = " ", side = "right") {
        const src = toStringValue(text);
        const padChar = toStringValue(ch || " ");
        const target = Number(width ?? 0);
        if (src.length >= target) {
          return src;
        }
        const fill = padChar.repeat(target - src.length);
        return side === "left" ? `${fill}${src}` : `${src}${fill}`;
      }
      function chomp(text) {
        return toStringValue(text).replace(/\r?\n$/u, "");
      }
      function words(text) {
        return toStringValue(text).replace(/([a-z0-9])([A-Z])/gu, "$1 $2").replace(/[_\-]+/gu, " ").trim().split(/\s+/u).filter(Boolean);
      }
      function title(text) {
        return words(text).map((w) => `${w[0].toUpperCase()}${w.slice(1).toLowerCase()}`).join(" ");
      }
      function snake(text) {
        return words(text).map((w) => w.toLowerCase()).join("_");
      }
      function kebab(text) {
        return words(text).map((w) => w.toLowerCase()).join("-");
      }
      function camel(text) {
        const ws = words(text).map((w) => w.toLowerCase());
        return ws.map((w, i) => i === 0 ? w : `${w[0].toUpperCase()}${w.slice(1)}`).join("");
      }
      module2.exports = {
        camel,
        chomp,
        chr,
        contains,
        ends_with,
        index,
        join,
        kebab,
        matches,
        ord,
        pad,
        pattern_to_regexp,
        quotemeta,
        rindex,
        replace,
        search,
        snake,
        split,
        starts_with,
        sprint,
        substr,
        title,
        trim
      };
    }
  });

  // lib/collections.js
  var require_collections = __commonJS({
    "lib/collections.js"(exports2, module2) {
      "use strict";
      function runtimeHelpers() {
        return require_runtime_helpers();
      }
      function retainCollectionValue(collection, value) {
        return runtimeHelpers().retainCollectionValue(collection, value);
      }
      function releaseCollectionValue(collection, value) {
        return runtimeHelpers().releaseCollectionValue(collection, value);
      }
      function releaseCollectionValues(collection) {
        return runtimeHelpers().releaseCollectionValues(collection);
      }
      function makeArray(values) {
        return runtimeHelpers().makeArray(values);
      }
      function makeSet(values) {
        return runtimeHelpers().makeSet(values);
      }
      var ZuzuBag = class _ZuzuBag {
        constructor(...items) {
          let values;
          if (items.length === 0) {
            this.items = [];
            return;
          }
          if (items.length > 1) {
            values = items;
          } else {
            const first = items[0];
            if (Array.isArray(first)) {
              values = first;
            } else if (first != null && typeof first !== "string" && typeof first[Symbol.iterator] === "function") {
              values = Array.from(first);
            } else {
              values = [first];
            }
          }
          this.items = values.map((value) => retainCollectionValue(this, value));
        }
        length() {
          return this.items.length;
        }
        count(value) {
          if (arguments.length === 0) {
            return this.items.length;
          }
          return this.items.filter((item) => item === value).length;
        }
        empty() {
          return this.items.length === 0 ? 1 : 0;
        }
        is_empty() {
          return this.empty();
        }
        contains(value) {
          return this.items.includes(value) ? 1 : 0;
        }
        add(...values) {
          this.items.push(...values.map((value) => retainCollectionValue(this, value)));
          return this;
        }
        push(...values) {
          return this.add(...values);
        }
        remove(value) {
          return this.remove_first(value);
        }
        remove_first(value) {
          const idx = this.items.indexOf(value);
          if (idx >= 0) {
            releaseCollectionValue(this, this.items[idx]);
            this.items.splice(idx, 1);
          }
          return this;
        }
        remove_if(fn2) {
          this.items = this.items.filter((item) => {
            if (fn2(item)) {
              releaseCollectionValue(this, item);
              return false;
            }
            return true;
          });
          return this;
        }
        get(idx, fallback = null) {
          return idx >= 0 && idx < this.items.length ? this.items[idx] : fallback;
        }
        map(fn2) {
          return new _ZuzuBag(this.items.map(fn2));
        }
        grep(fn2) {
          return new _ZuzuBag(this.items.filter(fn2));
        }
        any(fn2) {
          return this.items.some(fn2) ? 1 : 0;
        }
        all(fn2) {
          return this.items.every(fn2) ? 1 : 0;
        }
        first(fn2) {
          for (const item of this.items) {
            if (fn2(item)) {
              return item;
            }
          }
          return null;
        }
        for_each_value(fn2) {
          this.items.forEach(fn2);
          return this;
        }
        to_Array() {
          return makeArray(this.items);
        }
        to_Set() {
          return makeSet(this.items);
        }
        to_Iterator() {
          return this.items[Symbol.iterator]();
        }
        copy() {
          return new _ZuzuBag(this.items);
        }
        uniq() {
          return new _ZuzuBag([...new Set(this.items)]);
        }
        sum() {
          return this.items.reduce((a, b) => Number(a) + Number(b), 0);
        }
        product() {
          return this.items.reduce((a, b) => Number(a) * Number(b), 1);
        }
        sort(fn2) {
          return this.to_Array().sort(fn2);
        }
        sortstr() {
          return this.to_Array().sort((a, b) => String(a).localeCompare(String(b)));
        }
        sortnum() {
          return this.to_Array().map((item) => Number(item)).sort((a, b) => a - b);
        }
        clear() {
          releaseCollectionValues(this);
          this.items = [];
          return this;
        }
        [Symbol.iterator]() {
          return this.items[Symbol.iterator]();
        }
      };
      var Pair = class {
        constructor(options = {}) {
          this.pair = options.pair || [];
        }
        key() {
          return this.pair[0] ?? null;
        }
        value() {
          return this.pair[1] ?? null;
        }
      };
      var PairList = class _PairList {
        constructor(...options) {
          this.list = [];
          if (options.length > 1) {
            this.list = options.filter((entry) => Array.isArray(entry) && entry.length >= 2).map(
              (entry) => [String(entry[0]), retainCollectionValue(this, entry[1])]
            );
            return;
          }
          const first = options.length === 0 ? {} : options[0];
          if (Array.isArray(first)) {
            const entries = Array.isArray(first[0]) ? first : [first];
            this.list = entries.filter((entry) => Array.isArray(entry) && entry.length >= 2).map(
              (entry) => [String(entry[0]), retainCollectionValue(this, entry[1])]
            );
            return;
          }
          if (Array.isArray(first.list)) {
            this.list = first.list.filter((entry) => Array.isArray(entry) && entry.length >= 2).map(
              (entry) => [String(entry[0]), retainCollectionValue(this, entry[1])]
            );
          }
          return new Proxy(this, {
            get(target, prop, receiver) {
              if (typeof prop === "symbol" || prop in target) {
                return Reflect.get(target, prop, receiver);
              }
              if (typeof prop === "string") {
                return target.get(prop, null);
              }
              return void 0;
            },
            set(target, prop, value, receiver) {
              if (typeof prop === "symbol" || prop in target) {
                return Reflect.set(target, prop, value, receiver);
              }
              if (typeof prop === "string") {
                const idx = target.list.findIndex((pair) => pair[0] === String(prop));
                if (idx >= 0) {
                  releaseCollectionValue(target, target.list[idx][1]);
                  target.list[idx][1] = retainCollectionValue(target, value);
                } else {
                  target.list.push([
                    String(prop),
                    retainCollectionValue(target, value)
                  ]);
                }
                return true;
              }
              return false;
            }
          });
        }
        length() {
          return this.list.length;
        }
        count() {
          return this.list.length;
        }
        empty() {
          return this.list.length === 0 ? 1 : 0;
        }
        keys() {
          return this.list.map((pair) => pair[0]);
        }
        values() {
          return this.list.map((pair) => pair[1]);
        }
        enumerate() {
          return this.to_Array();
        }
        has(key) {
          return this.list.some((pair) => pair[0] === String(key)) ? 1 : 0;
        }
        exists(key) {
          return this.has(key);
        }
        defined(key) {
          const found = this.list.find((pair) => pair[0] === String(key));
          return found ? found[1] == null ? 0 : 1 : 0;
        }
        get(key, fallback = null) {
          const found = this.list.find((pair) => pair[0] === String(key));
          return found ? found[1] : fallback;
        }
        get_all(key) {
          return this.list.filter((pair) => pair[0] === String(key)).map((pair) => pair[1]);
        }
        all(key) {
          return this.get_all(key);
        }
        add(key, value) {
          this.list.push([String(key), retainCollectionValue(this, value)]);
          return this;
        }
        set(key, value) {
          return this.add(key, value);
        }
        kv() {
          const out = [];
          for (const [key, value] of this.list) {
            out.push(key, value);
          }
          return out;
        }
        sorted_keys() {
          return this.keys().slice().sort();
        }
        remove(key) {
          if (typeof key === "function") {
            this.list = this.list.filter((pair) => {
              if (key(new Pair({ pair: pair.slice() }))) {
                releaseCollectionValue(this, pair[1]);
                return false;
              }
              return true;
            });
            return this;
          }
          const normalized = String(key);
          this.list = this.list.filter((pair) => {
            if (pair[0] === normalized) {
              releaseCollectionValue(this, pair[1]);
              return false;
            }
            return true;
          });
          return this;
        }
        for_each_key(fn2) {
          for (const key of this.keys()) {
            fn2(key);
          }
          return this;
        }
        for_each_value(fn2) {
          for (const value of this.values()) {
            fn2(value);
          }
          return this;
        }
        for_each_pair(fn2) {
          for (const pair of this.list) {
            fn2(new Pair({ pair: pair.slice() }));
          }
          return this;
        }
        to_Array() {
          return this.list.map((pair) => new Pair({ pair: pair.slice() }));
        }
        to_Iterator() {
          return this.keys()[Symbol.iterator]();
        }
        copy() {
          return new _PairList({ list: this.list.map(([k, v]) => [k, v]) });
        }
        clear() {
          releaseCollectionValues(this);
          this.list = [];
          return this;
        }
      };
      Object.defineProperty(PairList.prototype, "__zuzu_builtin_type", {
        value: "PairList",
        enumerable: false,
        configurable: true
      });
      function withArrayMethods() {
        const define = (name2, fn2) => {
          if (!Object.prototype.hasOwnProperty.call(Array.prototype, name2)) {
            const desc = /* @__PURE__ */ Object.create(null);
            desc.value = fn2;
            desc.enumerable = false;
            Object.defineProperty(Array.prototype, name2, desc);
          }
        };
        define("count", function _count() {
          return this.length;
        });
        define("empty", function _empty() {
          return this.length === 0 ? 1 : 0;
        });
        define("is_empty", function _is_empty() {
          return this.empty();
        });
        define("append", function _append(...values) {
          this.push(...values.map((value) => retainCollectionValue(this, value)));
          return this;
        });
        define("add", function _add(...values) {
          this.push(...values.map((value) => retainCollectionValue(this, value)));
          return this;
        });
        define("prepend", function _prepend(...values) {
          this.unshift(...values.map((value) => retainCollectionValue(this, value)));
          return this;
        });
        define("get", function _get(idx, fallback = null) {
          return idx >= 0 && idx < this.length ? this[idx] : fallback;
        });
        define("set", function _set(idx, value) {
          releaseCollectionValue(this, this[idx]);
          this[idx] = retainCollectionValue(this, value);
          return this;
        });
        define("grep", function _grep(fn2) {
          return this.filter(fn2);
        });
        define("any", function _any(fn2) {
          return this.some(fn2) ? 1 : 0;
        });
        define("all", function _all(fn2) {
          return this.every(fn2) ? 1 : 0;
        });
        define("first", function _first(fn2) {
          return this.find(fn2) ?? null;
        });
        define("remove", function _remove(fn2) {
          for (let i = this.length - 1; i >= 0; i--) {
            if (fn2(this[i])) {
              releaseCollectionValue(this, this[i]);
              this.splice(i, 1);
            }
          }
          return this;
        });
        define("contains", function _contains(value) {
          return this.includes(value) ? 1 : 0;
        });
        define("first_index", function _first_index(fn2) {
          return this.findIndex(fn2);
        });
        define("reductions", function _reductions(fn2) {
          const out = [];
          for (const item of this) {
            if (out.length === 0) {
              out.push(item);
            } else {
              out.push(fn2(out[out.length - 1], item));
            }
          }
          return out;
        });
        define("head", function _head(n) {
          return this.slice(0, n);
        });
        define("tail", function _tail(n) {
          return this.slice(n - 1);
        });
        define("sum", function _sum() {
          return this.reduce((a, b) => Number(a) + Number(b), 0);
        });
        define("product", function _product() {
          return this.reduce((a, b) => Number(a) * Number(b), 1);
        });
        define("shuffle", function _shuffle() {
          return this.slice();
        });
        define("sample", function _sample(n) {
          return this.slice(0, n);
        });
        define("for_each_value", function _for_each_value(fn2) {
          this.forEach(fn2);
          return this;
        });
        define("sortstr", function _sortstr() {
          return this.slice().sort((a, b) => String(a).localeCompare(String(b)));
        });
        define(
          "sortnum",
          function _sortnum() {
            return this.map((item) => Number(item)).sort((a, b) => a - b);
          }
        );
        define("to_Array", function _to_array() {
          return makeArray(this);
        });
        define("to_Set", function _to_set() {
          return makeSet(this);
        });
        define("to_Bag", function _to_bag() {
          return new ZuzuBag(this);
        });
        define("to_Iterator", function _to_iterator() {
          return this[Symbol.iterator]();
        });
        define("copy", function _copy() {
          return makeArray(this);
        });
        define("clear", function _clear() {
          releaseCollectionValues(this);
          this.splice(0, this.length);
          return this;
        });
      }
      module2.exports = {
        ZuzuBag,
        Pair,
        PairList,
        withArrayMethods
      };
    }
  });

  // lib/runtime-helpers.js
  var require_runtime_helpers = __commonJS({
    "lib/runtime-helpers.js"(exports2, module2) {
      "use strict";
      var { ZuzuBag, Pair, PairList, withArrayMethods } = require_collections();
      var ZuzuBinary = class _ZuzuBinary {
        constructor(bytes = []) {
          if (bytes instanceof _ZuzuBinary) {
            this.bytes = new Uint8Array(bytes.bytes);
            return;
          }
          if (bytes instanceof Uint8Array) {
            this.bytes = new Uint8Array(bytes);
            return;
          }
          if (Array.isArray(bytes)) {
            this.bytes = Uint8Array.from(bytes.map((item) => Number(item) & 255));
            return;
          }
          this.bytes = new Uint8Array(0);
        }
        get length() {
          return this.bytes.length;
        }
        byteLength() {
          return this.bytes.length;
        }
        isAscii() {
          for (const byte of this.bytes) {
            if (byte > 127) {
              return 0;
            }
          }
          return 1;
        }
        slice(start, end) {
          return new this.constructor(this.bytes.slice(start, end));
        }
        at(index) {
          let idx = Number(index);
          if (idx < 0) {
            idx = this.bytes.length + idx;
          }
          if (idx < 0 || idx >= this.bytes.length) {
            return null;
          }
          return new this.constructor([this.bytes[idx]]);
        }
        to_String() {
          let out = "";
          for (const byte of this.bytes) {
            out += String.fromCharCode(byte);
          }
          return out;
        }
        toString() {
          return this.to_String();
        }
        [Symbol.toPrimitive](hint) {
          if (hint === "number") {
            return NaN;
          }
          return this.to_String();
        }
      };
      var BinaryString2 = class extends ZuzuBinary {
        constructor(bytes) {
          super(bytes);
        }
      };
      var weakStates = /* @__PURE__ */ new WeakMap();
      var retainedCollectionValues = /* @__PURE__ */ new WeakMap();
      var ZuzuWeakCell = class {
        constructor(value) {
          this.value = value;
        }
        deref() {
          const value = this.value;
          if (!isWeakableValue(value)) {
            return value;
          }
          const state = weakStates.get(value);
          return state && state.strong > 0 ? value : null;
        }
      };
      function isWeakCell(value) {
        return value instanceof ZuzuWeakCell;
      }
      function isWeakableValue(value) {
        if (value == null) {
          return false;
        }
        if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
          return false;
        }
        const tag = Object.prototype.toString.call(value);
        if (tag === "[object Boolean]" || tag === "[object Number]" || tag === "[object String]" || tag === "[object RegExp]") {
          return false;
        }
        if (value instanceof ZuzuBinary) {
          return false;
        }
        return typeof value === "object" || typeof value === "function";
      }
      function resolveWeakValue(value) {
        return isWeakCell(value) ? value.deref() : value;
      }
      function makeWeakValue(value) {
        return new ZuzuWeakCell(resolveWeakValue(value));
      }
      function retainValue(value) {
        const resolved = resolveWeakValue(value);
        if (isWeakableValue(resolved)) {
          const state = weakStates.get(resolved) || { strong: 0 };
          state.strong += 1;
          weakStates.set(resolved, state);
        }
        return resolved;
      }
      function retainedValuesForCollection(collection, create = false) {
        const resolved = resolveWeakValue(collection);
        if (!isWeakableValue(resolved)) {
          return null;
        }
        let values = retainedCollectionValues.get(resolved);
        if (!values && create) {
          values = [];
          retainedCollectionValues.set(resolved, values);
        }
        return values || null;
      }
      function retainCollectionValue(collection, value) {
        if (isWeakCell(value)) {
          return value;
        }
        const retained = retainValue(value);
        const values = retainedValuesForCollection(collection, true);
        if (values) {
          values.push(retained);
        }
        return retained;
      }
      function releaseCollectionValue(collection, value) {
        const values = retainedValuesForCollection(collection);
        if (!values) {
          return false;
        }
        const idx = values.indexOf(value);
        if (idx < 0) {
          return false;
        }
        values.splice(idx, 1);
        releaseValue(value);
        return true;
      }
      function releaseCollectionValues(collection) {
        const resolved = resolveWeakValue(collection);
        if (!isWeakableValue(resolved)) {
          return null;
        }
        const values = retainedCollectionValues.get(resolved);
        if (!values) {
          return null;
        }
        retainedCollectionValues.delete(resolved);
        while (values.length > 0) {
          releaseValue(values.pop());
        }
        return null;
      }
      function releaseValue(value) {
        if (isWeakCell(value)) {
          return null;
        }
        const resolved = resolveWeakValue(value);
        if (isWeakableValue(resolved)) {
          const state = weakStates.get(resolved);
          if (state) {
            const wasStrong = state.strong;
            state.strong = Math.max(0, state.strong - 1);
            if (wasStrong > 0 && state.strong === 0) {
              releaseCollectionValues(resolved);
            }
          }
        }
        return null;
      }
      function assignStrongValue(oldValue, newValue) {
        releaseValue(oldValue);
        return retainValue(newValue);
      }
      function assignWeakValue(oldValue, newValue) {
        releaseValue(oldValue);
        return makeWeakValue(newValue);
      }
      function isSetLike(value) {
        return Object.prototype.toString.call(value) === "[object Set]";
      }
      function isPairListLike(value) {
        if (value == null) {
          return false;
        }
        if (value instanceof PairList) {
          return true;
        }
        if (value.__zuzu_builtin_type === "PairList") {
          return true;
        }
        const ctorName = value.constructor && value.constructor.name;
        return ctorName === "PairList" || ctorName === "_PairList";
      }
      function collectTopLevelDeclarations(source, stripPod) {
        const stripped = stripPod(source);
        const masked = [];
        let depth = 0;
        let inSingle = false;
        let inDouble = false;
        let inBacktick = false;
        let inRegex = false;
        let inRegexClass = false;
        let inLineComment = false;
        let inBlockComment = false;
        let escape = false;
        for (let i = 0; i < stripped.length; i++) {
          const ch = stripped[i];
          const next = stripped[i + 1] || "";
          if (inLineComment) {
            if (ch === "\n") {
              inLineComment = false;
              masked.push("\n");
            } else {
              masked.push(" ");
            }
            continue;
          }
          if (inBlockComment) {
            if (ch === "*" && next === "/") {
              inBlockComment = false;
              masked.push(" ");
              i++;
              masked.push(" ");
              continue;
            }
            masked.push(ch === "\n" ? "\n" : " ");
            continue;
          }
          if (inRegex) {
            if (escape) {
              escape = false;
              masked.push(" ");
              continue;
            }
            if (ch === "\\") {
              escape = true;
              masked.push(" ");
              continue;
            }
            if (ch === "[") {
              inRegexClass = true;
              masked.push(" ");
              continue;
            }
            if (ch === "]") {
              inRegexClass = false;
              masked.push(" ");
              continue;
            }
            if (ch === "/" && !inRegexClass) {
              inRegex = false;
              masked.push(" ");
              continue;
            }
            masked.push(ch === "\n" ? "\n" : " ");
            continue;
          }
          if (inSingle || inDouble || inBacktick) {
            if (escape) {
              escape = false;
              masked.push(" ");
              continue;
            }
            if (ch === "\\") {
              escape = true;
              masked.push(" ");
              continue;
            }
            if (inSingle && ch === "'") {
              inSingle = false;
            } else if (inDouble && ch === '"') {
              inDouble = false;
            } else if (inBacktick && ch === "`") {
              inBacktick = false;
            }
            masked.push(ch === "\n" ? "\n" : " ");
            continue;
          }
          if (ch === "/" && next === "/") {
            inLineComment = true;
            masked.push(" ");
            i++;
            masked.push(" ");
            continue;
          }
          if (ch === "/" && next === "*") {
            inBlockComment = true;
            masked.push(" ");
            i++;
            masked.push(" ");
            continue;
          }
          if (ch === "/" && looksLikeRegexLiteralStart(stripped, i)) {
            inRegex = true;
            inRegexClass = false;
            masked.push(" ");
            continue;
          }
          if (ch === "'") {
            inSingle = true;
            masked.push(" ");
            continue;
          }
          if (ch === '"') {
            inDouble = true;
            masked.push(" ");
            continue;
          }
          if (ch === "`") {
            inBacktick = true;
            masked.push(" ");
            continue;
          }
          if (ch === "{") {
            depth++;
            masked.push(" ");
            continue;
          }
          if (ch === "}") {
            if (depth > 0) {
              depth--;
            }
            masked.push(" ");
            continue;
          }
          masked.push(depth === 0 ? ch : ch === "\n" ? "\n" : " ");
        }
        const topLevel = masked.join("");
        const names = /* @__PURE__ */ new Set();
        const patterns = [
          /(?:^|[;\n])\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_][A-Za-z0-9_]*)\s*(?:\(|\b)/gm,
          /(?:^|[;\n])\s*(?:export\s+)?(?:async\s+)?fn\s+(?:[A-Za-z_][A-Za-z0-9_]*\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*(?:\(|\b)/gm,
          /(?:^|[;\n])\s*(?:export\s+)?class\s+([A-Za-z_][A-Za-z0-9_]*)\b/gm,
          /(?:^|[;\n])\s*(?:export\s+)?trait\s+([A-Za-z_][A-Za-z0-9_]*)\b/gm,
          /(?:^|[;\n])\s*(?:export\s+)?(?:let|const)\s+(?:[A-Za-z_][A-Za-z0-9_]*\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*(?::=|=|;)/gm
        ];
        for (const rx of patterns) {
          let match = rx.exec(topLevel);
          while (match) {
            names.add(match[1]);
            match = rx.exec(topLevel);
          }
        }
        for (const name2 of collectTopLevelUnpackDeclarationNames(stripped, topLevel)) {
          names.add(name2);
        }
        const importRx = /(?:^|[;\n])\s*from\s+[^;\n]+?\s+(?:try\s+)?import\s+([\s\S]*?);/gm;
        let importMatch = importRx.exec(topLevel);
        while (importMatch) {
          for (const rawPart of importMatch[1].split(",")) {
            const part = rawPart.trim();
            if (!part || part === "*") {
              continue;
            }
            const alias = part.match(/\bas\s+([A-Za-z_][A-Za-z0-9_]*)\s*$/u);
            if (alias) {
              names.add(alias[1]);
              continue;
            }
            const direct = part.match(/^([A-Za-z_][A-Za-z0-9_]*)\b/u);
            if (direct) {
              names.add(direct[1]);
            }
          }
          importMatch = importRx.exec(topLevel);
        }
        return [...names];
      }
      function looksLikeRegexLiteralStart(source, index) {
        let pos = index - 1;
        while (pos >= 0 && /\s/u.test(source[pos])) {
          pos--;
        }
        if (pos < 0) {
          return true;
        }
        const previous = source[pos];
        return /[({[=,:;!~?&|+\-*%^<>]/u.test(previous);
      }
      function collectTopLevelUnpackDeclarationNames(source, topLevelMask) {
        const names = [];
        const rx = /(?:^|[;\n])\s*(?:export\s+)?(?:let|const)\b/gm;
        let match = rx.exec(topLevelMask);
        while (match) {
          let cursor = rx.lastIndex;
          while (/\s/u.test(source[cursor] || "")) {
            cursor++;
          }
          if (source[cursor] !== "{") {
            match = rx.exec(topLevelMask);
            continue;
          }
          const end = findMatchingBrace(source, cursor);
          if (end !== -1) {
            const pattern = source.slice(cursor + 1, end);
            names.push(...extractUnpackBindingNames(pattern));
            rx.lastIndex = end + 1;
          }
          match = rx.exec(topLevelMask);
        }
        return names;
      }
      function findMatchingBrace(source, start) {
        let depth = 0;
        let quote = null;
        let escape = false;
        for (let i = start; i < source.length; i++) {
          const ch = source[i];
          if (quote) {
            if (escape) {
              escape = false;
            } else if (ch === "\\") {
              escape = true;
            } else if (ch === quote) {
              quote = null;
            }
            continue;
          }
          if (ch === '"' || ch === "'" || ch === "`") {
            quote = ch;
            continue;
          }
          if (ch === "{") {
            depth++;
          } else if (ch === "}") {
            depth--;
            if (depth === 0) {
              return i;
            }
          }
        }
        return -1;
      }
      function extractUnpackBindingNames(pattern) {
        const names = [];
        for (const entry of splitTopLevel(pattern, ",")) {
          const beforeDefault = splitFirstTopLevelOperator(entry, ":=")[0].trim();
          if (!beforeDefault) {
            continue;
          }
          const beforeWeak = beforeDefault.replace(/\s+but\s+weak\s*$/u, "");
          const aliasParts = splitFirstTopLevelOperator(beforeWeak, ":");
          const binding = (aliasParts.length > 1 ? aliasParts[1] : aliasParts[0]).trim();
          const match = binding.match(/(?:^|\s)([A-Za-z_][A-Za-z0-9_]*)\s*$/u);
          if (match) {
            names.push(match[1]);
          }
        }
        return names;
      }
      function splitTopLevel(source, delimiter) {
        const parts = [];
        let start = 0;
        let depth = 0;
        let quote = null;
        let escape = false;
        for (let i = 0; i < source.length; i++) {
          const ch = source[i];
          if (quote) {
            if (escape) {
              escape = false;
            } else if (ch === "\\") {
              escape = true;
            } else if (ch === quote) {
              quote = null;
            }
            continue;
          }
          if (ch === '"' || ch === "'" || ch === "`") {
            quote = ch;
            continue;
          }
          if (ch === "(" || ch === "[" || ch === "{") {
            depth++;
            continue;
          }
          if (ch === ")" || ch === "]" || ch === "}") {
            depth = Math.max(0, depth - 1);
            continue;
          }
          if (depth === 0 && source.slice(i, i + delimiter.length) === delimiter) {
            parts.push(source.slice(start, i));
            i += delimiter.length - 1;
            start = i + 1;
          }
        }
        parts.push(source.slice(start));
        return parts;
      }
      function splitFirstTopLevelOperator(source, operator) {
        const parts = splitTopLevel(source, operator);
        if (parts.length <= 1) {
          return [source];
        }
        return [parts[0], parts.slice(1).join(operator)];
      }
      function buildComparator(name2) {
        if (name2 === "eq") {
          return (left, right) => String(left) === String(right);
        }
        if (name2 === "~") {
          return (left, right) => {
            if (right && typeof right.test === "function") {
              return right.test(String(left));
            }
            return false;
          };
        }
        return (left, right) => left == right;
      }
      function runSwitch(value, cmpName, cases, defaultBody) {
        const cmp = buildComparator(cmpName);
        let runNext = false;
        for (const section of cases) {
          const matched = section.values.some((item) => cmp(value, item));
          if (matched || runNext) {
            const result = section.body();
            runNext = result === true;
            if (!runNext && result && typeof result === "object" && result.__zuzu_return) {
              return result;
            }
            if (!runNext) {
              return;
            }
          }
        }
        if (defaultBody) {
          const result = defaultBody();
          if (result && typeof result === "object" && result.__zuzu_return) {
            return result;
          }
        }
      }
      function runMatch(left, right) {
        if (right && typeof right.test === "function") {
          const flags = typeof right.flags === "string" ? right.flags : "";
          const clone = new RegExp(right.source || operatorString(right), flags);
          const input2 = operatorString(left);
          if (flags.includes("g")) {
            return [...input2.matchAll(clone)];
          }
          const matched2 = input2.match(clone);
          return matched2 || false;
        }
        const input = operatorString(left);
        const pattern = operatorRegexp(right);
        const matched = input.match(pattern);
        return matched || false;
      }
      function toArrayLike(value) {
        if (value instanceof ZuzuBag) {
          return value.to_Array();
        }
        if (isSetLike(value)) {
          return [...value];
        }
        if (Array.isArray(value)) {
          return value.slice();
        }
        if (value && typeof value === "object") {
          return Object.keys(value);
        }
        return [];
      }
      function contains(collection, item) {
        collection = resolveWeakValue(collection);
        item = resolveWeakValue(item);
        if (collection instanceof ZuzuBag) {
          return collection.contains(item);
        }
        if (isSetLike(collection)) {
          for (const value of collection) {
            if (resolveWeakValue(value) === item) {
              return 1;
            }
          }
          return 0;
        }
        if (Array.isArray(collection)) {
          return collection.some((value) => resolveWeakValue(value) === item) ? 1 : 0;
        }
        if (collection && typeof collection === "object") {
          return Object.prototype.hasOwnProperty.call(collection, String(item)) ? 1 : 0;
        }
        return 0;
      }
      function makeLike(left, values) {
        if (left instanceof ZuzuBag) {
          return new ZuzuBag(values);
        }
        if (isSetLike(left)) {
          return new Set(values);
        }
        if (Array.isArray(left)) {
          return [...new Set(values)];
        }
        if (left && typeof left === "object") {
          const out = {};
          for (const key of values) {
            out[String(key)] = true;
          }
          const desc = /* @__PURE__ */ Object.create(null);
          desc.value = function _containsKey(key) {
            return Object.prototype.hasOwnProperty.call(out, String(key)) ? 1 : 0;
          };
          desc.enumerable = false;
          Object.defineProperty(out, "contains", desc);
          return out;
        }
        return values;
      }
      function collectionUnion(left, right) {
        const merged = [...toArrayLike(left), ...toArrayLike(right)];
        const deduped = [...new Set(merged)];
        return makeLike(left, deduped);
      }
      function collectionIntersection(left, right) {
        const rightArr = toArrayLike(right);
        return makeLike(left, toArrayLike(left).filter((item) => rightArr.includes(item)));
      }
      function collectionDifference(left, right) {
        const rightArr = toArrayLike(right);
        return makeLike(left, toArrayLike(left).filter((item) => !rightArr.includes(item)));
      }
      function collectionSubsetOf(left, right) {
        const rightArr = toArrayLike(right);
        return toArrayLike(left).every((item) => rightArr.includes(item)) ? 1 : 0;
      }
      function collectionSupersetOf(left, right) {
        return collectionSubsetOf(right, left);
      }
      function collectionEquivalentOf(left, right) {
        return collectionSubsetOf(left, right) && collectionSubsetOf(right, left) ? 1 : 0;
      }
      function makeArray(values) {
        const array = [];
        for (const value of values) {
          array.push(retainCollectionValue(array, value));
        }
        return array;
      }
      function makeSet(values) {
        const set = /* @__PURE__ */ new Set();
        for (const value of values) {
          addSetValue(set, value);
        }
        if (typeof set.to_Iterator !== "function") {
          const desc = /* @__PURE__ */ Object.create(null);
          desc.value = function _toIterator() {
            return this.values();
          };
          desc.enumerable = false;
          Object.defineProperty(set, "to_Iterator", desc);
        }
        return set;
      }
      function addSetValue(set, value) {
        if (set.has(value)) {
          return value;
        }
        const retained = retainCollectionValue(set, value);
        set.add(retained);
        return retained;
      }
      function makeBag(values) {
        const bag = new ZuzuBag();
        bag.items = values.map((value) => retainCollectionValue(bag, value));
        return bag;
      }
      function makePairList(entries = []) {
        const pairs = new PairList();
        pairs.list = entries.map(
          (entry) => [String(entry[0]), retainCollectionValue(pairs, entry[1])]
        );
        return pairs;
      }
      function makeTemporaryPairList(entries = []) {
        const pairs = makePairList(entries);
        Object.defineProperty(pairs, "__zuzu_temporary_call_args", {
          value: true,
          enumerable: false,
          configurable: true
        });
        return pairs;
      }
      function lengthOf(value) {
        if (value instanceof ZuzuBinary) {
          return value.byteLength();
        }
        if (value && value.bytes instanceof Uint8Array) {
          return value.bytes.length;
        }
        if (isPairListLike(value)) {
          return value.length();
        }
        if (value instanceof ZuzuBag) {
          return value.length();
        }
        if (isSetLike(value)) {
          return value.size;
        }
        if (typeof value === "string") {
          return [...value].length;
        }
        if (Array.isArray(value)) {
          return value.length;
        }
        if (value && typeof value === "object") {
          return Object.keys(value).length;
        }
        return 0;
      }
      function typeName2(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return "Null";
        }
        if (value instanceof ZuzuBinary) {
          return "BinaryString";
        }
        if (isPairListLike(value)) {
          return "PairList";
        }
        if (value instanceof ZuzuBag) {
          return "Bag";
        }
        if (isSetLike(value)) {
          return "Set";
        }
        if (Array.isArray(value)) {
          return "Array";
        }
        if (value instanceof Pair) {
          return "Pair";
        }
        if (value instanceof RegExp || Object.prototype.toString.call(value) === "[object RegExp]") {
          return "Regexp";
        }
        if (typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]") {
          return "Boolean";
        }
        if (typeof value === "number" || Object.prototype.toString.call(value) === "[object Number]") {
          return "Number";
        }
        if (typeof value === "string" || Object.prototype.toString.call(value) === "[object String]") {
          return "String";
        }
        if (typeof value === "function") {
          const source = Function.prototype.toString.call(value);
          return /^\s*class\b/.test(source) ? "Class" : "Function";
        }
        if (value && value.constructor && value.constructor.name) {
          const name2 = value.constructor.name;
          return name2 === "Object" ? "Dict" : name2;
        }
        return "Object";
      }
      function renderNumber(value) {
        if (Object.is(value, -0)) {
          return "0";
        }
        return String(value);
      }
      function operatorString(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return "";
        }
        if (typeof value === "string" || Object.prototype.toString.call(value) === "[object String]") {
          return String(value);
        }
        if (typeof value === "number" || Object.prototype.toString.call(value) === "[object Number]") {
          return renderNumber(Number(value));
        }
        if (typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]") {
          return value.valueOf() ? "true" : "false";
        }
        if (value instanceof RegExp || Object.prototype.toString.call(value) === "[object RegExp]") {
          return value.source || "";
        }
        if (value instanceof ZuzuBinary) {
          throw new Error(`TypeException: cannot coerce ${typeName2(value)} to String`);
        }
        if (typeof value === "function" || value.__zuzu_method === true || value.constructor && value.constructor.name === "ZuzuMethod") {
          throw new Error(`TypeException: cannot coerce ${typeName2(value)} to String`);
        }
        if (value && typeof value.to_String === "function") {
          return operatorString(value.to_String());
        }
        throw new Error(`TypeException: cannot coerce ${typeName2(value)} to String`);
      }
      function operatorRegexp(value) {
        value = resolveWeakValue(value);
        if (value instanceof RegExp || Object.prototype.toString.call(value) === "[object RegExp]") {
          const flags = typeof value.flags === "string" ? value.flags : "";
          return new RegExp(value.source || "", flags);
        }
        return new RegExp(operatorString(value));
      }
      module2.exports = {
        collectTopLevelDeclarations,
        runSwitch,
        runMatch,
        toArrayLike,
        contains,
        collectionUnion,
        collectionIntersection,
        collectionDifference,
        collectionSubsetOf,
        collectionSupersetOf,
        collectionEquivalentOf,
        makeArray,
        makeSet,
        makeBag,
        makePairList,
        makeTemporaryPairList,
        lengthOf,
        operatorString,
        operatorRegexp,
        ZuzuBinary,
        BinaryString: BinaryString2,
        ZuzuWeakCell,
        isWeakCell,
        isWeakableValue,
        isPairListLike,
        makeWeakValue,
        resolveWeakValue,
        retainValue,
        releaseValue,
        retainCollectionValue,
        releaseCollectionValue,
        releaseCollectionValues,
        addSetValue,
        assignStrongValue,
        assignWeakValue,
        ZuzuBag,
        Pair,
        PairList,
        withArrayMethods
      };
    }
  });

  // modules/std/string/base64.js
  var require_base64 = __commonJS({
    "modules/std/string/base64.js"(exports2, module2) {
      "use strict";
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      var DECODE = (() => {
        const out = /* @__PURE__ */ Object.create(null);
        for (let i = 0; i < ALPHABET.length; i++) {
          out[ALPHABET[i]] = i;
        }
        return out;
      })();
      function typeName2(value) {
        if (value == null) {
          return "Null";
        }
        if (typeof value === "string") {
          return "String";
        }
        if (value.bytes instanceof Uint8Array) {
          return "BinaryString";
        }
        return value.constructor && value.constructor.name ? value.constructor.name : typeof value;
      }
      function encodeBytes(bytes) {
        let out = "";
        for (let i = 0; i < bytes.length; i += 3) {
          const b0 = bytes[i];
          const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
          const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
          out += ALPHABET[b0 >> 2];
          out += ALPHABET[(b0 & 3) << 4 | b1 >> 4];
          out += i + 1 < bytes.length ? ALPHABET[(b1 & 15) << 2 | b2 >> 6] : "=";
          out += i + 2 < bytes.length ? ALPHABET[b2 & 63] : "=";
        }
        return out;
      }
      function decodeText(value) {
        const clean = String(value).replace(/\s+/gu, "");
        if (clean.length % 4 !== 0) {
          throw new Error("Exception: invalid Base64 length");
        }
        let padding = 0;
        if (clean.endsWith("==")) {
          padding = 2;
        } else if (clean.endsWith("=")) {
          padding = 1;
        }
        const bytes = [];
        for (let i = 0; i < clean.length; i += 4) {
          const chunk = clean.slice(i, i + 4);
          const values = [];
          for (let j = 0; j < 4; j++) {
            const ch = chunk[j];
            if (ch === "=") {
              values.push(0);
              continue;
            }
            if (DECODE[ch] == null) {
              throw new Error(`Exception: invalid Base64 character '${ch}'`);
            }
            values.push(DECODE[ch]);
          }
          const triple = values[0] << 18 | values[1] << 12 | values[2] << 6 | values[3];
          bytes.push(triple >> 16 & 255);
          if (chunk[2] !== "=") {
            bytes.push(triple >> 8 & 255);
          }
          if (chunk[3] !== "=") {
            bytes.push(triple & 255);
          }
        }
        const firstPadding = clean.indexOf("=");
        if (firstPadding >= 0 && firstPadding !== clean.length - padding) {
          throw new Error("Exception: invalid Base64 padding");
        }
        return new Uint8Array(bytes);
      }
      function encode(value) {
        if (!(value && value.bytes instanceof Uint8Array)) {
          throw new Error(`TypeException: encode expects BinaryString, got ${typeName2(value)}`);
        }
        return encodeBytes(value.bytes);
      }
      function decode(value) {
        if (typeof value !== "string") {
          throw new Error(`TypeException: decode expects String, got ${typeName2(value)}`);
        }
        return new BinaryString2(decodeText(value));
      }
      function encode_urlsafe(value) {
        return encode(value).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/gu, "");
      }
      function decode_urlsafe(value) {
        if (typeof value !== "string") {
          throw new Error(`TypeException: decode expects String, got ${typeName2(value)}`);
        }
        let normalized = value.replace(/-/gu, "+").replace(/_/gu, "/");
        const mod = normalized.length % 4;
        if (mod !== 0) {
          normalized += "=".repeat(4 - mod);
        }
        return decode(normalized);
      }
      module2.exports = {
        decode,
        decode_urlsafe,
        encode,
        encode_urlsafe
      };
    }
  });

  // modules/std/time.js
  var require_time = __commonJS({
    "modules/std/time.js"(exports2, module2) {
      "use strict";
      var MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
      var MONTH_BY_NAME = /* @__PURE__ */ new Map([
        ["jan", 1],
        ["january", 1],
        ["feb", 2],
        ["february", 2],
        ["mar", 3],
        ["march", 3],
        ["apr", 4],
        ["april", 4],
        ["may", 5],
        ["jun", 6],
        ["june", 6],
        ["jul", 7],
        ["july", 7],
        ["aug", 8],
        ["august", 8],
        ["sep", 9],
        ["sept", 9],
        ["september", 9],
        ["oct", 10],
        ["october", 10],
        ["nov", 11],
        ["november", 11],
        ["dec", 12],
        ["december", 12]
      ]);
      var WEEKDAY_BY_NAME = /* @__PURE__ */ new Set([
        "sun",
        "sunday",
        "mon",
        "monday",
        "tue",
        "tues",
        "tuesday",
        "wed",
        "weds",
        "wednesday",
        "thu",
        "thur",
        "thurs",
        "thursday",
        "fri",
        "friday",
        "sat",
        "saturday"
      ]);
      function defineType(object, name2) {
        Object.defineProperty(object, "__zuzu_type_name", {
          value: name2,
          enumerable: false,
          configurable: true
        });
      }
      function zoneName(zone) {
        if (zone instanceof TimeZone) {
          return zone.name();
        }
        if (zone == null || String(zone) === "") {
          return "UTC";
        }
        const text = String(zone);
        if (/^z$/iu.test(text) || /^gmt$/iu.test(text)) {
          return "UTC";
        }
        if (/^([+-]\d\d):?(\d\d)$/u.test(text)) {
          return text.replace(/^([+-]\d\d):?(\d\d)$/u, "$1:$2");
        }
        return text;
      }
      function isFixedOffset(zone) {
        return /^([+-]\d\d):(\d\d)$/u.test(zoneName(zone));
      }
      function offsetSeconds(zone) {
        const m = zoneName(zone).match(/^([+-])(\d\d):(\d\d)$/u);
        if (!m) {
          return null;
        }
        const seconds = Number(m[2]) * 3600 + Number(m[3]) * 60;
        return m[1] === "-" ? -seconds : seconds;
      }
      function pad(value, width = 2) {
        return String(value).padStart(width, "0");
      }
      function stripTrailingPeriod(text) {
        return String(text).replace(/\.+$/u, "").toLowerCase();
      }
      function isLeapYear(year) {
        if (year % 4 !== 0) return false;
        if (year % 100 !== 0) return true;
        return year % 400 === 0;
      }
      function daysInMonth(year, month) {
        if ([1, 3, 5, 7, 8, 10, 12].includes(month)) return 31;
        if ([4, 6, 9, 11].includes(month)) return 30;
        if (month === 2) return isLeapYear(year) ? 29 : 28;
        return 0;
      }
      function normaliseParts(parts) {
        if (parts.hour === 24) {
          parts.hour = 0;
        }
        return parts;
      }
      function partsForEpoch(epoch, zone) {
        const name2 = zoneName(zone);
        if (isFixedOffset(name2)) {
          const d = new Date((epoch + offsetSeconds(name2)) * 1e3);
          return {
            year: d.getUTCFullYear(),
            month: d.getUTCMonth() + 1,
            day: d.getUTCDate(),
            hour: d.getUTCHours(),
            minute: d.getUTCMinutes(),
            second: d.getUTCSeconds(),
            offset: offsetSeconds(name2)
          };
        }
        const formatter = new Intl.DateTimeFormat("en-GB-u-ca-gregory", {
          timeZone: name2 === "local" ? void 0 : name2,
          year: "numeric",
          month: "2-digit",
          day: "2-digit",
          hour: "2-digit",
          minute: "2-digit",
          second: "2-digit",
          hourCycle: "h23"
        });
        const out = {};
        for (const part of formatter.formatToParts(new Date(epoch * 1e3))) {
          if (part.type === "year") out.year = Number(part.value);
          if (part.type === "month") out.month = Number(part.value);
          if (part.type === "day") out.day = Number(part.value);
          if (part.type === "hour") out.hour = Number(part.value);
          if (part.type === "minute") out.minute = Number(part.value);
          if (part.type === "second") out.second = Number(part.value);
        }
        return normaliseParts(out);
      }
      function offsetForEpoch(epoch, zone) {
        if (isFixedOffset(zone)) {
          return offsetSeconds(zone);
        }
        const parts = partsForEpoch(epoch, zone);
        const naive = Date.UTC(
          parts.year,
          parts.month - 1,
          parts.day,
          parts.hour,
          parts.minute,
          parts.second
        ) / 1e3;
        return naive - Math.floor(epoch);
      }
      function sameWallEpoch(wall, zone) {
        const name2 = zoneName(zone);
        let current = { ...wall };
        for (let shift = 0; shift <= 180; shift++) {
          if (shift > 0) {
            const shifted = new Date(Date.UTC(
              wall.year,
              wall.month - 1,
              wall.day,
              wall.hour,
              wall.minute + shift,
              wall.second
            ));
            current = {
              year: shifted.getUTCFullYear(),
              month: shifted.getUTCMonth() + 1,
              day: shifted.getUTCDate(),
              hour: shifted.getUTCHours(),
              minute: shifted.getUTCMinutes(),
              second: shifted.getUTCSeconds()
            };
          }
          const naive = Date.UTC(
            current.year,
            current.month - 1,
            current.day,
            current.hour,
            current.minute,
            current.second
          ) / 1e3;
          const offsets = /* @__PURE__ */ new Set([
            offsetForEpoch(naive - 172800, name2),
            offsetForEpoch(naive - 86400, name2),
            offsetForEpoch(naive - 3600, name2),
            offsetForEpoch(naive, name2),
            offsetForEpoch(naive + 3600, name2),
            offsetForEpoch(naive + 86400, name2),
            offsetForEpoch(naive + 172800, name2)
          ]);
          const candidates = [];
          for (const offset of offsets) {
            const candidate = naive - offset;
            const check = partsForEpoch(candidate, name2);
            if (check.year === current.year && check.month === current.month && check.day === current.day && check.hour === current.hour && check.minute === current.minute && check.second === current.second) {
              candidates.push(candidate);
            }
          }
          if (candidates.length) {
            return Math.min(...candidates) + (wall.fraction || 0);
          }
        }
        return Date.UTC(wall.year, wall.month - 1, wall.day, wall.hour, wall.minute, wall.second) / 1e3;
      }
      function addMonthsToWall(parts, months) {
        const total = parts.year * 12 + (parts.month - 1) + Number(months);
        const year = Math.floor(total / 12);
        const month = (total % 12 + 12) % 12 + 1;
        const last = new Date(Date.UTC(year, month, 0)).getUTCDate();
        return { ...parts, year, month, day: Math.min(parts.day, last) };
      }
      function formatOffset(seconds, colon = true) {
        const sign = seconds < 0 ? "-" : "+";
        const abs = Math.abs(seconds);
        const text = `${sign}${pad(Math.floor(abs / 3600))}${pad(Math.floor(abs % 3600 / 60))}`;
        return colon ? `${text.slice(0, 3)}:${text.slice(3)}` : text;
      }
      function parseOffset(text) {
        if (text == null || /^(?:z|utc|gmt)$/iu.test(text)) {
          return 0;
        }
        if (/^ut$/iu.test(text)) {
          return 0;
        }
        const m = String(text).match(/^([+-])(\d\d):?(\d\d)$/u);
        if (!m) {
          return null;
        }
        const hours = Number(m[2]);
        const minutes = Number(m[3]);
        if (hours > 23 || minutes > 59) {
          return null;
        }
        const value = hours * 3600 + minutes * 60;
        return m[1] === "-" ? -value : value;
      }
      function parseRfc5322Zone(text) {
        const offset = parseOffset(text);
        if (offset != null) {
          return offset;
        }
        const key = String(text).toUpperCase();
        const legacy = {
          EST: -5 * 3600,
          EDT: -4 * 3600,
          CST: -6 * 3600,
          CDT: -5 * 3600,
          MST: -7 * 3600,
          MDT: -6 * 3600,
          PST: -8 * 3600,
          PDT: -7 * 3600
        };
        if (Object.prototype.hasOwnProperty.call(legacy, key)) {
          return legacy[key];
        }
        if (/^[A-Z]$/u.test(key) && key !== "J") {
          const pos = "ABCDEFGHIKLMNOPQRSTUVWXYZ".indexOf(key);
          if (pos >= 0) {
            return pos < 12 ? (pos + 1) * 3600 : -(pos - 11) * 3600;
          }
        }
        return null;
      }
      var TimeZone = class _TimeZone {
        constructor(name2 = "UTC") {
          defineType(this, "TimeZone");
          this._name = zoneName(name2);
        }
        static utc() {
          return new _TimeZone("UTC");
        }
        static local() {
          return new _TimeZone("local");
        }
        static named(name2) {
          return new _TimeZone(name2);
        }
        static offset(seconds) {
          return new _TimeZone(formatOffset(Number(seconds), true));
        }
        name() {
          return zoneName(this._name);
        }
        to_String() {
          return this.name();
        }
      };
      var Duration = class _Duration {
        constructor(seconds = 0, options = {}) {
          defineType(this, "Duration");
          this._years = Number(options.years || 0);
          this._months = Number(options.months || 0);
          this._weeks = Number(options.weeks || 0);
          this._days = Number(options.days || 0);
          this._hours = Number(options.hours || 0);
          this._minutes = Number(options.minutes || 0);
          this._seconds = Number(options.seconds == null ? seconds : options.seconds);
        }
        static seconds(n) {
          return new _Duration(n);
        }
        static minutes(n) {
          return new _Duration(0, { minutes: n });
        }
        static hours(n) {
          return new _Duration(0, { hours: n });
        }
        static days(n) {
          return new _Duration(0, { days: n });
        }
        static weeks(n) {
          return new _Duration(0, { weeks: n });
        }
        static months(n) {
          return new _Duration(0, { months: n });
        }
        static years(n) {
          return new _Duration(0, { years: n });
        }
        years() {
          return this._years;
        }
        months() {
          return this._months;
        }
        weeks() {
          return this._weeks;
        }
        days() {
          return this._days;
        }
        hours() {
          return this._hours;
        }
        minutes() {
          return this._minutes;
        }
        seconds() {
          return this._seconds;
        }
      };
      var TimeFormat = class _TimeFormat {
        constructor(pattern = "", options = {}) {
          defineType(this, "TimeFormat");
          this._kind = options.kind || "strftime";
          this._pattern = pattern == null ? "" : String(pattern);
          this._timezone = options.timezone == null ? null : zoneName(options.timezone);
        }
        static iso8601() {
          return new _TimeFormat("", { kind: "iso8601" });
        }
        static rfc3339() {
          return new _TimeFormat("", { kind: "rfc3339" });
        }
        static rfc5322() {
          return new _TimeFormat("", { kind: "rfc5322" });
        }
        static strftime(pattern, options = {}) {
          return new _TimeFormat(pattern, { kind: "strftime", timezone: options.timezone });
        }
        format(time) {
          return time.format(this);
        }
        parse(text, options = {}) {
          const parsed = parseTimeText(String(text), this._timezone || options.timezone, true);
          return new Time2(parsed.epoch, { timezone: this._timezone || options.timezone || parsed.zone });
        }
      };
      function parseTimeText(text, defaultZone, requireZone) {
        let m = text.match(/^(\d{4})-(\d\d)-(\d\d)(?:[Tt ](\d\d):(\d\d)(?::(\d\d)(?:\.\d+)?)?)?(?:\s*(Z|[+-]\d\d:?\d\d))?$/u);
        if (m) {
          if (requireZone && !m[7] && defaultZone == null) {
            throw new Error("Time.parse() requires a timezone");
          }
          const offset = m[7] ? parseOffset(m[7]) : null;
          if (m[7] && offset == null) {
            throw new Error("invalid time zone");
          }
          const zone = m[7] ? formatOffset(offset, true) : zoneName(defaultZone);
          const year = Number(m[1]);
          const month = Number(m[2]);
          const day = Number(m[3]);
          const hour = Number(m[4] || 0);
          const minute = Number(m[5] || 0);
          const second = Number(m[6] || 0);
          if (hour > 23 || minute > 59 || second > 59) {
            throw new Error("invalid time");
          }
          if (day < 1 || day > daysInMonth(year, month)) {
            throw new Error("invalid date");
          }
          return {
            epoch: sameWallEpoch({
              year,
              month,
              day,
              hour,
              minute,
              second
            }, zone),
            zone
          };
        }
        m = text.match(/^(?:([A-Za-z.]+),\s*)?(\d{1,2})\s+([A-Za-z.]+)\s+(\d{2}|\d{4})\s+(\d{1,2}):(\d\d)(?::(\d\d))?\s+([+-]\d\d:?\d\d|[A-Za-z]{1,5})$/iu);
        if (m) {
          if (m[1] && !WEEKDAY_BY_NAME.has(stripTrailingPeriod(m[1]))) {
            throw new Error("invalid weekday");
          }
          const month = MONTH_BY_NAME.get(stripTrailingPeriod(m[3]));
          if (!month) throw new Error("invalid month");
          let year = Number(m[4]);
          if (String(m[4]).length === 2) {
            year += year >= 50 ? 1900 : 2e3;
          }
          if (year < 1) {
            throw new Error("invalid year");
          }
          const day = Number(m[2]);
          const hour = Number(m[5]);
          const minute = Number(m[6]);
          const second = Number(m[7] || 0);
          if (hour > 23 || minute > 59 || second > 59) {
            throw new Error("invalid time");
          }
          if (day < 1 || day > daysInMonth(year, month)) {
            throw new Error("invalid date");
          }
          const offset = parseRfc5322Zone(m[8]);
          if (offset == null) {
            throw new Error("invalid time zone");
          }
          const zone = formatOffset(offset, true);
          return {
            epoch: sameWallEpoch({
              year,
              month,
              day,
              hour,
              minute,
              second
            }, zone),
            zone
          };
        }
        throw new Error("Error parsing time");
      }
      var Time2 = class _Time {
        constructor(epoch = null, options = {}) {
          defineType(this, "Time");
          this._epoch = epoch == null ? Math.floor(Date.now() / 1e3) : Number(epoch);
          this._timezone = zoneName(options.timezone || "UTC");
        }
        static parse(text, options = {}) {
          const parsed = parseTimeText(String(text), options.timezone, true);
          return new _Time(parsed.epoch, { timezone: options.timezone || parsed.zone });
        }
        _clone(nextEpoch, zone = this._timezone) {
          return new _Time(nextEpoch, { timezone: zone });
        }
        _parts() {
          return partsForEpoch(this._epoch, this._timezone);
        }
        epoch() {
          return this._epoch;
        }
        timezone() {
          return new TimeZone(this._timezone);
        }
        with_timezone(zone) {
          return this._clone(this._epoch, zoneName(zone));
        }
        reinterpret_timezone(zone) {
          return this._clone(sameWallEpoch(this._parts(), zone), zoneName(zone));
        }
        as_utc() {
          return this.with_timezone("UTC");
        }
        as_local() {
          return this.with_timezone("local");
        }
        sec() {
          return this._parts().second;
        }
        min() {
          return this._parts().minute;
        }
        hour() {
          return this._parts().hour;
        }
        day_of_month() {
          return this._parts().day;
        }
        mon() {
          return this._parts().month;
        }
        month() {
          return this.mon();
        }
        year() {
          return this._parts().year;
        }
        add_seconds(n) {
          return this._clone(this._epoch + Number(n));
        }
        add_minutes(n) {
          return this.add_seconds(Number(n) * 60);
        }
        add_hours(n) {
          return this.add_seconds(Number(n) * 3600);
        }
        _calendarAdd(delta) {
          let parts = this._parts();
          if (delta.years) parts = addMonthsToWall(parts, Number(delta.years) * 12);
          if (delta.months) parts = addMonthsToWall(parts, delta.months);
          const dayDelta = Number(delta.days || 0) + Number(delta.weeks || 0) * 7;
          if (dayDelta) {
            const d = new Date(Date.UTC(
              parts.year,
              parts.month - 1,
              parts.day + dayDelta,
              parts.hour,
              parts.minute,
              parts.second
            ));
            parts = {
              year: d.getUTCFullYear(),
              month: d.getUTCMonth() + 1,
              day: d.getUTCDate(),
              hour: d.getUTCHours(),
              minute: d.getUTCMinutes(),
              second: d.getUTCSeconds()
            };
          }
          return this._clone(sameWallEpoch(parts, this._timezone));
        }
        add_days(n) {
          return this._calendarAdd({ days: n });
        }
        add_weeks(n) {
          return this._calendarAdd({ weeks: n });
        }
        add_months(n) {
          return this._calendarAdd({ months: n });
        }
        add_years(n) {
          return this._calendarAdd({ years: n });
        }
        subtract_seconds(n) {
          return this.add_seconds(-Number(n));
        }
        subtract_minutes(n) {
          return this.add_minutes(-Number(n));
        }
        subtract_hours(n) {
          return this.add_hours(-Number(n));
        }
        subtract_days(n) {
          return this.add_days(-Number(n));
        }
        subtract_weeks(n) {
          return this.add_weeks(-Number(n));
        }
        subtract_months(n) {
          return this.add_months(-Number(n));
        }
        subtract_years(n) {
          return this.add_years(-Number(n));
        }
        add(duration) {
          return this.add_seconds(
            Number(duration.seconds()) + Number(duration.minutes()) * 60 + Number(duration.hours()) * 3600
          )._calendarAdd({
            days: duration.days(),
            weeks: duration.weeks(),
            months: duration.months(),
            years: duration.years()
          });
        }
        subtract(duration) {
          return this.add(new Duration(-duration.seconds(), {
            minutes: -duration.minutes(),
            hours: -duration.hours(),
            days: -duration.days(),
            weeks: -duration.weeks(),
            months: -duration.months(),
            years: -duration.years()
          }));
        }
        elapsed_seconds_until(other) {
          return other.epoch() - this._epoch;
        }
        compare(other) {
          return this._epoch < other.epoch() ? -1 : this._epoch > other.epoch() ? 1 : 0;
        }
        is_before(other) {
          return this._epoch < other.epoch();
        }
        is_after(other) {
          return this._epoch > other.epoch();
        }
        datetime() {
          return this.strftime("%Y-%m-%dT%H:%M:%S");
        }
        to_String() {
          return this.datetime();
        }
        to_iso8601() {
          return this.to_rfc3339();
        }
        to_rfc3339() {
          const p = this._parts();
          return `${pad(p.year, 4)}-${pad(p.month)}-${pad(p.day)}T${pad(p.hour)}:${pad(p.minute)}:${pad(p.second)}${formatOffset(offsetForEpoch(this._epoch, this._timezone), true)}`;
        }
        to_rfc5322(options = {}) {
          const p = this._parts();
          const d = new Date(Date.UTC(p.year, p.month - 1, p.day));
          const weekday = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][d.getUTCDay()];
          const core = `${pad(p.day)} ${MONTHS[p.month - 1]} ${pad(p.year, 4)} ${pad(p.hour)}:${pad(p.minute)}:${pad(p.second)} ${formatOffset(offsetForEpoch(this._epoch, this._timezone), false)}`;
          return options.include_weekday === false ? core : `${weekday}, ${core}`;
        }
        format(timeFormat) {
          const time = timeFormat._timezone == null ? this : this.with_timezone(timeFormat._timezone);
          if (timeFormat._kind === "iso8601" || timeFormat._kind === "rfc3339") return time.to_rfc3339();
          if (timeFormat._kind === "rfc5322") return time.to_rfc5322();
          return time.strftime(timeFormat._pattern);
        }
        strftime(fmt) {
          const p = this._parts();
          const offset = offsetForEpoch(this._epoch, this._timezone);
          const parts = {
            Y: pad(p.year, 4),
            m: pad(p.month),
            d: pad(p.day),
            H: pad(p.hour),
            M: pad(p.minute),
            S: pad(p.second),
            z: formatOffset(offset, false),
            Z: this._timezone,
            "%": "%"
          };
          return String(fmt).replace(/%([%YmdHMSzZ])/g, (_match, key) => parts[key]);
        }
      };
      var TimeParser = class {
        constructor(_fmt = "%Y-%m-%d") {
          this._format = String(_fmt);
        }
        parse(text) {
          const m = String(text).match(/(?:[A-Za-z]+\.?\s+)?([0-9]{1,2})(?:st|nd|rd|th)\s+([A-Za-z]{3}),\s+([0-9]{4})/u);
          if (!m) {
            try {
              return new Time2(parseTimeText(String(text), "UTC", false).epoch, { timezone: "UTC" });
            } catch (_err) {
              throw new Error("Exception: unable to parse time string");
            }
          }
          const day = Number(m[1]);
          const mon = MONTH_BY_NAME.get(m[2].toLowerCase());
          const year = Number(m[3]);
          if (!mon) {
            throw new Error("Exception: unable to parse month");
          }
          return new Time2(sameWallEpoch({
            year,
            month: mon,
            day,
            hour: 0,
            minute: 0,
            second: 0
          }, "UTC"), { timezone: "UTC" });
        }
      };
      module2.exports = {
        Time: Time2,
        TimeZone,
        Duration,
        TimeFormat,
        TimeParser
      };
    }
  });

  // modules/std/marshal/cbor.js
  var require_cbor = __commonJS({
    "modules/std/marshal/cbor.js"(exports2, module2) {
      "use strict";
      var { BinaryString: BinaryString2, ZuzuBinary } = require_runtime_helpers();
      var MAX_SAFE_INTEGER = 9007199254740991;
      var SELF_DESCRIBED_TAG = 55799;
      var PUSH_BYTES_CHUNK = 16384;
      var CborTextString = class {
        constructor(value) {
          this.value = String(value ?? "");
        }
      };
      var CborByteString = class {
        constructor(value) {
          this.value = toUint8Array(value);
        }
      };
      var CborTagged = class {
        constructor(tagNumberValue, value) {
          this.tagNumber = Number(tagNumberValue);
          this.value = value;
        }
      };
      function textString(value) {
        return new CborTextString(value);
      }
      function byteString(value) {
        return new CborByteString(value);
      }
      function tag(tagNumberValue, value) {
        return new CborTagged(tagNumberValue, value);
      }
      function isTextString(value) {
        return value instanceof CborTextString;
      }
      function isByteString(value) {
        return value instanceof CborByteString;
      }
      function isTagged(value) {
        return value instanceof CborTagged;
      }
      function textValue(value) {
        if (!isTextString(value)) {
          throw new Error("Not a CBOR text string");
        }
        return value.value;
      }
      function bytesValue(value) {
        if (!isByteString(value)) {
          throw new Error("Not a CBOR byte string");
        }
        return new Uint8Array(value.value);
      }
      function tagNumber(value) {
        if (!isTagged(value)) {
          throw new Error("Not a CBOR tag");
        }
        return value.tagNumber;
      }
      function tagValue(value) {
        if (!isTagged(value)) {
          throw new Error("Not a CBOR tag");
        }
        return value.value;
      }
      function encodeOne(item) {
        const out = [];
        encodeItem(item, out);
        return new BinaryString2(Uint8Array.from(out));
      }
      function decodeOne(input) {
        const bytes = toUint8Array(input);
        const decoded = decodeItem(bytes, 0, true);
        if (decoded.offset !== bytes.length) {
          throw cborError("trailing bytes after item");
        }
        return decoded.value;
      }
      function validateProfile(input) {
        const bytes = toUint8Array(input);
        const offset = scanItem(bytes, 0, true);
        if (offset !== bytes.length) {
          throw cborError("trailing bytes after item");
        }
        return true;
      }
      function encodeItem(item, out) {
        if (item == null) {
          out.push(246);
          return;
        }
        if (item === false) {
          out.push(244);
          return;
        }
        if (item === true) {
          out.push(245);
          return;
        }
        if (typeof item === "number") {
          encodeNumber(item, out);
          return;
        }
        if (typeof item === "string" || item instanceof CborTextString) {
          const text = item instanceof CborTextString ? item.value : item;
          const bytes = new TextEncoder().encode(text);
          encodeUnsigned(3, bytes.length, out);
          pushBytes(out, bytes);
          return;
        }
        if (item instanceof CborByteString) {
          encodeUnsigned(2, item.value.length, out);
          pushBytes(out, item.value);
          return;
        }
        if (item instanceof CborTagged) {
          if (item.tagNumber !== SELF_DESCRIBED_TAG) {
            throw cborError(`unsupported tag ${item.tagNumber}`);
          }
          encodeUnsigned(6, item.tagNumber, out);
          encodeItem(item.value, out);
          return;
        }
        if (item instanceof Uint8Array || item instanceof ZuzuBinary) {
          const bytes = toUint8Array(item);
          encodeUnsigned(2, bytes.length, out);
          pushBytes(out, bytes);
          return;
        }
        if (Array.isArray(item)) {
          encodeUnsigned(4, item.length, out);
          for (const value of item) {
            encodeItem(value, out);
          }
          return;
        }
        if (item instanceof Map) {
          encodeUnsigned(5, item.size, out);
          for (const [key, value] of item.entries()) {
            encodeItem(key, out);
            encodeItem(value, out);
          }
          return;
        }
        if (typeof item === "object") {
          const entries = Object.entries(item);
          encodeUnsigned(5, entries.length, out);
          for (const [key, value] of entries) {
            encodeItem(new CborTextString(key), out);
            encodeItem(value, out);
          }
          return;
        }
        throw cborError(`unsupported value type ${typeof item}`);
      }
      function encodeNumber(value, out) {
        if (!Number.isFinite(value)) {
          throw cborError(Number.isNaN(value) ? "NaN is invalid" : "infinite float is invalid");
        }
        if (!Object.is(value, -0) && Number.isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER) {
          if (value >= 0) {
            encodeUnsigned(0, value, out);
          } else {
            encodeUnsigned(1, -1 - value, out);
          }
          return;
        }
        out.push(251);
        const buffer = new ArrayBuffer(8);
        new DataView(buffer).setFloat64(0, value, false);
        pushBytes(out, new Uint8Array(buffer));
      }
      function encodeUnsigned(major, value, out) {
        if (!Number.isSafeInteger(value) || value < 0) {
          throw cborError("integer is outside supported range");
        }
        const prefix = major << 5;
        if (value <= 23) {
          out.push(prefix | value);
        } else if (value <= 255) {
          out.push(prefix | 24, value);
        } else if (value <= 65535) {
          out.push(prefix | 25, value >> 8, value & 255);
        } else if (value <= 4294967295) {
          out.push(
            prefix | 26,
            value >>> 24 & 255,
            value >>> 16 & 255,
            value >>> 8 & 255,
            value & 255
          );
        } else {
          out.push(prefix | 27);
          const high = Math.floor(value / 4294967296);
          const low = value >>> 0;
          out.push(
            high >>> 24 & 255,
            high >>> 16 & 255,
            high >>> 8 & 255,
            high & 255,
            low >>> 24 & 255,
            low >>> 16 & 255,
            low >>> 8 & 255,
            low & 255
          );
        }
      }
      function decodeItem(bytes, offset, topLevel) {
        requireAvailable(bytes, offset, 1, "initial byte");
        const initial = bytes[offset];
        const major = initial >> 5;
        const ai = initial & 31;
        offset++;
        if (ai === 31) {
          throw cborError("indefinite-length item");
        }
        if (ai >= 28 && ai <= 30) {
          throw cborError("reserved additional information");
        }
        if (major === 7) {
          return decodeSimpleOrFloat(bytes, offset, ai);
        }
        const argument = readArgument(bytes, offset, ai);
        const value = argument.value;
        offset = argument.offset;
        switch (major) {
          case 0:
            assertUnsignedNumberRange(value);
            return { value, offset };
          case 1:
            assertNegativeNumberRange(value);
            return { value: -1 - value, offset };
          case 2:
            requireAvailable(bytes, offset, value, "byte string payload");
            return {
              value: new CborByteString(bytes.subarray(offset, offset + value)),
              offset: offset + value
            };
          case 3: {
            requireAvailable(bytes, offset, value, "text string payload");
            const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(offset, offset + value));
            return { value: new CborTextString(text), offset: offset + value };
          }
          case 4: {
            const values = [];
            for (let i = 0; i < value; i++) {
              const item = decodeItem(bytes, offset, false);
              values.push(item.value);
              offset = item.offset;
            }
            return { value: values, offset };
          }
          case 5: {
            const map = /* @__PURE__ */ new Map();
            for (let i = 0; i < value; i++) {
              const key = decodeItem(bytes, offset, false);
              const mapValue = decodeItem(bytes, key.offset, false);
              map.set(key.value, mapValue.value);
              offset = mapValue.offset;
            }
            return { value: map, offset };
          }
          case 6: {
            if (!topLevel || value !== SELF_DESCRIBED_TAG) {
              throw cborError(`unsupported tag ${value}`);
            }
            const inner = decodeItem(bytes, offset, false);
            return {
              value: new CborTagged(value, inner.value),
              offset: inner.offset
            };
          }
          default:
            throw cborError("unsupported major type");
        }
      }
      function scanItem(bytes, offset, topLevel) {
        return decodeItem(bytes, offset, topLevel).offset;
      }
      function decodeSimpleOrFloat(bytes, offset, ai) {
        if (ai === 20) {
          return { value: false, offset };
        }
        if (ai === 21) {
          return { value: true, offset };
        }
        if (ai === 22) {
          return { value: null, offset };
        }
        if (ai === 25) {
          throw cborError("half-precision float is invalid");
        }
        if (ai === 26) {
          throw cborError("single-precision float is invalid");
        }
        if (ai === 27) {
          requireAvailable(bytes, offset, 8, "binary64 float");
          const value = new DataView(
            bytes.buffer,
            bytes.byteOffset + offset,
            8
          ).getFloat64(0, false);
          if (Number.isNaN(value)) {
            throw cborError("NaN is invalid");
          }
          if (!Number.isFinite(value)) {
            throw cborError("infinite float is invalid");
          }
          return { value, offset: offset + 8 };
        }
        throw cborError("unsupported simple value");
      }
      function readArgument(bytes, offset, ai) {
        if (ai <= 23) {
          return { value: ai, offset };
        }
        if (ai === 24) {
          requireAvailable(bytes, offset, 1, "uint8 argument");
          const value = bytes[offset];
          assertShortestArgument(value, 24);
          return { value, offset: offset + 1 };
        }
        if (ai === 25) {
          requireAvailable(bytes, offset, 2, "uint16 argument");
          const value = bytes[offset] << 8 | bytes[offset + 1];
          assertShortestArgument(value, 256);
          return { value, offset: offset + 2 };
        }
        if (ai === 26) {
          requireAvailable(bytes, offset, 4, "uint32 argument");
          const value = bytes[offset] * 16777216 + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3];
          assertShortestArgument(value, 65536);
          return { value, offset: offset + 4 };
        }
        if (ai === 27) {
          requireAvailable(bytes, offset, 8, "uint64 argument");
          const high = bytes[offset] * 16777216 + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3];
          const low = bytes[offset + 4] * 16777216 + (bytes[offset + 5] << 16) + (bytes[offset + 6] << 8) + bytes[offset + 7];
          const value = high * 4294967296 + low;
          assertShortestArgument(value, 4294967296);
          return { value, offset: offset + 8 };
        }
        throw cborError("unsupported additional information");
      }
      function assertShortestArgument(value, minimum) {
        if (value < minimum) {
          throw cborError("non-shortest integer encoding");
        }
      }
      function assertUnsignedNumberRange(value) {
        if (value > MAX_SAFE_INTEGER) {
          throw cborError("integer is outside Zuzu Number range");
        }
      }
      function assertNegativeNumberRange(value) {
        if (value >= MAX_SAFE_INTEGER) {
          throw cborError("integer is outside Zuzu Number range");
        }
      }
      function requireAvailable(bytes, offset, length, context) {
        if (offset + length > bytes.length) {
          throw cborError(`incomplete ${context}`);
        }
      }
      function pushBytes(out, bytes) {
        for (let offset = 0; offset < bytes.length; offset += PUSH_BYTES_CHUNK) {
          out.push(...bytes.subarray(offset, offset + PUSH_BYTES_CHUNK));
        }
      }
      function toUint8Array(value) {
        if (value instanceof ZuzuBinary) {
          return new Uint8Array(value.bytes);
        }
        if (value instanceof Uint8Array) {
          return new Uint8Array(value);
        }
        if (Array.isArray(value)) {
          return Uint8Array.from(value.map((item) => Number(item) & 255));
        }
        if (value && value.buffer instanceof ArrayBuffer) {
          return new Uint8Array(value.buffer, value.byteOffset || 0, value.byteLength);
        }
        throw new Error("TypeException: CBOR adapter expects BinaryString or Uint8Array bytes");
      }
      function cborError(message) {
        return new Error(`CBOR profile error: ${message}`);
      }
      module2.exports = {
        CborTextString,
        CborByteString,
        CborTagged,
        SELF_DESCRIBED_TAG,
        byteString,
        bytesValue,
        decodeOne,
        encodeOne,
        isByteString,
        isTagged,
        isTextString,
        tag,
        tagNumber,
        tagValue,
        textString,
        textValue,
        validateProfile
      };
    }
  });

  // lib/gui/dom-renderer.js
  var require_dom_renderer = __commonJS({
    "lib/gui/dom-renderer.js"(exports2, module2) {
      "use strict";
      function installSafeDefineProperties() {
        if (Object.__zuzu_safe_define_properties) {
          return;
        }
        const nativeDefineProperty = Object.defineProperty;
        const nativeDefineProperties = Object.defineProperties;
        function safeDescriptor(descriptor) {
          if (!descriptor || typeof descriptor !== "object") {
            return descriptor;
          }
          const safe = /* @__PURE__ */ Object.create(null);
          for (const key of [
            "value",
            "get",
            "set",
            "writable",
            "enumerable",
            "configurable"
          ]) {
            if (Object.prototype.hasOwnProperty.call(descriptor, key)) {
              safe[key] = descriptor[key];
            }
          }
          return safe;
        }
        Object.defineProperty = function zuzuSafeDefineProperty(obj, prop, descriptor) {
          return nativeDefineProperty(obj, prop, safeDescriptor(descriptor));
        };
        Object.defineProperties = function zuzuSafeDefineProperties(obj, descriptors) {
          const safe = /* @__PURE__ */ Object.create(null);
          for (const key of Object.keys(descriptors || {})) {
            safe[key] = safeDescriptor(descriptors[key]);
          }
          return nativeDefineProperties(obj, safe);
        };
        nativeDefineProperty(Object, "__zuzu_safe_define_properties", {
          value: true,
          enumerable: false,
          configurable: false
        });
      }
      var activeState = null;
      function rendererState() {
        if (!activeState) {
          throw new Error("Zuzu GUI DOM renderer is not active");
        }
        return activeState;
      }
      function rendererDocument() {
        const state = rendererState();
        return state.document || document;
      }
      function itemLabel(item) {
        if (item == null) {
          return "";
        }
        if (typeof item === "string" || typeof item === "number") {
          return String(item);
        }
        return String(item.label ?? item.value ?? "");
      }
      function itemValue(item) {
        if (item == null) {
          return "";
        }
        if (typeof item === "string" || typeof item === "number") {
          return String(item);
        }
        return item.value ?? itemLabel(item);
      }
      function itemChildren(item) {
        return Array.isArray(item && item.children) ? item.children : [];
      }
      function pathKey(path) {
        return Array.isArray(path) ? path.map(Number).join(",") : "";
      }
      function sendWidgetEvent(type, node, extra = {}) {
        const state = node.__zuzuRendererState || rendererState();
        if (state.sendEvent) {
          state.sendEvent({
            windowId: state.windowId,
            type,
            widgetGuid: node.dataset.guid || null,
            ...extra
          });
          return;
        }
        if (!window.zuzuGui) {
          return;
        }
        window.zuzuGui.sendEvent({
          windowId: state.windowId,
          type,
          widgetGuid: node.dataset.guid || null,
          ...extra
        });
      }
      function sendThrottledWidgetEvent(type, node, extraFactory) {
        if (node.__zuzuPendingEvent) {
          node.__zuzuPendingEvent.extraFactory = extraFactory;
          return;
        }
        node.__zuzuPendingEvent = { extraFactory };
        setTimeout(() => {
          const pending = node.__zuzuPendingEvent;
          node.__zuzuPendingEvent = null;
          sendWidgetEvent(type, node, pending.extraFactory());
        }, 50);
      }
      function applyCommonProps(element, snapshot) {
        const props = snapshot.props || {};
        element.dataset.guid = snapshot.guid || "";
        element.hidden = props.visible === false;
        element.className = "";
        if (snapshot.classes && snapshot.classes.length > 0) {
          element.classList.add(...snapshot.classes);
        }
        if (snapshot.id) {
          element.id = snapshot.id;
        } else {
          element.removeAttribute("id");
        }
        if (props.disabled) {
          element.setAttribute("aria-disabled", "true");
          if ("disabled" in element) {
            element.disabled = true;
          }
        } else {
          element.removeAttribute("aria-disabled");
          if ("disabled" in element) {
            element.disabled = false;
          }
        }
        for (const [key, cssName] of [
          ["width", "width"],
          ["height", "height"],
          ["minwidth", "minWidth"],
          ["minheight", "minHeight"],
          ["maxwidth", "maxWidth"],
          ["maxheight", "maxHeight"]
        ]) {
          if (props[key] != null && props[key] !== "") {
            element.style[cssName] = `${Number(props[key]) || 0}px`;
          } else {
            element.style[cssName] = "";
          }
        }
      }
      function applyBoxStyle(element, snapshot) {
        const props = snapshot.props || {};
        element.classList.add(snapshot.type === "HBox" ? "zuzu-hbox" : "zuzu-vbox");
        element.style.display = "flex";
        element.style.flexDirection = snapshot.type === "HBox" ? "row" : "column";
        if (props.gap != null) {
          element.style.gap = `${Number(props.gap) || 0}px`;
        }
        if (props.padding != null) {
          element.style.padding = `${Number(props.padding) || 0}px`;
        }
      }
      function applySpecificProps(element, snapshot) {
        const type = snapshot.type || "Widget";
        const props = snapshot.props || {};
        if (type === "Window") {
          return;
        }
        if (type === "Frame") {
          let legend = element.querySelector(":scope > legend");
          if (!legend) {
            legend = rendererDocument().createElement("legend");
            element.prepend(legend);
          }
          legend.textContent = props.label || "";
          element.classList.toggle("zuzu-collapsed", props.collapsed === true);
          return;
        }
        if (type === "VBox" || type === "HBox") {
          applyBoxStyle(element, snapshot);
          return;
        }
        if (type === "Label") {
          element.textContent = props.text || "";
          if (props.for_id) {
            element.htmlFor = props.for_id;
          }
          return;
        }
        if (type === "Text") {
          element.textContent = props.text || props.value || "";
          element.style.whiteSpace = props.wrap === false ? "pre" : "pre-wrap";
          return;
        }
        if (type === "RichText") {
          element.innerHTML = props.value || "";
          return;
        }
        if (type === "Image") {
          element.src = props.src || "";
          element.alt = props.alt || "";
          element.style.objectFit = props.fit === "stretch" ? "fill" : props.fit || "contain";
          return;
        }
        if (type === "Input") {
          setInputValue(element, props.value || "");
          element.placeholder = props.placeholder || "";
          element.readOnly = props.readonly === true;
          element.required = props.required === true;
          if ("type" in element) {
            element.type = props.password ? "password" : "text";
          }
          return;
        }
        if (type === "DatePicker") {
          setInputValue(element, props.value || "");
          element.placeholder = "YYYY-MM-DD";
          element.pattern = "\\d{4}-\\d{2}-\\d{2}";
          element.dataset.min = props.min || "";
          element.dataset.max = props.max || "";
          return;
        }
        if (type === "Checkbox" || type === "Radio") {
          const input = element.querySelector("input");
          const label = element.querySelector("span");
          input.checked = props.checked === true;
          input.indeterminate = props.indeterminate === true;
          input.value = props.value || "";
          input.name = props.name || props.group || "";
          label.textContent = props.label || "";
          return;
        }
        if (type === "RadioGroup") {
          const radios = element.querySelectorAll(':scope input[type="radio"]');
          for (const radio of radios) {
            radio.name = snapshot.guid || "";
          }
          return;
        }
        if (type === "Select") {
          renderSelectOptions(element, props);
          element.value = props.value == null ? "" : String(props.value);
          element.multiple = props.multiple === true;
          return;
        }
        if (type === "Separator") {
          element.classList.toggle("zuzu-vertical-separator", props.orientation === "vertical");
          return;
        }
        if (type === "Slider") {
          setInputValue(element, props.value ?? 0);
          element.min = props.min ?? 0;
          element.max = props.max ?? 100;
          element.step = props.step ?? 1;
          element.disabled = props.disabled === true || props.readonly === true;
          return;
        }
        if (type === "Progress") {
          element.value = Number(props.value ?? 0);
          element.max = Number(props.max ?? 100);
          element.classList.toggle("zuzu-indeterminate", props.indeterminate === true);
          element.title = props.show_text ? `${element.value} / ${element.max}` : "";
          return;
        }
        if (type === "Tabs") {
          element.dataset.selected = props.selected || "";
          for (const child of Array.from(element.children)) {
            if (child.__zuzuGuiType === "Tab") {
              child.open = child.dataset.value === element.dataset.selected;
            }
          }
          return;
        }
        if (type === "Tab") {
          element.open = props.selected === true;
          element.dataset.value = props.value || "";
          element.querySelector("summary").textContent = props.title || props.value || "";
          return;
        }
        if (type === "ListView") {
          renderListView(element, props);
          return;
        }
        if (type === "TreeView") {
          renderTreeView(element, props);
          return;
        }
        if (type === "Menu") {
          let label = element.__zuzuMenuLabel;
          if (!label) {
            label = rendererDocument().createElement("span");
            label.className = "zuzu-menu-label";
            label.__zuzuRendererState = rendererState();
            element.__zuzuMenuLabel = label;
            element.insertBefore(label, element.children[0] || null);
          }
          label.textContent = props.text || "";
          return;
        }
        if (type === "Button" || type === "MenuItem") {
          element.textContent = props.text || "";
        }
      }
      function setInputValue(element, value) {
        const text = String(value ?? "");
        if (element.value === text) {
          return;
        }
        const focused = rendererDocument().activeElement === element;
        const selectionStart = focused ? element.selectionStart : null;
        const selectionEnd = focused ? element.selectionEnd : null;
        element.value = text;
        if (focused && typeof element.setSelectionRange === "function" && selectionStart != null && selectionEnd != null) {
          const start = Math.min(selectionStart, text.length);
          const end = Math.min(selectionEnd, text.length);
          element.setSelectionRange(start, end);
        }
      }
      function createElement(snapshot) {
        const type = snapshot.type || "Widget";
        let element;
        if (type === "Window") {
          element = rendererDocument().createElement("main");
        } else if (type === "Frame") {
          element = rendererDocument().createElement("fieldset");
        } else if (type === "VBox" || type === "HBox") {
          element = rendererDocument().createElement("div");
        } else if (type === "Label") {
          element = rendererDocument().createElement("label");
        } else if (type === "Text" || type === "RichText") {
          element = rendererDocument().createElement("div");
          element.addEventListener("click", () => {
            sendWidgetEvent("click", element);
          });
        } else if (type === "Image") {
          element = rendererDocument().createElement("img");
          element.addEventListener("click", () => {
            sendWidgetEvent("click", element);
          });
        } else if (type === "Input") {
          element = snapshot.props && snapshot.props.multiline ? rendererDocument().createElement("textarea") : rendererDocument().createElement("input");
          element.addEventListener("input", () => {
            sendWidgetEvent("input", element, { value: element.value });
          });
          element.addEventListener("change", () => {
            sendWidgetEvent("change", element, { value: element.value });
          });
        } else if (type === "DatePicker") {
          element = rendererDocument().createElement("input");
          element.type = "text";
          element.inputMode = "numeric";
          element.autocomplete = "off";
          element.addEventListener("input", () => {
            sendWidgetEvent("input", element, { value: element.value });
          });
          element.addEventListener("change", () => {
            sendWidgetEvent("change", element, { value: element.value });
          });
        } else if (type === "Checkbox" || type === "Radio") {
          element = rendererDocument().createElement("label");
          element.className = "zuzu-check-control";
          const input = rendererDocument().createElement("input");
          input.type = type === "Radio" ? "radio" : "checkbox";
          const label = rendererDocument().createElement("span");
          element.append(input, label);
          input.addEventListener("change", () => {
            const eventTarget = type === "Radio" && element.dataset.parentGuid ? element.dataset.parentGuid : element.dataset.guid;
            sendWidgetEvent("change", element, {
              widgetGuid: eventTarget,
              checked: input.checked,
              value: input.value
            });
          });
        } else if (type === "Select") {
          element = rendererDocument().createElement("select");
          element.addEventListener("change", () => {
            sendWidgetEvent("change", element, { value: element.value });
          });
        } else if (type === "Button" || type === "MenuItem") {
          element = rendererDocument().createElement("button");
          element.type = "button";
          element.addEventListener("click", () => {
            sendWidgetEvent("click", element);
          });
        } else if (type === "Menu") {
          element = rendererDocument().createElement("nav");
        } else if (type === "Separator") {
          element = rendererDocument().createElement("hr");
        } else if (type === "Slider") {
          element = rendererDocument().createElement("input");
          element.type = "range";
          element.addEventListener("input", () => {
            sendThrottledWidgetEvent("input", element, () => ({
              value: Number(element.value)
            }));
          });
          element.addEventListener("change", () => {
            sendWidgetEvent("change", element, { value: Number(element.value) });
          });
        } else if (type === "Progress") {
          element = rendererDocument().createElement("progress");
        } else if (type === "Tabs") {
          element = rendererDocument().createElement("div");
          element.className = "zuzu-tabs";
        } else if (type === "Tab") {
          element = rendererDocument().createElement("details");
          const summary = rendererDocument().createElement("summary");
          element.appendChild(summary);
          summary.addEventListener("click", (event) => {
            event.preventDefault();
            const parent = element.parentNode;
            if (parent) {
              for (const child of Array.from(parent.children)) {
                if (child.__zuzuGuiType === "Tab") {
                  child.open = child === element;
                }
              }
            }
            element.open = true;
            sendWidgetEvent("select", element, {
              widgetGuid: element.dataset.parentGuid || element.dataset.guid,
              selected: element.dataset.value || "",
              value: element.dataset.value || ""
            });
          });
        } else if (type === "ListView" || type === "TreeView") {
          element = rendererDocument().createElement("div");
          element.tabIndex = 0;
        } else {
          element = rendererDocument().createElement("div");
        }
        element.__zuzuRendererState = rendererState();
        element.__zuzuGuiType = type;
        element.__zuzuGuiSubType = type === "Input" && snapshot.props && snapshot.props.multiline ? "multiline" : "";
        return element;
      }
      function renderNode(snapshot) {
        const element = createElement(snapshot);
        applyCommonProps(element, snapshot);
        applySpecificProps(element, snapshot);
        rendererState().nodes.set(snapshot.guid, element);
        for (const child of snapshot.children || []) {
          if (snapshot.type === "Window" && child.type === "Menu" && !rendererState().renderMenus) {
            continue;
          }
          const childElement = renderNode(child);
          childElement.dataset.parentGuid = snapshot.guid || "";
          if (snapshot.type === "RadioGroup" && child.type === "Radio") {
            const radio = childElement.querySelector('input[type="radio"]');
            if (radio) {
              radio.name = snapshot.guid || "";
            }
          }
          element.appendChild(childElement);
        }
        return element;
      }
      function renderSelectOptions(element, props) {
        element.replaceChildren();
        for (const item of props.options || []) {
          const option = rendererDocument().createElement("option");
          option.textContent = itemLabel(item);
          option.value = String(itemValue(item));
          option.disabled = item && item.disabled === true;
          element.appendChild(option);
        }
      }
      function renderListView(element, props) {
        element.classList.add("zuzu-listview");
        element.replaceChildren();
        const list = rendererDocument().createElement("ul");
        const selected = props.selected_index == null ? null : Number(props.selected_index);
        (props.items || []).forEach((item, index) => {
          const row = rendererDocument().createElement("li");
          row.textContent = itemLabel(item);
          row.dataset.index = String(index);
          row.classList.toggle("selected", index === selected);
          row.addEventListener("click", () => {
            markListSelected(element, index);
            sendWidgetEvent("select", element, { selected_index: index });
          });
          row.addEventListener("dblclick", () => {
            markListSelected(element, index);
            sendWidgetEvent("activate", element, { selected_index: index });
          });
          list.appendChild(row);
        });
        element.appendChild(list);
      }
      function markListSelected(element, index) {
        for (const row of element.querySelectorAll("li")) {
          row.classList.toggle("selected", Number(row.dataset.index) === Number(index));
        }
      }
      function renderTreeView(element, props) {
        element.classList.add("zuzu-treeview");
        element.replaceChildren();
        const selected = pathKey(props.selected_path || []);
        const expanded = new Set((props.expanded_paths || []).map(pathKey));
        element.appendChild(renderTreeItems(props.items || [], [], selected, expanded, element));
      }
      function renderTreeItems(items, prefix, selected, expanded, owner) {
        const list = rendererDocument().createElement("ul");
        items.forEach((item, index) => {
          const path = [...prefix, index];
          const key = pathKey(path);
          const children = itemChildren(item);
          const row = rendererDocument().createElement("li");
          if (children.length > 0) {
            const details = rendererDocument().createElement("details");
            details.open = expanded.has(key);
            const summary = rendererDocument().createElement("summary");
            summary.textContent = itemLabel(item);
            summary.dataset.path = key;
            summary.classList.toggle("selected", key === selected);
            summary.addEventListener("click", () => {
              markTreeSelected(owner, key);
              sendWidgetEvent("select", owner, { selected_path: path });
            });
            summary.addEventListener("dblclick", () => {
              markTreeSelected(owner, key);
              sendWidgetEvent("activate", owner, { selected_path: path });
            });
            details.addEventListener("toggle", () => {
              sendWidgetEvent(details.open ? "expand" : "collapse", owner, {
                selected_path: path
              });
            });
            details.append(summary, renderTreeItems(children, path, selected, expanded, owner));
            row.appendChild(details);
          } else {
            const button = rendererDocument().createElement("button");
            button.type = "button";
            button.textContent = itemLabel(item);
            button.dataset.path = key;
            button.classList.toggle("selected", key === selected);
            button.addEventListener("click", () => {
              markTreeSelected(owner, key);
              sendWidgetEvent("select", owner, { selected_path: path });
            });
            button.addEventListener("dblclick", () => {
              markTreeSelected(owner, key);
              sendWidgetEvent("activate", owner, { selected_path: path });
            });
            row.appendChild(button);
          }
          list.appendChild(row);
        });
        return list;
      }
      function markTreeSelected(element, key) {
        for (const node of element.querySelectorAll("[data-path]")) {
          node.classList.toggle("selected", node.dataset.path === key);
        }
      }
      function replaceNode(snapshot) {
        const old = rendererState().nodes.get(snapshot.guid);
        if (!old) {
          return;
        }
        const parent = old.parentNode;
        const next = renderNode(snapshot);
        forgetNode(old);
        parent.replaceChild(next, old);
      }
      function forgetNode(node) {
        const guid = node && node.dataset ? node.dataset.guid : null;
        if (guid) {
          rendererState().nodes.delete(guid);
        }
        for (const child of Array.from(node.children || [])) {
          forgetNode(child);
        }
      }
      function updateNode(snapshot) {
        const element = rendererState().nodes.get(snapshot.guid);
        if (!element) {
          return;
        }
        if (element.__zuzuGuiType !== (snapshot.type || "Widget")) {
          replaceNode(snapshot);
          return;
        }
        if (element.__zuzuGuiType === "Input" && element.__zuzuGuiSubType !== (snapshot.props && snapshot.props.multiline ? "multiline" : "")) {
          replaceNode(snapshot);
          return;
        }
        applyCommonProps(element, snapshot);
        applySpecificProps(element, snapshot);
      }
      function createZuzuGuiDomRenderer(options = {}) {
        installSafeDefineProperties();
        const doc = options.document || options.root && options.root.ownerDocument || document;
        const root = options.root || doc.getElementById(options.rootId || "app");
        if (!root) {
          throw new Error("Zuzu GUI DOM renderer requires a root element");
        }
        const state = {
          document: doc,
          windowId: null,
          nodes: /* @__PURE__ */ new Map(),
          root,
          sendEvent: typeof options.sendEvent === "function" ? options.sendEvent : null,
          renderMenus: options.renderMenus === true
        };
        function withState(fn2) {
          const previous = activeState;
          activeState = state;
          try {
            return fn2();
          } finally {
            activeState = previous;
          }
        }
        return {
          render(payload = {}) {
            return withState(() => {
              state.windowId = payload.windowId;
              state.nodes.clear();
              root.replaceChildren(renderNode(payload.snapshot));
            });
          },
          create(payload = {}) {
            return withState(() => {
              if (payload.snapshot && payload.snapshot.type === "Menu" && !state.renderMenus) {
                return;
              }
              const parent = state.nodes.get(payload.parentGuid);
              if (!parent) {
                return;
              }
              const node = renderNode(payload.snapshot);
              const index = Number.isInteger(payload.index) ? payload.index : null;
              if (index == null || index >= parent.children.length) {
                parent.appendChild(node);
              } else {
                parent.insertBefore(node, parent.children[index]);
              }
            });
          },
          update(payload = {}) {
            return withState(() => {
              if (!payload.snapshot) {
                return;
              }
              if ((payload.snapshot.type === "Menu" || payload.snapshot.type === "MenuItem") && !state.renderMenus) {
                return;
              }
              updateNode(payload.snapshot);
            });
          },
          destroy(payload = {}) {
            return withState(() => {
              const node = state.nodes.get(payload.widgetGuid);
              if (node && node.parentNode) {
                node.parentNode.removeChild(node);
              }
              if (node) {
                forgetNode(node);
              }
            });
          },
          nodeForGuid(guid) {
            return state.nodes.get(guid) || null;
          }
        };
      }
      if (typeof module2 !== "undefined" && module2.exports) {
        module2.exports = {
          createZuzuGuiDomRenderer
        };
      }
      if (typeof window !== "undefined") {
        window.ZuzuGuiDomRenderer = {
          createZuzuGuiDomRenderer
        };
      }
    }
  });

  // lib/browser-gui-renderer.js
  var require_browser_gui_renderer = __commonJS({
    "lib/browser-gui-renderer.js"(exports2, module2) {
      "use strict";
      var {
        createZuzuGuiDomRenderer
      } = require_dom_renderer();
      var DEFAULT_ROOT_ID = "zuzu-browser-gui";
      var STYLE_ID = "zuzu-browser-gui-style";
      function createBrowserGuiRenderer(options = {}) {
        return createZuzuGuiDomRenderer({
          document: options.document,
          root: options.root,
          rootId: options.rootId,
          renderMenus: options.renderMenus,
          sendEvent: options.sendEvent
        });
      }
      function browserDocument(options) {
        if (options.document) {
          return options.document;
        }
        if (typeof document !== "undefined") {
          return document;
        }
        throw new Error("Zuzu browser GUI requires a DOM document");
      }
      function resolveRoot(doc, options) {
        if (options.root) {
          return options.root;
        }
        const rootId = options.rootId || DEFAULT_ROOT_ID;
        let root = doc.getElementById ? doc.getElementById(rootId) : null;
        if (root) {
          return root;
        }
        root = doc.createElement("div");
        root.id = rootId;
        root.className = "zuzu-browser-gui-root";
        const parent = doc.body || doc.documentElement;
        if (!parent) {
          throw new Error("Zuzu browser GUI requires document.body");
        }
        parent.appendChild(root);
        return root;
      }
      function installStyles(doc) {
        if (!doc.createElement || !doc.head) {
          return;
        }
        if (doc.getElementById && doc.getElementById(STYLE_ID)) {
          return;
        }
        const style = doc.createElement("style");
        style.id = STYLE_ID;
        style.textContent = [
          ".zuzu-browser-gui-root{position:fixed;inset:0;pointer-events:none;",
          "z-index:2147480000;font:13px/1.4 system-ui,sans-serif;color:#202124;}",
          ".zuzu-browser-window{position:absolute;display:flex;flex-direction:column;",
          "min-width:220px;min-height:120px;background:#fff;border:1px solid #8c939f;",
          "box-shadow:0 12px 36px rgba(0,0,0,.22);pointer-events:auto;}",
          ".zuzu-browser-window-titlebar{display:flex;align-items:center;gap:8px;",
          "height:32px;padding:0 6px 0 10px;background:#e9edf3;border-bottom:1px solid #c8ced8;",
          "user-select:none;cursor:default;}",
          ".zuzu-browser-window-title{flex:1;overflow:hidden;text-overflow:ellipsis;",
          "white-space:nowrap;font-weight:600;}",
          ".zuzu-browser-window-close{width:24px;height:24px;border:0;background:transparent;",
          "font:16px/1 system-ui,sans-serif;cursor:pointer;}",
          ".zuzu-browser-window-close:hover{background:#d8dde6;}",
          ".zuzu-browser-window-content{flex:1;min-height:0;overflow:auto;padding:12px;}",
          ".zuzu-browser-window-content>main{display:flex;flex-direction:column;gap:8px;}",
          ".zuzu-browser-window nav{display:flex;gap:4px;padding:4px 8px;",
          "border-bottom:1px solid #d7dbe2;background:#f7f8fa;}",
          ".zuzu-browser-window .zuzu-menu-label{padding:4px 8px;font-weight:600;}",
          ".zuzu-browser-window nav button{border:1px solid transparent;background:transparent;",
          "padding:4px 8px;cursor:pointer;}",
          ".zuzu-browser-window nav button:hover{border-color:#c4c9d2;background:#fff;}"
        ].join("");
        doc.head.appendChild(style);
      }
      function snapshotTitle(snapshot) {
        const props = snapshot && snapshot.props ? snapshot.props : {};
        return String(props.title || "Zuzu Window");
      }
      function snapshotDimension(snapshot, name2, fallback) {
        const props = snapshot && snapshot.props ? snapshot.props : {};
        const value = Number(props[name2]);
        return Number.isFinite(value) && value > 0 ? value : fallback;
      }
      var WINDOW_FRAME_PROPS = /* @__PURE__ */ new Set([
        "height",
        "maxheight",
        "maxwidth",
        "minheight",
        "minwidth",
        "width"
      ]);
      function contentSnapshot(snapshot) {
        if (!snapshot || snapshot.type !== "Window" || !snapshot.props) {
          return snapshot;
        }
        const props = { ...snapshot.props };
        for (const key of WINDOW_FRAME_PROPS) {
          delete props[key];
        }
        return {
          ...snapshot,
          props
        };
      }
      function optionValue(options, key, fallback = null) {
        if (options && typeof options.get === "function") {
          return options.get(key, fallback);
        }
        if (options && Object.prototype.hasOwnProperty.call(options, key)) {
          return options[key];
        }
        return fallback;
      }
      function optionString2(options, key, fallback = "") {
        const value = optionValue(options, key, fallback);
        return value == null ? value : String(value);
      }
      function browserDialogHost(doc, options) {
        if (options.dialogs && typeof options.dialogs === "object") {
          return options.dialogs;
        }
        if (options.window && typeof options.window === "object") {
          return options.window;
        }
        if (doc.defaultView && typeof doc.defaultView === "object") {
          return doc.defaultView;
        }
        if (typeof window !== "undefined" && window) {
          return window;
        }
        if (typeof globalThis !== "undefined" && globalThis) {
          return globalThis;
        }
        return {};
      }
      function removeNode(node) {
        if (node && node.parentNode) {
          node.parentNode.removeChild(node);
        }
      }
      function createBrowserGuiBridge(options = {}) {
        const doc = browserDocument(options);
        const root = resolveRoot(doc, options);
        installStyles(doc);
        let nextWindowId = 1;
        let nextZIndex = Number(options.baseZIndex || 100);
        const windows = /* @__PURE__ */ new Map();
        const dialogs = browserDialogHost(doc, options);
        function focusWindow(id) {
          const win = windows.get(Number(id));
          if (!win) {
            return;
          }
          win.frame.style.zIndex = String(nextZIndex++);
          if (typeof win.frame.focus === "function") {
            win.frame.focus();
          }
        }
        function closeNativeWindow(id, notifyClosed = true) {
          const win = windows.get(Number(id));
          if (!win) {
            return;
          }
          windows.delete(Number(id));
          removeNode(win.frame);
          if (notifyClosed && typeof win.options.onClosed === "function") {
            win.options.onClosed();
          }
        }
        function requestClose(id) {
          const win = windows.get(Number(id));
          if (!win) {
            return;
          }
          let cancelled = false;
          if (typeof win.options.onCloseRequest === "function") {
            cancelled = win.options.onCloseRequest() === true;
          }
          if (cancelled) {
            return;
          }
          closeNativeWindow(id);
        }
        function createFrame(id, snapshot) {
          const width = snapshotDimension(snapshot, "width", 480);
          const height = snapshotDimension(snapshot, "height", 320);
          const title = snapshotTitle(snapshot);
          const frame = doc.createElement("div");
          frame.className = "zuzu-browser-window";
          frame.dataset.windowId = String(id);
          frame.setAttribute("role", "dialog");
          frame.setAttribute("aria-label", title);
          frame.tabIndex = -1;
          frame.style.width = `${width}px`;
          frame.style.height = `${height}px`;
          frame.style.left = `${24 + (id - 1) % 8 * 28}px`;
          frame.style.top = `${24 + (id - 1) % 8 * 24}px`;
          frame.addEventListener("mousedown", () => focusWindow(id));
          const titlebar = doc.createElement("div");
          titlebar.className = "zuzu-browser-window-titlebar";
          const titleText = doc.createElement("span");
          titleText.className = "zuzu-browser-window-title";
          titleText.textContent = title;
          const close = doc.createElement("button");
          close.className = "zuzu-browser-window-close";
          close.type = "button";
          close.setAttribute("aria-label", `Close ${title}`);
          close.textContent = "x";
          close.addEventListener("click", () => requestClose(id));
          titlebar.append(titleText, close);
          const content = doc.createElement("div");
          content.className = "zuzu-browser-window-content";
          frame.append(titlebar, content);
          return {
            frame,
            content,
            titleText
          };
        }
        return {
          windows,
          openWindow(snapshot, bridgeOptions = {}) {
            const id = nextWindowId++;
            const frameParts = createFrame(id, snapshot);
            const renderer = createBrowserGuiRenderer({
              document: doc,
              root: frameParts.content,
              renderMenus: true,
              sendEvent(payload) {
                if (typeof bridgeOptions.onEvent === "function") {
                  bridgeOptions.onEvent(payload);
                }
              }
            });
            windows.set(id, {
              id,
              snapshot,
              options: bridgeOptions,
              renderer,
              ...frameParts
            });
            root.appendChild(frameParts.frame);
            renderer.render({
              windowId: id,
              snapshot: contentSnapshot(snapshot)
            });
            focusWindow(id);
            return id;
          },
          closeWindow(id) {
            closeNativeWindow(id);
          },
          createWidget(id, parentGuid, snapshot, index) {
            const win = windows.get(Number(id));
            if (win) {
              win.renderer.create({
                parentGuid,
                snapshot,
                index
              });
            }
          },
          updateWidget(id, snapshot) {
            const win = windows.get(Number(id));
            if (!win) {
              return;
            }
            if (snapshot && snapshot.type === "Window") {
              win.snapshot = snapshot;
              const title = snapshotTitle(snapshot);
              win.titleText.textContent = title;
              win.frame.setAttribute("aria-label", title);
              win.frame.style.width = `${snapshotDimension(snapshot, "width", 480)}px`;
              win.frame.style.height = `${snapshotDimension(snapshot, "height", 320)}px`;
              return;
            }
            win.renderer.update({
              snapshot
            });
          },
          destroyWidget(id, widgetGuid) {
            const win = windows.get(Number(id));
            if (win) {
              win.renderer.destroy({
                widgetGuid
              });
            }
          },
          alert(message, optionsForDialog = {}) {
            if (typeof dialogs.alert === "function") {
              dialogs.alert(String(message ?? ""));
            }
            return true;
          },
          confirm(message, optionsForDialog = {}) {
            if (typeof dialogs.confirm === "function") {
              return dialogs.confirm(String(message ?? "")) ? true : false;
            }
            return optionValue(optionsForDialog, "default", false) ? true : false;
          },
          prompt(message, optionsForDialog = {}) {
            const defaultValue = optionString2(
              optionsForDialog,
              "value",
              optionString2(optionsForDialog, "default", "")
            );
            if (typeof dialogs.prompt === "function") {
              return dialogs.prompt(String(message ?? ""), defaultValue);
            }
            return defaultValue;
          },
          colourPicker(optionsForDialog = {}) {
            const defaultValue = optionString2(
              optionsForDialog,
              "value",
              "#000000"
            );
            if (typeof dialogs.colourPicker === "function") {
              return dialogs.colourPicker(defaultValue, optionsForDialog);
            }
            if (typeof dialogs.colorPicker === "function") {
              return dialogs.colorPicker(defaultValue, optionsForDialog);
            }
            if (typeof dialogs.prompt === "function") {
              const answer = dialogs.prompt(
                optionString2(optionsForDialog, "label", "Colour:"),
                defaultValue
              );
              return answer == null ? defaultValue : answer;
            }
            return defaultValue;
          },
          fileOpen() {
            throw new Error(
              "GUI_DIALOGUE_UNSUPPORTED: file dialogues are unsupported in JS/Browser"
            );
          },
          fileSave() {
            throw new Error(
              "GUI_DIALOGUE_UNSUPPORTED: file dialogues are unsupported in JS/Browser"
            );
          },
          directoryOpen() {
            throw new Error(
              "GUI_DIALOGUE_UNSUPPORTED: directory dialogues are unsupported in JS/Browser"
            );
          },
          directorySave() {
            throw new Error(
              "GUI_DIALOGUE_UNSUPPORTED: directory dialogues are unsupported in JS/Browser"
            );
          },
          focusWindow
        };
      }
      module2.exports = {
        createBrowserGuiBridge,
        createBrowserGuiRenderer
      };
    }
  });

  // lib/host/browser-host.js
  var require_browser_host = __commonJS({
    "lib/host/browser-host.js"(exports2, module2) {
      "use strict";
      function _splitPath(value) {
        return String(value ?? "").split(/[\\/]+/u).filter(Boolean);
      }
      function _normalizePath(value) {
        const isAbs = String(value ?? "").startsWith("/");
        const stack = [];
        for (const part of _splitPath(value)) {
          if (part === ".") {
            continue;
          }
          if (part === "..") {
            if (stack.length > 0) {
              stack.pop();
            }
            continue;
          }
          stack.push(part);
        }
        if (isAbs) {
          return `/${stack.join("/")}`;
        }
        return stack.join("/") || ".";
      }
      function _resolvePath(...parts) {
        const raw = parts.map((item) => String(item ?? "")).join("/");
        const seeded = raw.startsWith("/") ? raw : `/${raw}`;
        return _normalizePath(seeded);
      }
      function _dirname(value) {
        const normalized = _normalizePath(value);
        if (normalized === "/" || normalized === ".") {
          return "/";
        }
        const parts = _splitPath(normalized);
        parts.pop();
        return parts.length > 0 ? `/${parts.join("/")}` : "/";
      }
      function _sourceUrlComment(runOptions = {}) {
        const filename = runOptions.filename == null ? "/<browser>.zzs" : String(runOptions.filename);
        return `
//# sourceURL=${filename.replace(/[\r\n]/gu, "_")}`;
      }
      function _browserEval(source, context, runOptions = {}) {
        context.globalThis = context;
        const sourceUrl = _sourceUrlComment(runOptions);
        try {
          const expr = Function(
            "__zuzu_context",
            `with ( __zuzu_context ) { return ( ${source} ); }${sourceUrl}`
          );
          return expr(context);
        } catch (_exprError) {
          const script = Function(
            "__zuzu_context",
            `with ( __zuzu_context ) { ${source}
 }${sourceUrl}`
          );
          return script(context);
        }
      }
      function _defaultGuiBridge(options) {
        if (Object.prototype.hasOwnProperty.call(options, "guiBridge")) {
          return options.guiBridge;
        }
        const doc = options.document || (typeof document !== "undefined" ? document : null);
        if (!doc || typeof doc.createElement !== "function") {
          return null;
        }
        let bridge = null;
        function getBridge() {
          if (bridge) {
            return bridge;
          }
          const {
            createBrowserGuiBridge
          } = require_browser_gui_renderer();
          bridge = createBrowserGuiBridge({
            document: doc,
            root: options.guiRoot,
            rootId: options.guiRootId,
            baseZIndex: options.guiBaseZIndex,
            dialogs: options.guiDialogs,
            window: options.window
          });
          return bridge;
        }
        return {
          get windows() {
            return getBridge().windows;
          },
          openWindow(...args) {
            return getBridge().openWindow(...args);
          },
          closeWindow(...args) {
            return getBridge().closeWindow(...args);
          },
          createWidget(...args) {
            return getBridge().createWidget(...args);
          },
          updateWidget(...args) {
            return getBridge().updateWidget(...args);
          },
          destroyWidget(...args) {
            return getBridge().destroyWidget(...args);
          },
          focusWindow(...args) {
            return getBridge().focusWindow(...args);
          },
          alert(...args) {
            return getBridge().alert(...args);
          },
          confirm(...args) {
            return getBridge().confirm(...args);
          },
          prompt(...args) {
            return getBridge().prompt(...args);
          },
          colourPicker(...args) {
            return getBridge().colourPicker(...args);
          },
          fileOpen(...args) {
            return getBridge().fileOpen(...args);
          },
          fileSave(...args) {
            return getBridge().fileSave(...args);
          },
          directoryOpen(...args) {
            return getBridge().directoryOpen(...args);
          },
          directorySave(...args) {
            return getBridge().directorySave(...args);
          }
        };
      }
      function createBrowserHost(options = {}) {
        const repoRoot = options.repoRoot || "/";
        const includePaths = Array.isArray(options.includePaths) ? options.includePaths.map((item) => _resolvePath(item)) : [];
        const virtualFiles = new Map(Object.entries(options.virtualFiles || {}).map(([filename, source]) => [_resolvePath(filename), String(source)]));
        const jsModules = new Map(Object.entries(options.jsModules || {}).map(([filename, loaded]) => [_resolvePath(filename), loaded]));
        const fetchedFiles = /* @__PURE__ */ new Map();
        const fetchModule = typeof options.fetchModule === "function" ? options.fetchModule : null;
        const runInContext = typeof options.evaluate === "function" ? options.evaluate : _browserEval;
        const capabilities2 = /* @__PURE__ */ new Set([
          "console",
          "time",
          "module_load",
          "module_fetch",
          "file_availability",
          "http",
          "js",
          "gui"
        ]);
        const workerSource = options.workerSource || typeof globalThis !== "undefined" && globalThis.__ZUZU_BROWSER_WORKER_SOURCE__ || null;
        const workerUrl = options.workerUrl || typeof globalThis !== "undefined" && globalThis.__ZUZU_BROWSER_WORKER_URL__ || null;
        const workerFactory = typeof options.workerFactory === "function" ? options.workerFactory : typeof globalThis !== "undefined" && typeof globalThis.__ZUZU_BROWSER_WORKER_FACTORY__ === "function" ? globalThis.__ZUZU_BROWSER_WORKER_FACTORY__ : null;
        if (workerSource || workerUrl || workerFactory) {
          capabilities2.add("worker");
        }
        const gui = _defaultGuiBridge(options);
        return {
          name: "browser",
          repoRoot,
          includePaths,
          capabilities: capabilities2,
          gui,
          workerSource,
          workerUrl,
          workerFactory,
          cwd() {
            return "/";
          },
          resolve(...parts) {
            return _resolvePath(...parts);
          },
          dirname(value) {
            return _dirname(value);
          },
          join(...parts) {
            return _normalizePath(parts.map((item) => String(item ?? "")).join("/"));
          },
          readFileText(filename) {
            const key = _resolvePath(filename);
            if (virtualFiles.has(key)) {
              return virtualFiles.get(key);
            }
            if (fetchedFiles.has(key)) {
              return fetchedFiles.get(key);
            }
            if (fetchModule) {
              const fetched = fetchModule(key);
              if (typeof fetched === "string") {
                fetchedFiles.set(key, fetched);
                return fetched;
              }
            }
            throw new Error(`Exception: Browser host cannot read file '${filename}'`);
          },
          fileExists(filename) {
            const key = _resolvePath(filename);
            if (virtualFiles.has(key) || jsModules.has(key) || fetchedFiles.has(key)) {
              return true;
            }
            if (fetchModule) {
              const fetched = fetchModule(key);
              if (typeof fetched === "string") {
                fetchedFiles.set(key, fetched);
                return true;
              }
            }
            return false;
          },
          runInContext(source, context, runOptions = {}) {
            return runInContext(source, context, runOptions);
          },
          consoleLog(value) {
            if (typeof options.consoleLog === "function") {
              options.consoleLog(value);
              return;
            }
            if (typeof console !== "undefined" && typeof console.log === "function") {
              console.log(value);
            }
          },
          now() {
            return Date.now();
          },
          getEnv(_name) {
            return null;
          },
          loadJsModule(filename) {
            const key = _resolvePath(filename);
            if (!jsModules.has(key)) {
              throw new Error(`Exception: Browser host has no JS module for '${filename}'`);
            }
            return jsModules.get(key);
          }
        };
      }
      module2.exports = {
        createBrowserHost
      };
    }
  });

  // lib/transpiler-utils.js
  var require_transpiler_utils = __commonJS({
    "lib/transpiler-utils.js"(exports2, module2) {
      "use strict";
      function isEscaped(text, idx) {
        let k = idx - 1;
        let backslashes = 0;
        while (k >= 0 && text[k] === "\\") {
          backslashes++;
          k--;
        }
        return backslashes % 2 === 1;
      }
      function findMatching(source, start, openChar, closeChar) {
        let depth = 0;
        let quote = null;
        for (let i = start; i < source.length; i++) {
          const ch = source[i];
          if (quote) {
            if (ch === quote && !isEscaped(source, i)) {
              quote = null;
            }
            continue;
          }
          if (ch === '"' || ch === "'" || ch === "`") {
            quote = ch;
            continue;
          }
          if (ch === openChar) {
            depth++;
          } else if (ch === closeChar) {
            depth--;
            if (depth === 0) {
              return i;
            }
          }
        }
        return -1;
      }
      function splitCaseValues(text) {
        return text.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
      }
      function stripPod(source) {
        const lines = source.split(/\r?\n/);
        const out = [];
        let inPod = false;
        for (const line of lines) {
          if (/^=cut\b/.test(line)) {
            inPod = false;
            continue;
          }
          if (/^=\w+/.test(line)) {
            inPod = true;
            continue;
          }
          if (inPod) {
            continue;
          }
          out.push(line);
        }
        return out.join("\n");
      }
      function stripPodPreservingLines(source) {
        const lines = source.split(/\r?\n/);
        const out = [];
        let inPod = false;
        for (const line of lines) {
          if (/^=cut\b/.test(line)) {
            inPod = false;
            out.push("");
            continue;
          }
          if (/^=\w+/.test(line)) {
            inPod = true;
            out.push("");
            continue;
          }
          out.push(inPod ? "" : line);
        }
        return out.join("\n");
      }
      module2.exports = {
        isEscaped,
        findMatching,
        splitCaseValues,
        stripPod,
        stripPodPreservingLines
      };
    }
  });

  // lib/transpiler-new/errors.js
  var require_errors = __commonJS({
    "lib/transpiler-new/errors.js"(exports2, module2) {
      "use strict";
      var TranspilerSyntaxError = class extends Error {
        constructor(message, token = null) {
          const suffix = token && token.line != null && token.column != null ? ` at ${token.line}:${token.column}` : "";
          super(`${message}${suffix}`);
          this.name = "TranspilerSyntaxError";
          this.token = token;
        }
      };
      var UnsupportedSyntaxError = class extends Error {
        constructor(message, token = null) {
          const suffix = token && token.line != null && token.column != null ? ` at ${token.line}:${token.column}` : "";
          super(`${message}${suffix}`);
          this.name = "UnsupportedSyntaxError";
          this.token = token;
        }
      };
      module2.exports = {
        TranspilerSyntaxError,
        UnsupportedSyntaxError
      };
    }
  });

  // lib/transpiler-new/lexer.js
  var require_lexer = __commonJS({
    "lib/transpiler-new/lexer.js"(exports2, module2) {
      "use strict";
      var { stripPod } = require_transpiler_utils();
      var {
        TranspilerSyntaxError,
        UnsupportedSyntaxError
      } = require_errors();
      var UTF8_ENCODER = new TextEncoder();
      var KEYWORDS = /* @__PURE__ */ new Set([
        "from",
        "import",
        "as",
        "let",
        "const",
        "function",
        "async",
        "await",
        "spawn",
        "return",
        "if",
        "else",
        "true",
        "false",
        "null",
        "and",
        "or",
        "xor",
        "nand",
        "not",
        // TODO: Remove stale legacy JS-only words that are not current
        // ZuzuScript keywords: contains, difference, elsif, export, foreach,
        // given, isa, my, not_in, our, package, sub, then, use, when.
        "not_in",
        "eq",
        "ne",
        "gt",
        "ge",
        "lt",
        "le",
        "cmp",
        "eqi",
        "nei",
        "gti",
        "gei",
        "lti",
        "lei",
        "cmpi",
        "mod",
        "abs",
        "sqrt",
        "floor",
        "ceil",
        "round",
        "int",
        "length",
        "uc",
        "lc",
        "say",
        "class",
        "trait",
        "try",
        "catch",
        "switch",
        "case",
        "default",
        "for",
        "while",
        "do",
        "fn",
        "next",
        "continue",
        "last",
        "unless",
        "export",
        "die",
        "new",
        "method",
        "static",
        "extends",
        "with",
        "but",
        "super",
        "does",
        "my",
        "our",
        "use",
        "package",
        "given",
        "when",
        "then",
        "elsif",
        "foreach",
        "in",
        "isa",
        "can",
        "does",
        "typeof",
        "debug",
        "warn",
        "assert",
        "throw",
        "sub",
        "union",
        "intersection",
        "difference",
        "subsetof",
        "supersetof",
        "equivalentof",
        "contains"
      ]);
      var SIMPLE_PUNCTUATION = /* @__PURE__ */ new Set(["(", ")", "{", "}", "[", "]", ",", ";", "."]);
      function decodeSimpleEscape(esc) {
        switch (esc) {
          case "n":
            return "\n";
          case "r":
            return "\r";
          case "t":
            return "	";
          case '"':
          case "'":
          case "`":
          case "/":
          case "$":
          case "\\":
            return esc;
          default:
            return null;
        }
      }
      function decodeUnicodeEscape(digits) {
        if (!/^[0-9A-Fa-f]{4}$/u.test(digits)) {
          return null;
        }
        const code = Number.parseInt(digits, 16);
        if (code >= 55296 && code <= 57343) {
          return null;
        }
        return String.fromCodePoint(code);
      }
      function decodeHexEscape(digits) {
        if (!/^[0-9A-Fa-f]{2}$/u.test(digits)) {
          return null;
        }
        return String.fromCharCode(Number.parseInt(digits, 16));
      }
      function isDigit(ch) {
        return ch >= "0" && ch <= "9";
      }
      function isUnicodeLetter(ch) {
        return ch.toLowerCase() !== ch.toUpperCase();
      }
      function isIdentifierStart(ch) {
        return ch === "_" || ch === "$" || isUnicodeLetter(ch);
      }
      function isIdentifierPart(ch) {
        return isIdentifierStart(ch) || isDigit(ch);
      }
      function appendUtf8ByteChars(out, ch) {
        for (const byte of UTF8_ENCODER.encode(ch)) {
          out.value += String.fromCharCode(byte);
        }
      }
      function makeToken(type, value, start, end, source) {
        return {
          type,
          value,
          start: start.offset,
          end: end.offset,
          line: start.line,
          column: start.column,
          endLine: end.line,
          endColumn: end.column,
          raw: source.slice(start.offset, end.offset)
        };
      }
      function readTemplateLiteral(text, start, state) {
        const parts = [];
        let offset = state.offset;
        let line = state.line;
        let column = state.column;
        const delimiter = text.slice(start.offset, start.offset + 3) === "```" ? "```" : "`";
        function peek(n = 0) {
          return text[offset + n] || "";
        }
        function advance() {
          const ch = text[offset] || "";
          offset++;
          if (ch === "\n") {
            line++;
            column = 1;
          } else {
            column++;
          }
          return ch;
        }
        function cursor() {
          return { offset, line, column };
        }
        function skipQuoted() {
          const quote = advance();
          while (offset < text.length) {
            const ch = advance();
            if (ch === "\\") {
              advance();
              continue;
            }
            if (ch === quote) {
              return;
            }
          }
          throw new TranspilerSyntaxError("Unterminated quoted section in template literal");
        }
        function skipLineComment() {
          advance();
          advance();
          while (offset < text.length && peek() !== "\n") {
            advance();
          }
        }
        function skipBlockComment() {
          advance();
          advance();
          while (offset < text.length) {
            if (peek() === "*" && peek(1) === "/") {
              advance();
              advance();
              return;
            }
            advance();
          }
          throw new TranspilerSyntaxError("Unterminated block comment in template literal");
        }
        let textPart = "";
        for (let i = 0; i < delimiter.length; i++) {
          advance();
        }
        while (offset < text.length) {
          const ch = peek();
          if (delimiter === "```" ? text.slice(offset, offset + 3) === "```" : ch === "`") {
            if (textPart.length > 0) {
              parts.push({
                type: "text",
                value: textPart
              });
            }
            for (let i = 0; i < delimiter.length; i++) {
              advance();
            }
            return {
              parts,
              end: cursor()
            };
          }
          if (delimiter !== "```" && ch === "\\") {
            advance();
            const escStart = cursor();
            const esc = advance();
            if (esc === "x") {
              const digits = advance() + advance();
              const decoded2 = decodeHexEscape(digits);
              if (decoded2 == null) {
                throw new TranspilerSyntaxError(
                  "Invalid hex escape sequence",
                  makeToken("escape", `x${digits}`, escStart, cursor(), text)
                );
              }
              textPart += decoded2;
              continue;
            }
            if (esc === "u") {
              const digits = advance() + advance() + advance() + advance();
              const decoded2 = decodeUnicodeEscape(digits);
              if (decoded2 == null) {
                throw new TranspilerSyntaxError(
                  "Invalid unicode escape sequence",
                  makeToken("escape", `u${digits}`, escStart, cursor(), text)
                );
              }
              textPart += decoded2;
              continue;
            }
            const decoded = decodeSimpleEscape(esc);
            if (decoded == null) {
              throw new TranspilerSyntaxError(
                `Unsupported escape sequence \\${esc}`,
                makeToken("escape", esc, escStart, cursor(), text)
              );
            }
            textPart += decoded;
            continue;
          }
          if (delimiter !== "```" && ch === "\n") {
            throw new TranspilerSyntaxError("Unterminated template literal", makeToken("template", "", start, cursor(), text));
          }
          if (ch === "$" && peek(1) === "{") {
            if (textPart.length > 0) {
              parts.push({
                type: "text",
                value: textPart
              });
              textPart = "";
            }
            advance();
            advance();
            const exprStart = offset;
            let depth = 1;
            while (offset < text.length) {
              if (peek() === '"' || peek() === "'" || peek() === "`") {
                skipQuoted();
                continue;
              }
              if (peek() === "/" && peek(1) === "/") {
                skipLineComment();
                continue;
              }
              if (peek() === "/" && peek(1) === "*") {
                skipBlockComment();
                continue;
              }
              const cur = advance();
              if (cur === "{") {
                depth++;
              } else if (cur === "}") {
                depth--;
                if (depth === 0) {
                  parts.push({
                    type: "expr",
                    value: text.slice(exprStart, offset - 1)
                  });
                  break;
                }
              }
            }
            if (depth !== 0) {
              throw new TranspilerSyntaxError("Unterminated template interpolation");
            }
            continue;
          }
          textPart += advance();
        }
        throw new TranspilerSyntaxError("Unterminated template literal", makeToken("template", "", start, cursor(), text));
      }
      function tokenize(source) {
        const text = stripPod(String(source ?? ""));
        const tokens = [];
        let lastToken = null;
        let offset = 0;
        let line = 1;
        let column = 1;
        function cursor() {
          return { offset, line, column };
        }
        function peek(n = 0) {
          return text[offset + n] || "";
        }
        function advance() {
          const ch = text[offset] || "";
          offset++;
          if (ch === "\n") {
            line++;
            column = 1;
          } else {
            column++;
          }
          return ch;
        }
        function addToken(type, value, start, end2) {
          const token = makeToken(type, value, start, end2, text);
          tokens.push(token);
          lastToken = token;
        }
        function canStartRegex() {
          if (!lastToken) {
            return true;
          }
          if (lastToken.type === "punctuation" && ["(", "[", "{", ",", ";"].includes(lastToken.value)) {
            return true;
          }
          if (lastToken.type === "operator") {
            return true;
          }
          if (lastToken.type === "keyword" && ["return", "case", "if", "while", "throw", "and", "or", "xor", "nand", "not"].includes(lastToken.value)) {
            return true;
          }
          return false;
        }
        function readInterpolationSource() {
          advance();
          advance();
          const exprStart = offset;
          let depth = 1;
          while (offset < text.length) {
            if (peek() === '"' || peek() === "'" || peek() === "`") {
              const quote = advance();
              while (offset < text.length) {
                const ch = advance();
                if (ch === "\\") {
                  advance();
                  continue;
                }
                if (ch === quote) {
                  break;
                }
              }
              continue;
            }
            if (peek() === "/" && peek(1) === "/") {
              advance();
              advance();
              while (offset < text.length && peek() !== "\n") {
                advance();
              }
              continue;
            }
            if (peek() === "/" && peek(1) === "*") {
              advance();
              advance();
              while (offset < text.length) {
                if (peek() === "*" && peek(1) === "/") {
                  advance();
                  advance();
                  break;
                }
                advance();
              }
              continue;
            }
            const cur = advance();
            if (cur === "{") {
              depth++;
            } else if (cur === "}") {
              depth--;
              if (depth === 0) {
                return text.slice(exprStart, offset - 1);
              }
            }
          }
          throw new TranspilerSyntaxError("Unterminated template interpolation");
        }
        while (offset < text.length) {
          const ch = peek();
          if (offset === 0 && ch === "#" && peek(1) === "!") {
            advance();
            advance();
            while (offset < text.length && peek() !== "\n") {
              advance();
            }
            continue;
          }
          if (ch === " " || ch === "	" || ch === "\r" || ch === "\n") {
            advance();
            continue;
          }
          if (ch === "/" && peek(1) === "/") {
            while (offset < text.length && peek() !== "\n") {
              advance();
            }
            continue;
          }
          if (ch === "/" && peek(1) === "*") {
            advance();
            advance();
            while (offset < text.length && !(peek() === "*" && peek(1) === "/")) {
              advance();
            }
            if (offset >= text.length) {
              throw new TranspilerSyntaxError("Unterminated block comment");
            }
            advance();
            advance();
            continue;
          }
          const start = cursor();
          if (ch === "/" && peek(1) !== "/" && peek(1) !== "*" && canStartRegex()) {
            let pattern = "";
            let textPart = "";
            const parts = [];
            let inClass = false;
            let sawInterpolation = false;
            advance();
            while (offset < text.length) {
              const cur = peek();
              if (cur === "\\") {
                const backslash = advance();
                const escaped = advance();
                pattern += backslash + escaped;
                textPart += backslash + escaped;
                continue;
              }
              if (cur === "[") {
                inClass = true;
              } else if (cur === "]") {
                inClass = false;
              }
              if (cur === "$" && peek(1) === "{") {
                if (textPart.length > 0) {
                  parts.push({
                    type: "text",
                    value: textPart
                  });
                  textPart = "";
                }
                const expr = readInterpolationSource();
                parts.push({
                  type: "expr",
                  value: expr
                });
                sawInterpolation = true;
                pattern += `\${${expr}}`;
                continue;
              }
              if (cur === "/" && !inClass) {
                break;
              }
              if (cur === "\n") {
                throw new TranspilerSyntaxError("Unterminated regexp literal");
              }
              const value = advance();
              pattern += value;
              textPart += value;
            }
            if (peek() !== "/") {
              throw new TranspilerSyntaxError("Unterminated regexp literal");
            }
            advance();
            let flags = "";
            while (/[a-z]/i.test(peek())) {
              flags += advance();
            }
            if (sawInterpolation && textPart.length > 0) {
              parts.push({
                type: "text",
                value: textPart
              });
            }
            addToken("regexp", { pattern, parts, flags }, start, cursor());
            continue;
          }
          if (ch === '"') {
            if (peek(1) === '"' && peek(2) === '"') {
              let value2 = "";
              advance();
              advance();
              advance();
              while (offset < text.length) {
                if (peek() === '"' && peek(1) === '"' && peek(2) === '"') {
                  advance();
                  advance();
                  advance();
                  addToken("string", value2, start, cursor());
                  value2 = null;
                  break;
                }
                value2 += advance();
              }
              if (value2 !== null) {
                throw new TranspilerSyntaxError("Unterminated triple-quoted string literal");
              }
              continue;
            }
            let value = "";
            advance();
            while (offset < text.length && peek() !== '"') {
              if (peek() === "\\") {
                const escStart = cursor();
                advance();
                const esc = advance();
                if (esc === "x") {
                  const digits = advance() + advance();
                  const decoded = decodeHexEscape(digits);
                  if (decoded == null) {
                    throw new TranspilerSyntaxError(
                      "Invalid hex escape sequence",
                      makeToken("escape", `x${digits}`, escStart, cursor(), text)
                    );
                  }
                  value += decoded;
                } else if (esc === "u") {
                  const digits = advance() + advance() + advance() + advance();
                  const decoded = decodeUnicodeEscape(digits);
                  if (decoded == null) {
                    throw new TranspilerSyntaxError(
                      "Invalid unicode escape sequence",
                      makeToken("escape", `u${digits}`, escStart, cursor(), text)
                    );
                  }
                  value += decoded;
                } else {
                  const decoded = decodeSimpleEscape(esc);
                  if (decoded == null) {
                    throw new TranspilerSyntaxError(
                      `Unsupported escape sequence \\${esc}`,
                      makeToken("escape", esc, escStart, cursor(), text)
                    );
                  }
                  value += decoded;
                }
                continue;
              }
              if (peek() === "\n") {
                throw new TranspilerSyntaxError("Unterminated string literal");
              }
              value += advance();
            }
            if (peek() !== '"') {
              throw new TranspilerSyntaxError("Unterminated string literal");
            }
            advance();
            addToken("string", value, start, cursor());
            continue;
          }
          if (ch === "'") {
            if (peek(1) === "'" && peek(2) === "'") {
              const out = { value: "" };
              advance();
              advance();
              advance();
              while (offset < text.length) {
                if (peek() === "'" && peek(1) === "'" && peek(2) === "'") {
                  advance();
                  advance();
                  advance();
                  addToken("binary_string", out.value, start, cursor());
                  out.value = null;
                  break;
                }
                appendUtf8ByteChars(out, advance());
              }
              if (out.value !== null) {
                throw new TranspilerSyntaxError("Unterminated triple-quoted binary string literal");
              }
              continue;
            }
            let value = "";
            advance();
            while (offset < text.length && peek() !== "'") {
              if (peek() === "\\") {
                const escStart = cursor();
                advance();
                const esc = advance();
                if (esc === "u") {
                  throw new TranspilerSyntaxError(
                    "Unicode escapes are not supported in binary strings",
                    makeToken("escape", esc, escStart, cursor(), text)
                  );
                }
                if (esc === "x") {
                  const digits = advance() + advance();
                  const decoded2 = decodeHexEscape(digits);
                  if (decoded2 == null) {
                    throw new TranspilerSyntaxError(
                      "Invalid hex escape sequence",
                      makeToken("escape", `x${digits}`, escStart, cursor(), text)
                    );
                  }
                  value += decoded2;
                  continue;
                }
                const decoded = decodeSimpleEscape(esc);
                if (decoded == null) {
                  throw new TranspilerSyntaxError(
                    `Unsupported escape sequence \\${esc}`,
                    makeToken("escape", esc, escStart, cursor(), text)
                  );
                }
                value += decoded;
                continue;
              }
              if (peek() === "\n") {
                throw new TranspilerSyntaxError("Unterminated binary string literal");
              }
              const out = { value: "" };
              appendUtf8ByteChars(out, advance());
              value += out.value;
            }
            if (peek() !== "'") {
              throw new TranspilerSyntaxError("Unterminated binary string literal");
            }
            advance();
            addToken("binary_string", value, start, cursor());
            continue;
          }
          if (ch === "`") {
            const template = readTemplateLiteral(text, start, cursor());
            offset = template.end.offset;
            line = template.end.line;
            column = template.end.column;
            addToken("template", template.parts, start, template.end);
            continue;
          }
          const twoChar = ch + peek(1);
          const threeChar = twoChar + peek(2);
          if (twoChar === "^^") {
            advance();
            advance();
            addToken("identifier", "^^", start, cursor());
            continue;
          }
          if (["...", "<<<", ">>>", "**=", "?:=", "<=>"].includes(threeChar)) {
            advance();
            advance();
            advance();
            addToken("operator", threeChar, start, cursor());
            continue;
          }
          if (["{{", "<<", ">>", ":=", "==", "!=", "<=", ">=", "+=", "-=", "*=", "/=", "%=", "_=", "++", "--", "->", "?:", "**", "@@", "@?", "~=", "|>", "<|", "\u2282\u2283", "\xD7=", "\xF7="].includes(twoChar)) {
            advance();
            advance();
            addToken("operator", twoChar, start, cursor());
            continue;
          }
          if (ch === "_" && !isIdentifierPart(peek(1))) {
            advance();
            addToken("operator", "_", start, cursor());
            continue;
          }
          if (isDigit(ch)) {
            let value = "";
            while (isDigit(peek())) {
              value += advance();
            }
            if (peek() === "." && isDigit(peek(1))) {
              value += advance();
              while (isDigit(peek())) {
                value += advance();
              }
            }
            addToken("number", value, start, cursor());
            continue;
          }
          if (isIdentifierStart(ch)) {
            let value = "";
            while (isIdentifierPart(peek())) {
              value += advance();
            }
            if (KEYWORDS.has(value)) {
              addToken("keyword", value, start, cursor());
            } else {
              addToken("identifier", value, start, cursor());
            }
            continue;
          }
          if (SIMPLE_PUNCTUATION.has(ch)) {
            advance();
            addToken("punctuation", ch, start, cursor());
            continue;
          }
          if (["+", "-", "*", "/", "%", "<", ">", "=", "_", "?", ":", "~", "!", "\\", "&", "|", "^", "@", "\xD7", "\xF7", "\xAC", "\u22C0", "\u22C1", "\u22BB", "\u22BC"].includes(ch)) {
            advance();
            addToken("operator", ch, start, cursor());
            continue;
          }
          if (["\u2261", "\u2262", "\u2260", "\u2264", "\u2265", "\u2192", "\u221A", "\u230A", "\u230B", "\u2308", "\u2309", "\u2208", "\u2209", "\u22C3", "\u22C2", "\u2216", "\u2282", "\u2283", "\xAB", "\xBB", "\u2276", "\u2277", "\u25B7", "\u25C1"].includes(ch)) {
            advance();
            addToken("operator", ch, start, cursor());
            continue;
          }
          throw new UnsupportedSyntaxError(
            `Unsupported character ${JSON.stringify(ch)}`,
            makeToken("unsupported", ch, start, start, text)
          );
        }
        const end = cursor();
        tokens.push(makeToken("eof", "", end, end, text));
        return tokens;
      }
      module2.exports = {
        tokenize
      };
    }
  });

  // lib/transpiler-new/ast.js
  var require_ast = __commonJS({
    "lib/transpiler-new/ast.js"(exports2, module2) {
      "use strict";
      function withLoc(node, start, end) {
        return {
          ...node,
          loc: {
            start: start ? {
              offset: start.start,
              line: start.line,
              column: start.column
            } : null,
            end: end ? {
              offset: end.end,
              line: end.endLine,
              column: end.endColumn
            } : null
          }
        };
      }
      module2.exports = {
        withLoc
      };
    }
  });

  // lib/transpiler-new/parser.js
  var require_parser = __commonJS({
    "lib/transpiler-new/parser.js"(exports2, module2) {
      "use strict";
      var { withLoc } = require_ast();
      var { tokenize } = require_lexer();
      var {
        TranspilerSyntaxError,
        UnsupportedSyntaxError
      } = require_errors();
      function parse(tokens, options = {}) {
        let index = 0;
        let asyncContextDepth = 1;
        function startLocFromToken(token) {
          return {
            start: token.start,
            line: token.line,
            column: token.column
          };
        }
        function startLocFromNode(node) {
          return {
            start: node.loc.start.offset,
            line: node.loc.start.line,
            column: node.loc.start.column
          };
        }
        function endLocFromToken(token) {
          return {
            end: token.end,
            endLine: token.endLine,
            endColumn: token.endColumn
          };
        }
        function endLocFromNode(node) {
          return {
            end: node.loc.end.offset,
            endLine: node.loc.end.line,
            endColumn: node.loc.end.column
          };
        }
        function current() {
          return tokens[index];
        }
        function peekToken(n = 1) {
          return tokens[index + n] || tokens[tokens.length - 1];
        }
        function previous() {
          return tokens[index - 1];
        }
        function canTerminateSimpleStatement() {
          const token = current();
          if (token.type === "punctuation" && token.value === "}") {
            return true;
          }
          if (token.type === "eof") {
            return true;
          }
          return false;
        }
        function consumeStatementTerminator(message) {
          if (match("punctuation", ";")) {
            return;
          }
          if (canTerminateSimpleStatement()) {
            return;
          }
          throw new TranspilerSyntaxError(message || "Expected statement terminator", current());
        }
        function atEnd() {
          return current().type === "eof";
        }
        function match(type, value = null) {
          const token = current();
          if (token.type !== type) {
            return false;
          }
          if (value != null && token.value !== value) {
            return false;
          }
          index++;
          return true;
        }
        function expect(type, value = null, message = null) {
          const token = current();
          if (match(type, value)) {
            return previous();
          }
          throw new TranspilerSyntaxError(
            message || `Expected ${value != null ? `${type} ${value}` : type}`,
            token
          );
        }
        function expectIdentifier(message = "Expected identifier") {
          const token = current();
          if (token.type === "identifier" || token.type === "keyword") {
            if (token.value === "^^") {
              throw new TranspilerSyntaxError("'^^' is reserved for the chain placeholder", token);
            }
            index++;
            return token;
          }
          throw new TranspilerSyntaxError(message, token);
        }
        function parseProgram() {
          const body = [];
          const start = current();
          while (!atEnd()) {
            body.push(parseStatement());
          }
          return withLoc({
            type: "Program",
            body
          }, start, previous() || start);
        }
        function matchPairListClose() {
          if (current().type === "punctuation" && current().value === "}" && peekToken().type === "punctuation" && peekToken().value === "}") {
            index += 2;
            return true;
          }
          return false;
        }
        function parseExpressionRoot() {
          const expr = parseExpression();
          if (!atEnd()) {
            throw new TranspilerSyntaxError("Unexpected token after expression", current());
          }
          return expr;
        }
        function parseStatement() {
          const token = current();
          if (token.type === "punctuation" && token.value === ";") {
            index++;
            return withLoc({ type: "EmptyStatement" }, token, token);
          }
          if (token.type === "keyword") {
            switch (token.value) {
              case "from":
                return parseImportDeclaration();
              case "let":
              case "const":
                return parseVariableDeclaration();
              case "function":
                return parseFunctionDeclaration();
              case "async":
                if (peekToken().type === "keyword" && peekToken().value === "function") {
                  return parseFunctionDeclaration();
                }
                if (peekToken().type === "keyword" && peekToken().value === "fn") {
                  const start = expect("keyword", "async");
                  return parseFunctionDeclarationLikeFn(true, start);
                }
                break;
              case "return":
                return parseReturnStatement();
              case "if":
                return parseIfStatement();
              case "for":
                return parseForStatement();
              case "while":
                return parseWhileStatement();
              case "switch":
                return parseSwitchStatement();
              case "next":
              case "continue":
                return parseLoopControlStatement("ContinueStatement");
              case "last":
                return parseLoopControlStatement("BreakStatement");
              case "throw":
                return parseThrowStatement();
              case "die":
                return parseDieStatement();
              case "warn":
                return parseWarnStatement();
              case "assert":
                return parseAssertStatement();
              case "debug":
                return parseDebugStatement();
              case "say":
                return parseSayStatement();
              case "try":
                return parseTryStatement();
              case "class":
                return parseClassDeclaration();
              case "trait":
                return parseTraitDeclaration();
              case "export":
                return parseExportDeclaration();
              case "catch":
              case "unless":
                throw new UnsupportedSyntaxError(
                  `Keyword ${token.value} is not supported by zuzu-js transpilation yet`,
                  token
                );
              case "fn":
                return parseFunctionDeclarationLikeFn();
              default:
                break;
            }
          }
          if (token.type === "punctuation" && token.value === "{") {
            return parseBlockStatement();
          }
          return parseExpressionStatement();
        }
        function parseExportDeclaration() {
          const start = expect("keyword", "export");
          const token = current();
          const allowed = /* @__PURE__ */ new Set(["let", "const", "function", "async", "fn", "class", "trait"]);
          if (token.type !== "keyword" || !allowed.has(token.value)) {
            throw new TranspilerSyntaxError("Expected declaration after export", token);
          }
          const declaration = parseStatement();
          declaration.exported = true;
          declaration.loc.start = {
            offset: start.start,
            line: start.line,
            column: start.column
          };
          return declaration;
        }
        function parseImportDeclaration() {
          const start = expect("keyword", "from");
          const moduleParts = [];
          while (!(current().type === "keyword" && (current().value === "import" || current().value === "try"))) {
            if (current().type === "identifier" || current().type === "keyword" || current().type === "operator" && current().value === "/" || current().type === "operator" && current().value === "." || current().type === "punctuation" && current().value === ".") {
              moduleParts.push(current().value);
              index++;
              continue;
            }
            if (current().type === "string") {
              moduleParts.push(current().value);
              index++;
              break;
            }
            throw new TranspilerSyntaxError("Invalid module path in import", current());
          }
          const tryMode = match("keyword", "try");
          expect("keyword", "import");
          let importAll = false;
          const specifiers = [];
          if (match("operator", "*")) {
            if (tryMode) {
              throw new TranspilerSyntaxError(
                "Wildcard import '*' cannot be combined with try import",
                previous()
              );
            }
            importAll = true;
          } else {
            do {
              const imported = expectIdentifier();
              let local = imported;
              if (match("keyword", "as")) {
                local = expectIdentifier("Expected alias name after as");
              }
              specifiers.push({
                type: "ImportSpecifier",
                imported: imported.value,
                local: local.value
              });
            } while (match("punctuation", ","));
          }
          let condition = null;
          if (current().type === "keyword" && ["if", "unless"].includes(current().value)) {
            const keyword = current();
            if (importAll) {
              throw new TranspilerSyntaxError(
                "Wildcard import '*' cannot be combined with postfix if/unless",
                keyword
              );
            }
            index++;
            condition = {
              type: "PostfixCondition",
              keyword: keyword.value,
              test: parseExpression()
            };
          }
          consumeStatementTerminator("Expected ; after import declaration");
          return withLoc({
            type: "ImportDeclaration",
            source: moduleParts.join(""),
            tryMode,
            importAll,
            specifiers,
            condition
          }, start, previous());
        }
        function parseVariableDeclaration() {
          const start = expect("keyword");
          if (current().type === "punctuation" && current().value === "{") {
            return parseVariableUnpackDeclaration(start);
          }
          const declaration = parseVariableDeclarationParts(start);
          consumeStatementTerminator("Expected ; after variable declaration");
          return withLoc({
            type: "VariableDeclaration",
            ...declaration
          }, start, previous());
        }
        function parseVariableDeclarationParts(start) {
          let declaredType = null;
          let id = expectIdentifier();
          if (current().type === "identifier" && ![":=", "=", ";", ",", ")"].includes(current().value)) {
            declaredType = id.value;
            id = expectIdentifier("Expected variable name after type");
          }
          let isWeakStorage = parseOptionalWeakModifier("declaration");
          let init = null;
          if (match("operator", ":=") || match("operator", "=")) {
            init = parseExpression();
            isWeakStorage = parseOptionalWeakModifier("declaration") || isWeakStorage;
          }
          return {
            kind: start.value,
            declaredType,
            id: withLoc({
              type: "Identifier",
              name: id.value
            }, id, id),
            init,
            isWeakStorage
          };
        }
        function parseVariableUnpackDeclaration(start) {
          const pattern = parseDeclarationBindingPattern();
          expect("operator", ":=", "Expected ':=' after declaration binding pattern");
          const init = parseExpression();
          consumeStatementTerminator("Expected ; after variable unpack declaration");
          return withLoc({
            type: "VariableUnpackDeclaration",
            kind: start.value,
            pattern,
            init
          }, start, previous());
        }
        function parseDeclarationBindingPattern() {
          const start = expect("punctuation", "{", "Expected '{' in declaration binding pattern");
          const entries = [];
          if (!match("punctuation", "}")) {
            while (true) {
              if (match("punctuation", ",")) {
                continue;
              }
              if (match("punctuation", "}")) {
                break;
              }
              entries.push(parseDeclarationBindingEntry());
              if (match("punctuation", "}")) {
                break;
              }
              match("punctuation", ",");
            }
          }
          return withLoc({
            type: "KeyedBindingPattern",
            entries
          }, start, previous());
        }
        function parseDeclarationBindingEntry() {
          const start = current();
          const binding = parseDeclarationBindingKeyAndName();
          let defaultValue = null;
          if (match("operator", ":=")) {
            defaultValue = parseExpression();
          }
          const isWeakStorage = parseOptionalWeakModifier("declaration");
          return withLoc({
            type: "DeclarationBindingEntry",
            key: binding.key,
            declaredType: binding.declaredType,
            name: binding.name,
            defaultValue,
            isWeakStorage
          }, start, previous() || start);
        }
        function parseDeclarationBindingKeyAndName() {
          if (current().type === "identifier") {
            const first = current();
            index++;
            if (match("operator", ":")) {
              const typed = parseTypedBindingName();
              return {
                key: bindingIdentifierKey(first),
                declaredType: typed.declaredType,
                name: typed.name
              };
            }
            if (current().type === "identifier" || current().type === "keyword") {
              const name2 = expectIdentifier("Expected unpacked binding name after type");
              return {
                key: bindingIdentifierKey(name2),
                declaredType: first.value,
                name: name2.value
              };
            }
            return {
              key: bindingIdentifierKey(first),
              declaredType: null,
              name: first.value
            };
          }
          if (current().type === "keyword" || current().type === "string") {
            const key = parseDeclarationBindingKey();
            expect("operator", ":", "Expected ':' after declaration binding key");
            const typed = parseTypedBindingName();
            return {
              key,
              declaredType: typed.declaredType,
              name: typed.name
            };
          }
          if (current().type === "template" || current().type === "punctuation" && current().value === "(") {
            const key = parseDeclarationBindingKey();
            expect("operator", ":", "Expected ':' after declaration binding key");
            const typed = parseTypedBindingName();
            return {
              key,
              declaredType: typed.declaredType,
              name: typed.name
            };
          }
          throw new TranspilerSyntaxError("Expected unpacked binding in declaration", current());
        }
        function parseTypedBindingName() {
          let declaredType = null;
          let name2 = expectIdentifier("Expected unpacked binding name");
          if (current().type === "identifier") {
            declaredType = name2.value;
            name2 = expectIdentifier("Expected unpacked binding name after type");
          }
          return {
            declaredType,
            name: name2.value
          };
        }
        function bindingIdentifierKey(token) {
          return withLoc({
            type: "BraceIdentifier",
            name: token.value
          }, token, token);
        }
        function parseDeclarationBindingKey() {
          const token = current();
          if (token.type === "identifier" || token.type === "keyword") {
            index++;
            return withLoc({
              type: "BraceIdentifier",
              name: token.value
            }, token, token);
          }
          if (token.type === "string") {
            index++;
            return withLoc({
              type: "StringLiteral",
              value: token.value
            }, token, token);
          }
          if (token.type === "template") {
            return parsePrimary();
          }
          if (match("punctuation", "(")) {
            const expr = parseExpression();
            expect("punctuation", ")", "Expected ) after declaration binding key");
            return expr;
          }
          throw new TranspilerSyntaxError("Expected declaration binding key", token);
        }
        function parseFunctionDeclaration() {
          let isAsync = false;
          let start = current();
          if (match("keyword", "async")) {
            isAsync = true;
            start = previous();
          }
          expect("keyword", "function");
          const id = expectIdentifier();
          if (match("punctuation", ";")) {
            return withLoc({
              type: "FunctionDeclaration",
              id: {
                type: "Identifier",
                name: id.value
              },
              params: [],
              returnType: null,
              isAsync,
              isPredeclared: true,
              body: withLoc({
                type: "BlockStatement",
                body: []
              }, id, id)
            }, start, previous());
          }
          const params = parseParameterList();
          const returnType = parseOptionalReturnType();
          const body = parseBlockInAsyncContext(isAsync);
          return withLoc({
            type: "FunctionDeclaration",
            id: {
              type: "Identifier",
              name: id.value
            },
            params,
            returnType,
            isAsync,
            isPredeclared: false,
            body
          }, start, previous());
        }
        function parseFunctionDeclarationLikeFn(isAsync = false, startOverride = null) {
          const start = startOverride || current();
          expect("keyword", "fn");
          const id = expectIdentifier();
          const params = parseParameterList();
          const returnType = parseOptionalReturnType();
          const body = parseBlockInAsyncContext(isAsync);
          return withLoc({
            type: "FunctionDeclaration",
            id: {
              type: "Identifier",
              name: id.value
            },
            params,
            returnType,
            isAsync,
            body
          }, start, previous());
        }
        function parseClassDeclaration() {
          const start = expect("keyword", "class");
          const id = expectIdentifier("Expected class name");
          let base = null;
          if (match("keyword", "extends")) {
            const baseId = expectIdentifier("Expected base class name after extends");
            base = withLoc({
              type: "Identifier",
              name: baseId.value
            }, baseId, baseId);
          }
          const traits = parseTraitCompositionList();
          if (match("punctuation", ";")) {
            return withLoc({
              type: "ClassDeclaration",
              id: withLoc({
                type: "Identifier",
                name: id.value
              }, id, id),
              base,
              traits,
              body: [],
              shorthand: true
            }, start, previous());
          }
          expect("punctuation", "{", "Expected { to start class body");
          const body = [];
          while (!(current().type === "punctuation" && current().value === "}")) {
            if (atEnd()) {
              throw new TranspilerSyntaxError("Unterminated class declaration", current());
            }
            if (current().type === "punctuation" && current().value === ";") {
              index++;
              continue;
            }
            body.push(parseClassMember());
          }
          expect("punctuation", "}");
          return withLoc({
            type: "ClassDeclaration",
            id: withLoc({
              type: "Identifier",
              name: id.value
            }, id, id),
            base,
            traits,
            body,
            shorthand: false
          }, start, previous());
        }
        function parseTraitDeclaration() {
          const start = expect("keyword", "trait");
          const id = expectIdentifier("Expected trait name");
          expect("punctuation", "{", "Expected { to start trait body");
          const body = [];
          while (!(current().type === "punctuation" && current().value === "}")) {
            if (atEnd()) {
              throw new TranspilerSyntaxError("Unterminated trait declaration", current());
            }
            if (current().type === "punctuation" && current().value === ";") {
              index++;
              continue;
            }
            body.push(parseMethodDeclaration({ allowStatic: false }));
          }
          expect("punctuation", "}");
          return withLoc({
            type: "TraitDeclaration",
            id: withLoc({
              type: "Identifier",
              name: id.value
            }, id, id),
            body
          }, start, previous());
        }
        function parseTraitCompositionList() {
          const traits = [];
          if (current().type === "keyword" && ["with", "but"].includes(current().value)) {
            index++;
            do {
              const traitId = expectIdentifier("Expected trait name");
              traits.push(withLoc({
                type: "Identifier",
                name: traitId.value
              }, traitId, traitId));
            } while (match("punctuation", ","));
          }
          return traits;
        }
        function parseOptionalWeakModifier(context) {
          if (current().type !== "keyword" || current().value !== "but") {
            return false;
          }
          index++;
          const modifier = current();
          if (!(modifier.type === "identifier" || modifier.type === "keyword") || modifier.value !== "weak") {
            throw new TranspilerSyntaxError(
              `Unknown but modifier '${modifier.value || ""}' in ${context}; expected 'but weak'`,
              modifier
            );
          }
          index++;
          return true;
        }
        function parseClassMember() {
          if (current().type === "keyword" && ["static", "async"].includes(current().value)) {
            return parseMethodDeclaration({ allowStatic: true });
          }
          if (current().type === "keyword" && current().value === "method") {
            return parseMethodDeclaration({ allowStatic: true });
          }
          if (current().type === "keyword" && ["let", "const"].includes(current().value)) {
            return parseFieldDeclaration();
          }
          if (current().type === "keyword" && current().value === "class") {
            return parseClassDeclaration();
          }
          if (current().type === "keyword" && current().value === "trait") {
            return parseTraitDeclaration();
          }
          throw new UnsupportedSyntaxError("Unsupported class member", current());
        }
        function parseMethodDeclaration({ allowStatic = true } = {}) {
          const start = current();
          let isStatic = false;
          let isAsync = false;
          while (current().type === "keyword" && ["static", "async"].includes(current().value)) {
            if (current().value === "static") {
              if (!allowStatic || isStatic) {
                break;
              }
              isStatic = true;
              index++;
              continue;
            }
            if (isAsync) {
              break;
            }
            isAsync = true;
            index++;
          }
          expect("keyword", "method", "Expected method declaration");
          const id = expectIdentifier("Expected method name");
          if (match("punctuation", ";")) {
            return withLoc({
              type: "MethodDeclaration",
              id: withLoc({
                type: "Identifier",
                name: id.value
              }, id, id),
              params: [],
              returnType: null,
              body: withLoc({
                type: "BlockStatement",
                body: []
              }, id, id),
              static: isStatic,
              isAsync,
              isPredeclared: true
            }, start, previous());
          }
          const params = parseParameterList();
          const returnType = parseOptionalReturnType();
          const body = parseBlockInAsyncContext(isAsync);
          return withLoc({
            type: "MethodDeclaration",
            id: withLoc({
              type: "Identifier",
              name: id.value
            }, id, id),
            params,
            returnType,
            body,
            static: isStatic,
            isAsync,
            isPredeclared: false
          }, start, previous());
        }
        function parseFieldDeclaration() {
          const start = expect("keyword");
          let typeName2 = null;
          let id = expectIdentifier("Expected field name");
          if (current().type === "identifier" && current().value !== "with" && !(current().type === "operator" && current().value === ":=") && !(current().type === "punctuation" && [";", "}"].includes(current().value))) {
            typeName2 = id.value;
            id = expectIdentifier("Expected field name after type");
          }
          const accessors = [];
          if (match("keyword", "with")) {
            do {
              accessors.push(expectIdentifier("Expected accessor name").value);
            } while (match("punctuation", ","));
          }
          let isWeakStorage = parseOptionalWeakModifier("field declaration");
          let defaultValue = null;
          if (match("operator", ":=")) {
            defaultValue = parseExpression();
            isWeakStorage = parseOptionalWeakModifier("field declaration") || isWeakStorage;
          }
          consumeStatementTerminator("Expected ; after field declaration");
          return withLoc({
            type: "FieldDeclaration",
            kind: start.value,
            typeName: typeName2,
            id: withLoc({
              type: "Identifier",
              name: id.value
            }, id, id),
            accessors,
            defaultValue,
            isWeakStorage
          }, start, previous());
        }
        function parseParameterList() {
          expect("punctuation", "(");
          const params = [];
          if (!match("punctuation", ")")) {
            while (true) {
              if (match("punctuation", ",")) {
                continue;
              }
              params.push(parseParameter());
              if (match("punctuation", ")")) {
                break;
              }
              if (match("punctuation", ",") && match("punctuation", ")")) {
                break;
              }
            }
          }
          return params;
        }
        function parseParameter() {
          const start = current();
          let rest = false;
          if (match("operator", "...")) {
            if (current().type === "identifier" && peekToken().type === "identifier") {
              const containerType = expectIdentifier("Expected parameter type after ...");
              const id2 = expectIdentifier("Expected parameter name");
              return withLoc({
                type: "SpecialParameter",
                special: "rest_only",
                leadName: null,
                containerType: containerType.value,
                name: id2.value
              }, start, previous() || start);
            }
            rest = true;
          }
          let typeName2 = null;
          let id = expectIdentifier("Expected parameter name");
          if (!rest && current().type === "operator" && current().value === "...") {
            index++;
            const first = expectIdentifier("Expected parameter type or name after ...");
            let containerType;
            let target;
            if (current().type === "identifier" && !["?", ":=", ",", ")"].includes(current().value)) {
              containerType = first.value;
              target = expectIdentifier("Expected parameter name after special variadic type");
            } else {
              containerType = "Array";
              target = first;
            }
            return withLoc({
              type: "SpecialParameter",
              special: "lead_rest",
              leadName: id.value,
              containerType,
              name: target.value
            }, start, previous() || start);
          }
          if (!rest && current().type === "identifier" && !["?", ":=", ",", ")"].includes(current().value) && peekToken().type !== "identifier") {
            typeName2 = id.value;
            id = expectIdentifier("Expected parameter name after type");
          }
          let optional = false;
          let defaultValue = null;
          if (match("operator", "?")) {
            optional = true;
          }
          if (match("operator", ":=")) {
            defaultValue = parseExpression();
          }
          return withLoc({
            type: "Parameter",
            name: id.value,
            typeName: typeName2,
            optional,
            defaultValue,
            rest
          }, start, previous() || start);
        }
        function parseOptionalReturnType() {
          if (current().type === "operator" && (current().value === "->" || current().value === "\u2192")) {
            index++;
            return expectIdentifier("Expected return type after ->").value;
          }
          return null;
        }
        function parseReturnStatement() {
          const start = expect("keyword", "return");
          let argument = null;
          if (!(current().type === "punctuation" && current().value === ";") && !(current().type === "keyword" && ["if", "unless"].includes(current().value))) {
            argument = parseExpression();
          }
          const stmt = withLoc({
            type: "ReturnStatement",
            argument
          }, start, previous() || start);
          return finishStatement(stmt, "Expected ; after return statement");
        }
        function parseIfStatement() {
          const start = expect("keyword", "if");
          expect("punctuation", "(");
          let declaration = null;
          let test = null;
          if (current().type === "keyword" && ["let", "const"].includes(current().value)) {
            declaration = parseInlineVariableDeclaration();
            test = declaration.id;
          } else {
            test = parseExpression();
          }
          expect("punctuation", ")", "Expected ) after if condition");
          const consequent = parseBlockStatement();
          let alternate = null;
          if (match("keyword", "else")) {
            if (current().type === "keyword" && current().value === "if") {
              alternate = parseIfStatement();
            } else {
              alternate = parseBlockStatement();
            }
          }
          return withLoc({
            type: "IfStatement",
            declaration,
            test,
            consequent,
            alternate
          }, start, previous());
        }
        function parseForStatement() {
          const start = expect("keyword", "for");
          expect("punctuation", "(");
          let decl = null;
          let id = null;
          let iterable;
          if (current().type === "keyword" && ["let", "const"].includes(current().value)) {
            decl = expect("keyword");
            id = expectIdentifier("Expected loop variable");
            expect("keyword", "in", "Expected in inside for loop");
            iterable = parseExpression();
          } else if (current().type === "identifier" && peekToken().type === "keyword" && peekToken().value === "in") {
            id = expectIdentifier("Expected loop variable");
            expect("keyword", "in", "Expected in inside for loop");
            iterable = parseExpression();
          } else {
            decl = { value: "const" };
            id = {
              value: "^^",
              start: current().start,
              end: current().end,
              line: current().line,
              column: current().column
            };
            iterable = parseExpression();
          }
          expect("punctuation", ")", "Expected ) after for loop header");
          const body = parseBlockStatement();
          let elseBlock = null;
          if (match("keyword", "else")) {
            elseBlock = parseBlockStatement();
          }
          return withLoc({
            type: "ForInStatement",
            kind: decl ? decl.value : null,
            left: {
              type: "Identifier",
              name: id.value
            },
            iterable,
            body,
            elseBlock
          }, start, previous());
        }
        function parseWhileStatement() {
          const start = expect("keyword", "while");
          expect("punctuation", "(");
          let declaration = null;
          let test = null;
          if (current().type === "keyword" && ["let", "const"].includes(current().value)) {
            declaration = parseInlineVariableDeclaration();
            test = declaration.id;
          } else {
            test = parseExpression();
          }
          expect("punctuation", ")", "Expected ) after while condition");
          const body = parseBlockStatement();
          return withLoc({
            type: "WhileStatement",
            declaration,
            test,
            body
          }, start, previous());
        }
        function parseSwitchStatement() {
          const start = expect("keyword", "switch");
          expect("punctuation", "(");
          const discriminant = parseExpression();
          let comparator = "==";
          if (match("operator", ":")) {
            const token = current();
            if (!["identifier", "keyword", "operator", "string"].includes(token.type)) {
              throw new TranspilerSyntaxError("Expected switch comparator after :", token);
            }
            index++;
            comparator = token.value;
          }
          expect("punctuation", ")", "Expected ) after switch header");
          expect("punctuation", "{", "Expected { to start switch body");
          const cases = [];
          let defaultCase = null;
          while (!(current().type === "punctuation" && current().value === "}")) {
            if (atEnd()) {
              throw new TranspilerSyntaxError("Unterminated switch statement", current());
            }
            if (current().type === "keyword" && current().value === "case") {
              cases.push(parseSwitchCase());
              continue;
            }
            if (current().type === "keyword" && current().value === "default") {
              if (defaultCase) {
                throw new TranspilerSyntaxError("Duplicate default clause in switch statement", current());
              }
              defaultCase = parseSwitchDefaultCase();
              continue;
            }
            throw new TranspilerSyntaxError("Expected case or default inside switch statement", current());
          }
          expect("punctuation", "}");
          return withLoc({
            type: "SwitchStatement",
            discriminant,
            comparator,
            cases,
            defaultCase
          }, start, previous());
        }
        function parseSwitchCase() {
          const start = expect("keyword", "case");
          const values = [parseExpression()];
          while (match("punctuation", ",")) {
            values.push(parseExpression());
          }
          expect("operator", ":", "Expected : after switch case");
          const consequent = parseSwitchConsequent(start);
          return withLoc({
            type: "SwitchCase",
            values,
            consequent
          }, start, endLocFromNode(consequent));
        }
        function parseSwitchDefaultCase() {
          const start = expect("keyword", "default");
          expect("operator", ":", "Expected : after default");
          const consequent = parseSwitchConsequent(start);
          return withLoc({
            type: "SwitchCase",
            values: null,
            consequent
          }, start, endLocFromNode(consequent));
        }
        function parseSwitchConsequent(startToken) {
          const body = [];
          while (true) {
            if (atEnd()) {
              throw new TranspilerSyntaxError("Unterminated switch case body", current());
            }
            if (current().type === "punctuation" && current().value === "}") {
              break;
            }
            if (current().type === "keyword" && ["case", "default"].includes(current().value)) {
              break;
            }
            body.push(parseStatement());
          }
          return withLoc({
            type: "BlockStatement",
            body
          }, startToken, previous() || startToken);
        }
        function parseInlineVariableDeclaration() {
          const start = expect("keyword");
          const declaration = parseVariableDeclarationParts(start);
          return withLoc({
            type: "VariableDeclaration",
            ...declaration
          }, start, previous());
        }
        function parseLoopControlStatement(type) {
          const start = expect("keyword");
          const stmt = withLoc({ type }, start, previous() || start);
          return finishStatement(stmt, `Expected ; after ${start.value}`);
        }
        function parseThrowStatement() {
          const start = expect("keyword", "throw");
          const argument = parseExpression();
          const stmt = withLoc({
            type: "ThrowStatement",
            argument
          }, start, previous());
          return finishStatement(stmt, "Expected ; after throw statement");
        }
        function parseDieStatement() {
          const start = expect("keyword", "die");
          const argument = parseExpression();
          const stmt = withLoc({
            type: "DieStatement",
            argument
          }, start, previous());
          return finishStatement(stmt, "Expected ; after die statement");
        }
        function parseWarnStatement() {
          const start = expect("keyword", "warn");
          const argument = parseExpression();
          const stmt = withLoc({
            type: "WarnStatement",
            argument
          }, start, previous());
          return finishStatement(stmt, "Expected ; after warn statement");
        }
        function parseAssertStatement() {
          const start = expect("keyword", "assert");
          const argument = parseExpression();
          const stmt = withLoc({
            type: "AssertStatement",
            argument
          }, start, previous());
          return finishStatement(stmt, "Expected ; after assert statement");
        }
        function parseDebugStatement() {
          const start = expect("keyword", "debug");
          const argumentsList = [];
          if (!(current().type === "punctuation" && current().value === ";")) {
            argumentsList.push(parseExpression());
            while (match("punctuation", ",")) {
              argumentsList.push(parseExpression());
            }
          }
          const stmt = withLoc({
            type: "DebugStatement",
            arguments: argumentsList
          }, start, previous() || start);
          return finishStatement(stmt, "Expected ; after debug statement");
        }
        function parseSayStatement() {
          const start = expect("keyword", "say");
          const args = [];
          if (!(current().type === "punctuation" && current().value === ";")) {
            args.push(parseExpression());
            while (match("punctuation", ",")) {
              args.push(parseExpression());
            }
          }
          const stmt = withLoc({
            type: "ExpressionStatement",
            expression: withLoc({
              type: "CallExpression",
              callee: withLoc({
                type: "Identifier",
                name: "say"
              }, start, start),
              arguments: args
            }, start, previous() || start)
          }, start, previous() || start);
          return finishStatement(stmt, "Expected ; after say statement");
        }
        function parseTryStatement() {
          const parsed = parseTryLike();
          return withLoc({
            type: "TryStatement",
            block: parsed.block,
            handlers: parsed.handlers
          }, parsed.start, previous());
        }
        function parseTryLike() {
          const start = expect("keyword", "try");
          const block = parseBlockStatement();
          const handlers = [];
          while (current().type === "keyword" && current().value === "catch") {
            const catchTok = expect("keyword", "catch");
            let typeName2 = "Exception";
            let paramName = "e";
            if (match("punctuation", "(")) {
              if (current().type === "identifier") {
                const first = current();
                index++;
                if (current().type === "identifier") {
                  typeName2 = first.value;
                  paramName = current().value;
                  index++;
                } else {
                  paramName = first.value;
                }
              }
              expect("punctuation", ")", "Expected ) after catch clause");
            }
            const handlerBody = parseBlockStatement();
            handlers.push(withLoc({
              type: "CatchClause",
              typeName: typeName2,
              paramName,
              body: handlerBody
            }, catchTok, previous()));
          }
          return {
            start,
            block,
            handlers
          };
        }
        function parseBlockStatement() {
          const start = expect("punctuation", "{");
          const body = [];
          while (!(current().type === "punctuation" && current().value === "}")) {
            if (atEnd()) {
              throw new TranspilerSyntaxError("Unterminated block statement", current());
            }
            body.push(parseStatement());
          }
          expect("punctuation", "}");
          return withLoc({
            type: "BlockStatement",
            body
          }, start, previous());
        }
        function parseBlockInAsyncContext(isAsync) {
          const previousDepth = asyncContextDepth;
          asyncContextDepth = isAsync ? previousDepth + 1 : 0;
          try {
            return parseBlockStatement();
          } finally {
            asyncContextDepth = previousDepth;
          }
        }
        function parseExpressionStatement() {
          const start = current();
          const expression = parseExpression();
          const stmt = withLoc({
            type: "ExpressionStatement",
            expression
          }, start, previous());
          return finishStatement(stmt, "Expected ; after expression");
        }
        function finishStatement(stmt, semicolonMessage) {
          if (current().type === "keyword" && ["if", "unless"].includes(current().value)) {
            const keyword = current();
            index++;
            let test = parseExpression();
            if (keyword.value === "unless") {
              test = withLoc({
                type: "UnaryExpression",
                operator: "not",
                argument: test,
                prefix: true
              }, keyword, endLocFromNode(test));
            }
            consumeStatementTerminator(semicolonMessage);
            const consequent = withLoc({
              type: "BlockStatement",
              body: [stmt]
            }, startLocFromNode(stmt), endLocFromNode(stmt));
            return withLoc({
              type: "IfStatement",
              declaration: null,
              test,
              consequent,
              alternate: null
            }, startLocFromNode(stmt), endLocFromNode(consequent));
          }
          if (current().type === "keyword" && current().value === "for") {
            const keyword = current();
            index++;
            const iterable = parseExpression();
            consumeStatementTerminator(semicolonMessage);
            const body = withLoc({
              type: "BlockStatement",
              body: [stmt]
            }, startLocFromNode(stmt), endLocFromNode(stmt));
            return withLoc({
              type: "ForInStatement",
              kind: "const",
              left: {
                type: "Identifier",
                name: "^^"
              },
              iterable,
              body,
              elseBlock: null
            }, startLocFromNode(stmt), endLocFromNode(iterable) || keyword);
          }
          consumeStatementTerminator(semicolonMessage);
          return stmt;
        }
        function parseExpression() {
          return parseAssignment();
        }
        function parseConditional() {
          return parseConditionalTail(parseLogicalOr());
        }
        function parseConditionalTail(expr) {
          if (match("operator", "?:")) {
            const alternate = parseConditional();
            return withLoc({
              type: "ShortTernaryExpression",
              test: expr,
              alternate
            }, startLocFromNode(expr), endLocFromNode(alternate));
          }
          if (match("operator", "?")) {
            const consequent = parseExpression();
            expect("operator", ":", "Expected : in ternary expression");
            const alternate = parseConditional();
            return withLoc({
              type: "ConditionalExpression",
              test: expr,
              consequent,
              alternate
            }, startLocFromNode(expr), endLocFromNode(alternate));
          }
          return expr;
        }
        function parseAssignment() {
          const left = parseChain();
          if (current().type === "operator" && [":=", "+=", "-=", "*=", "/=", "%=", "**=", "_=", "?:=", "\xD7=", "\xF7="].includes(current().value)) {
            const op = current();
            index++;
            const right = parseAssignment();
            const isWeakWrite = parseOptionalWeakModifier("assignment");
            if (isWeakWrite && op.value !== ":=") {
              throw new TranspilerSyntaxError(
                "but weak is only valid on ':=' assignments",
                op
              );
            }
            if (isWeakWrite && left && left.type === "BinaryExpression" && left.operator === "@?") {
              throw new TranspilerSyntaxError(
                "but weak is not valid on @? path assignments",
                op
              );
            }
            return withLoc({
              type: "AssignmentExpression",
              operator: op.value,
              left,
              right,
              isWeakWrite
            }, startLocFromNode(left), endLocFromNode(right));
          }
          if (current().type === "operator" && current().value === "~=") {
            const op = current();
            index++;
            const pattern = parseChain();
            if (current().type !== "operator" || !(current().value === "->" || current().value === "\u2192")) {
              throw new TranspilerSyntaxError("Expected -> after regex replacement pattern", current());
            }
            index++;
            const replacement = parseAssignment();
            return withLoc({
              type: "RegexReplaceExpression",
              operator: op.value,
              left,
              pattern,
              replacement
            }, startLocFromNode(left), endLocFromNode(replacement));
          }
          return left;
        }
        function chainDirection(token) {
          if (token.type !== "operator") {
            return null;
          }
          if (token.value === "\u25B7" || token.value === "|>") {
            return "right";
          }
          if (token.value === "\u25C1" || token.value === "<|") {
            return "left";
          }
          return null;
        }
        function parseChain() {
          let expr = parseConditional();
          const firstDirection = chainDirection(current());
          if (!firstDirection) {
            return expr;
          }
          let op = current();
          index++;
          const right = firstDirection === "left" ? parseLeftwardChainRhs() : parseConditional();
          expr = withLoc({
            type: "BinaryExpression",
            operator: op.value,
            left: expr,
            right
          }, startLocFromNode(expr), endLocFromNode(right));
          while (firstDirection === "right") {
            const nextDirection = chainDirection(current());
            if (!nextDirection) {
              break;
            }
            if (nextDirection !== firstDirection) {
              throw new TranspilerSyntaxError("Mixed chain directions require parentheses", current());
            }
            op = current();
            index++;
            const nextRight = parseConditional();
            expr = withLoc({
              type: "BinaryExpression",
              operator: op.value,
              left: expr,
              right: nextRight
            }, startLocFromNode(expr), endLocFromNode(nextRight));
          }
          if (firstDirection === "left" && chainDirection(current())) {
            throw new TranspilerSyntaxError("Mixed chain directions require parentheses", current());
          }
          return expr;
        }
        function parseLeftwardChainRhs() {
          const left = parseConditional();
          const direction = chainDirection(current());
          if (!direction) {
            return left;
          }
          if (direction !== "left") {
            throw new TranspilerSyntaxError("Mixed chain directions require parentheses", current());
          }
          const op = current();
          index++;
          const right = parseLeftwardChainRhs();
          return withLoc({
            type: "BinaryExpression",
            operator: op.value,
            left,
            right
          }, startLocFromNode(left), endLocFromNode(right));
        }
        function parseLogicalOr() {
          return parseLeftAssociative(
            parseLogicalAnd,
            (token) => token.type === "keyword" && ["or", "xor", "nand"].includes(token.value) || token.type === "operator" && ["\u22C1", "\u22BB", "\u22BC"].includes(token.value)
          );
        }
        function parseLogicalAnd() {
          return parseLeftAssociative(
            parseEquality,
            (token) => token.type === "keyword" && token.value === "and" || token.type === "operator" && token.value === "\u22C0"
          );
        }
        function parseEquality() {
          return parseLeftAssociative(
            parseBitwise,
            (token) => token.type === "operator" && ["==", "!=", "="].includes(token.value) || token.type === "operator" && ["\u2261", "\u2262", "\u2260"].includes(token.value) || token.type === "keyword" && ["eq", "ne", "default"].includes(token.value)
          );
        }
        function parseBitwise() {
          return parseLeftAssociative(
            parseComparison,
            (token) => token.type === "operator" && ["&", "|", "^"].includes(token.value)
          );
        }
        function parseComparison() {
          return parseLeftAssociative(
            parseRange,
            (token) => token.type === "operator" && ["<", "<=", ">", ">=", "\u2264", "\u2265", "~", "<=>", "@", "@@", "@?", "\\", "\u2208", "\u2209", "\u22C3", "\u22C2", "\u2216", "\u2282", "\u2283", "\u2282\u2283", "\u2276", "\u2277"].includes(token.value) || token.type === "keyword" && ["gt", "ge", "lt", "le", "cmp", "eqi", "nei", "gti", "gei", "lti", "lei", "cmpi", "in", "not_in", "union", "intersection", "difference", "subsetof", "supersetof", "equivalentof", "does", "can"].includes(token.value) || token.type === "identifier" && token.value === "instanceof"
          );
        }
        function parseRange() {
          return parseLeftAssociative(
            parseTerm,
            (token) => token.type === "operator" && token.value === "..."
          );
        }
        function parseTerm() {
          return parseLeftAssociative(
            parseFactor,
            (token) => token.type === "operator" && ["+", "-", "_"].includes(token.value)
          );
        }
        function parseFactor() {
          return parseLeftAssociative(
            parseUnary,
            (token) => token.type === "operator" && ["*", "/", "%", "**"].includes(token.value) || token.type === "operator" && ["\xD7", "\xF7"].includes(token.value) || token.type === "keyword" && token.value === "mod"
          );
        }
        function parseLeftAssociative(nextFn, predicate) {
          let expr = nextFn();
          while (predicate(current())) {
            const op = current();
            index++;
            const right = nextFn();
            expr = withLoc({
              type: "BinaryExpression",
              operator: op.value,
              left: expr,
              right
            }, startLocFromNode(expr), endLocFromNode(right));
          }
          return expr;
        }
        function parseUnary() {
          if (current().type === "operator" && ["-", "+", "++", "--", "!", "~", "\\", "\u221A", "\xAC"].includes(current().value) || current().type === "keyword" && ["not", "typeof", "abs", "sqrt", "floor", "ceil", "round", "int", "length", "uc", "lc"].includes(current().value)) {
            const op = current();
            index++;
            const argument = op.value === "\\" ? parseReferenceTarget() : parseUnary();
            let expr = withLoc({
              type: op.value === "\\" ? "RefExpression" : "UnaryExpression",
              operator: op.value,
              argument,
              prefix: true
            }, startLocFromToken(op), endLocFromNode(argument));
            if (op.value === "\\") {
              expr = parsePostfixSuffixes(expr);
            }
            return expr;
          }
          return parsePostfix();
        }
        function parseReferenceTarget() {
          let expr = parsePrimary();
          while (true) {
            const nextExpr = parseMemberAccess(expr);
            if (nextExpr === expr) {
              break;
            }
            expr = nextExpr;
          }
          return expr;
        }
        function parsePostfix() {
          return parsePostfixSuffixes(parsePrimary());
        }
        function parsePostfixSuffixes(expr) {
          while (true) {
            const nextExpr = parseMemberAccess(expr);
            if (nextExpr !== expr) {
              expr = nextExpr;
              continue;
            }
            if (current().type === "punctuation" && current().value === "(") {
              const args = parseCallArgumentsOnly();
              expr = withLoc({
                type: "CallExpression",
                callee: expr,
                arguments: args
              }, startLocFromNode(expr), endLocFromToken(previous()));
              continue;
            }
            if (current().type === "operator" && ["++", "--"].includes(current().value)) {
              const op = current();
              index++;
              expr = withLoc({
                type: "UpdateExpression",
                operator: op.value,
                argument: expr,
                prefix: false
              }, startLocFromNode(expr), endLocFromToken(op));
              continue;
            }
            break;
          }
          return expr;
        }
        function parseMemberAccess(expr) {
          if (match("punctuation", ".")) {
            if (match("punctuation", "(")) {
              const property2 = parseExpression();
              expect("punctuation", ")", "Expected ) after dynamic member name");
              return withLoc({
                type: "MemberExpression",
                object: expr,
                property: property2,
                computed: true
              }, startLocFromNode(expr), endLocFromToken(previous()));
            }
            const property = expectIdentifier("Expected property name after .");
            return withLoc({
              type: "MemberExpression",
              object: expr,
              property: {
                type: "Identifier",
                name: property.value
              },
              computed: false
            }, startLocFromNode(expr), endLocFromToken(property));
          }
          if (match("punctuation", "[")) {
            const closeBracket = current().type === "punctuation" && current().value === "]";
            const startsWithColon = current().type === "operator" && current().value === ":";
            let first = null;
            if (!closeBracket && !startsWithColon) {
              first = parseExpression();
            }
            if (match("operator", ":")) {
              let second = null;
              if (!(current().type === "punctuation" && current().value === "]")) {
                second = parseExpression();
              }
              expect("punctuation", "]");
              return withLoc({
                type: "SliceExpression",
                object: expr,
                start: first,
                length: second
              }, startLocFromNode(expr), endLocFromToken(previous()));
            }
            if (first == null) {
              throw new TranspilerSyntaxError("Expected index or slice expression", current());
            }
            expect("punctuation", "]");
            return withLoc({
              type: "MemberExpression",
              object: expr,
              property: first,
              computed: true
            }, startLocFromNode(expr), endLocFromToken(previous()));
          }
          if (match("punctuation", "{")) {
            let property;
            if ((current().type === "identifier" || current().type === "keyword") && peekToken().type === "punctuation" && peekToken().value === "}") {
              const key = current();
              index++;
              property = withLoc(
                key.type === "identifier" ? {
                  type: "BraceIdentifier",
                  name: key.value
                } : {
                  type: "StringLiteral",
                  value: key.value
                },
                key,
                key
              );
            } else {
              property = parseExpression();
            }
            expect("punctuation", "}");
            return withLoc({
              type: "MemberExpression",
              object: expr,
              property,
              computed: true
            }, startLocFromNode(expr), endLocFromToken(previous()));
          }
          return expr;
        }
        function parseCallArgumentsOnly() {
          expect("punctuation", "(");
          const args = [];
          let closed = false;
          if (!match("punctuation", ")")) {
            while (true) {
              if (match("punctuation", ",")) {
                if (current().type === "punctuation" && current().value === ")") {
                  break;
                }
                continue;
              }
              if (current().type === "punctuation" && current().value === ")") {
                break;
              }
              args.push(parseCallArgument());
              if (match("punctuation", ")")) {
                closed = true;
                break;
              }
              match("punctuation", ",");
            }
            if (!closed && current().type === "punctuation" && current().value === ")") {
              expect("punctuation", ")", "Expected ) after call arguments");
            }
          }
          return args;
        }
        function parseCallArgument() {
          const start = current();
          if (match("operator", "...")) {
            const argument = parseExpression();
            return withLoc({
              type: "SpreadArgument",
              argument
            }, start, endLocFromNode(argument));
          }
          const expr = parseExpression();
          if (current().type === "keyword" && current().value === "but") {
            throw new TranspilerSyntaxError(
              "but weak is not valid as a function argument marker",
              current()
            );
          }
          if (current().type === "operator" && current().value === ":") {
            const normalized = normalizeNamedArgumentKey(expr);
            expect("operator", ":", "Expected : in named argument");
            const value = parseExpression();
            return withLoc({
              type: "NamedArgument",
              key: normalized.key,
              keyExpr: normalized.keyExpr,
              value
            }, startLocFromNode(expr), previous());
          }
          return expr;
        }
        function normalizeNamedArgumentKey(expr) {
          if (expr.type === "Identifier") {
            return {
              key: expr.name,
              keyExpr: withLoc({
                type: "StringLiteral",
                value: expr.name
              }, startLocFromNode(expr), endLocFromNode(expr))
            };
          }
          if (expr.type === "StringLiteral") {
            return {
              key: expr.value,
              keyExpr: expr
            };
          }
          if (expr.type === "GroupedExpression") {
            return normalizeNamedArgumentKey(expr.expression);
          }
          if (expr.type === "MemberExpression") {
            if (expr.computed && expr.property.type === "StringLiteral") {
              return {
                key: expr.property.value,
                keyExpr: withLoc({
                  type: "StringLiteral",
                  value: expr.property.value
                }, startLocFromNode(expr.property), endLocFromNode(expr.property))
              };
            }
            if (!expr.computed && expr.property.type === "Identifier") {
              return {
                key: expr.property.name,
                keyExpr: withLoc({
                  type: "StringLiteral",
                  value: expr.property.name
                }, startLocFromNode(expr.property), endLocFromNode(expr.property))
              };
            }
          }
          return {
            key: null,
            keyExpr: expr
          };
        }
        function parsePrimary() {
          const token = current();
          if (match("number")) {
            return withLoc({
              type: "NumericLiteral",
              value: Number(token.value)
            }, token, token);
          }
          if (match("string")) {
            return withLoc({
              type: "StringLiteral",
              value: token.value
            }, token, token);
          }
          if (match("binary_string")) {
            return withLoc({
              type: "BinaryStringLiteral",
              value: token.value
            }, token, token);
          }
          if (match("template")) {
            const parts = parseInterpolationParts(token.value, token);
            return withLoc({
              type: "TemplateLiteral",
              parts
            }, token, token);
          }
          if (match("regexp")) {
            return withLoc({
              type: "RegExpLiteral",
              pattern: token.value.pattern,
              parts: parseInterpolationParts(token.value.parts || [], token),
              flags: token.value.flags
            }, token, token);
          }
          if (token.type === "keyword" && ["true", "false", "null"].includes(token.value)) {
            index++;
            return withLoc({
              type: "Literal",
              value: token.value === "null" ? null : token.value === "true"
            }, token, token);
          }
          if (token.type === "keyword" && token.value === "super") {
            index++;
            return withLoc({
              type: "Super"
            }, token, token);
          }
          if (match("identifier")) {
            return withLoc({
              type: "Identifier",
              name: token.value
            }, token, token);
          }
          if (token.type === "keyword" && token.value === "say") {
            index++;
            return withLoc({
              type: "Identifier",
              name: token.value
            }, token, token);
          }
          if (token.type === "keyword" && token.value === "function") {
            index++;
            const params = parseParameterList();
            const body = parseBlockInAsyncContext(false);
            return withLoc({
              type: "FunctionExpression",
              params,
              isAsync: false,
              body
            }, token, previous());
          }
          if (token.type === "keyword" && token.value === "async") {
            index++;
            if (current().type === "keyword" && current().value === "function") {
              const functionToken = current();
              index++;
              const params = parseParameterList();
              const body = parseBlockInAsyncContext(true);
              return withLoc({
                type: "FunctionExpression",
                params,
                isAsync: true,
                body
              }, token, previous() || functionToken);
            }
            if (current().type === "keyword" && current().value === "fn") {
              return parseFnExpression(token, true);
            }
            throw new TranspilerSyntaxError("Expected function or fn after async", current());
          }
          if (token.type === "keyword" && token.value === "fn") {
            return parseFnExpression(token, false);
          }
          if (token.type === "operator" && (token.value === "->" || token.value === "\u2192")) {
            return parseArrowLambdaExpression(token);
          }
          if (token.type === "keyword" && token.value === "await") {
            if (asyncContextDepth <= 0) {
              throw new TranspilerSyntaxError("await may only be used inside async code", token);
            }
            index++;
            const block = parseBlockStatement();
            return withLoc({
              type: "AwaitExpression",
              block
            }, token, previous());
          }
          if (token.type === "keyword" && token.value === "spawn") {
            if (asyncContextDepth <= 0) {
              throw new TranspilerSyntaxError("spawn may only be used inside async code", token);
            }
            index++;
            const block = parseBlockStatement();
            return withLoc({
              type: "SpawnExpression",
              block
            }, token, previous());
          }
          if (token.type === "keyword" && token.value === "try") {
            const parsed = parseTryLike();
            return withLoc({
              type: "TryExpression",
              block: parsed.block,
              handlers: parsed.handlers
            }, parsed.start, previous());
          }
          if (token.type === "keyword" && token.value === "do") {
            index++;
            const block = parseBlockStatement();
            return withLoc({
              type: "DoExpression",
              block
            }, token, previous());
          }
          if (token.type === "keyword" && token.value === "new") {
            index++;
            let callee = parsePrimary();
            while (true) {
              const nextExpr = parseMemberAccess(callee);
              if (nextExpr === callee) {
                break;
              }
              callee = nextExpr;
            }
            const traits = parseTraitCompositionList();
            if (current().type === "punctuation" && current().value === "(") {
              const args = parseCallArgumentsOnly();
              callee = withLoc({
                type: "CallExpression",
                callee,
                arguments: args
              }, startLocFromNode(callee), endLocFromToken(previous()));
            }
            return withLoc({
              type: "NewExpression",
              callee,
              traits
            }, token, previous());
          }
          if (token.type === "keyword" && ["let", "const"].includes(token.value) && peekToken().type === "punctuation" && peekToken().value === "{") {
            throw new TranspilerSyntaxError(
              "Expected name after let or const in expression",
              peekToken()
            );
          }
          if (token.type === "keyword" && ["let", "const"].includes(token.value)) {
            return parseLetExpression();
          }
          if (token.type === "keyword") {
            index++;
            return withLoc({
              type: "Identifier",
              name: token.value
            }, token, token);
          }
          if (match("operator", "\u230A")) {
            return parseCircumfixUnary(token, "floor", "\u230B", "Expected closing floor operator");
          }
          if (match("operator", "\u2308")) {
            return parseCircumfixUnary(token, "ceil", "\u2309", "Expected closing ceil operator");
          }
          if (match("punctuation", "(")) {
            const expr = parseExpression();
            expect("punctuation", ")", "Expected ) after grouped expression");
            return withLoc({
              type: "GroupedExpression",
              expression: expr
            }, token, previous());
          }
          if (match("punctuation", "[")) {
            const elements = [];
            if (!match("punctuation", "]")) {
              while (true) {
                if (match("punctuation", ",")) {
                  continue;
                }
                if (match("punctuation", "]")) {
                  break;
                }
                elements.push(parseExpression());
                if (match("punctuation", "]")) {
                  break;
                }
                match("punctuation", ",");
              }
            }
            return withLoc({
              type: "ArrayExpression",
              elements
            }, token, previous());
          }
          if (match("operator", "{{")) {
            const opener = previous();
            const entries = [];
            if (!matchPairListClose()) {
              while (true) {
                if (match("punctuation", ",")) {
                  continue;
                }
                if (matchPairListClose()) {
                  break;
                }
                const start = current();
                const keyExpr = parseExpression();
                if (current().type === "operator" && current().value === ":") {
                  const normalized = normalizeNamedArgumentKey(keyExpr);
                  expect("operator", ":", "Expected : in pairlist literal");
                  const value = parseExpression();
                  entries.push(withLoc({
                    type: "PairListEntry",
                    key: normalized.key,
                    keyExpr: normalized.keyExpr,
                    value
                  }, startLocFromNode(keyExpr), endLocFromNode(value)));
                } else {
                  entries.push(keyExpr);
                }
                if (matchPairListClose()) {
                  break;
                }
                match("punctuation", ",");
              }
            }
            return withLoc({
              type: "PairListLiteral",
              entries
            }, opener, previous());
          }
          if (match("operator", "<<") || match("operator", "<<<") || match("operator", "\xAB")) {
            const opener = previous();
            const closer = opener.value === "<<<" ? ">>>" : opener.value === "\xAB" ? "\xBB" : ">>";
            const elements = parseDelimitedCollection(closer);
            return withLoc({
              type: opener.value === "<<<" ? "BagLiteral" : "SetLiteral",
              elements
            }, opener, previous());
          }
          if (match("punctuation", "{")) {
            const properties = [];
            if (!match("punctuation", "}")) {
              while (true) {
                if (match("punctuation", ",")) {
                  continue;
                }
                if (match("punctuation", "}")) {
                  break;
                }
                let key;
                if (current().type === "identifier" || current().type === "keyword") {
                  key = current().value;
                  index++;
                } else if (current().type === "string") {
                  key = current().value;
                  index++;
                } else {
                  throw new TranspilerSyntaxError("Expected object literal key", current());
                }
                expect("operator", ":", "Expected : in object literal");
                const value = parseExpression();
                properties.push({ key, value });
                if (match("punctuation", "}")) {
                  break;
                }
                match("punctuation", ",");
              }
            }
            return withLoc({
              type: "ObjectExpression",
              properties
            }, token, previous());
          }
          throw new TranspilerSyntaxError("Unexpected token in expression", token);
        }
        function parseFnExpression(token, isAsync) {
          index++;
          let params;
          if (current().type === "punctuation" && current().value === "(") {
            params = parseParameterList();
          } else {
            params = [parseParameter()];
          }
          if (current().type === "operator" && (current().value === "->" || current().value === "\u2192")) {
            index++;
          } else {
            throw new TranspilerSyntaxError("Expected -> after fn parameters", current());
          }
          const previousDepth = asyncContextDepth;
          asyncContextDepth = isAsync ? previousDepth + 1 : 0;
          let expr;
          try {
            expr = parseExpression();
          } finally {
            asyncContextDepth = previousDepth;
          }
          const returnStmt = withLoc({
            type: "ReturnStatement",
            argument: expr
          }, token, token);
          const body = withLoc({
            type: "BlockStatement",
            body: [returnStmt]
          }, token, token);
          return withLoc({
            type: "FunctionExpression",
            params,
            isAsync,
            body
          }, token, previous() || token);
        }
        function parseArrowLambdaExpression(token) {
          index++;
          const expr = parseExpression();
          const returnStmt = withLoc({
            type: "ReturnStatement",
            argument: expr
          }, token, token);
          const body = withLoc({
            type: "BlockStatement",
            body: [returnStmt]
          }, token, token);
          return withLoc({
            type: "FunctionExpression",
            params: [{
              type: "Parameter",
              name: "^^",
              typeName: null,
              optional: true,
              defaultValue: null,
              rest: false
            }],
            isAsync: false,
            body
          }, token, previous() || token);
        }
        function parseDelimitedCollection(closer) {
          const elements = [];
          if (match("operator", closer)) {
            return elements;
          }
          while (true) {
            if (match("punctuation", ",")) {
              continue;
            }
            if (match("operator", closer)) {
              break;
            }
            elements.push(parseExpression());
            if (match("operator", closer)) {
              break;
            }
            match("punctuation", ",");
          }
          return elements;
        }
        function parseLetExpression() {
          const start = expect("keyword");
          if (current().type === "punctuation" && current().value === "{") {
            throw new TranspilerSyntaxError(
              "Expected name after let or const in expression",
              current()
            );
          }
          return withLoc({
            type: "LetExpression",
            ...parseVariableDeclarationParts(start)
          }, start, previous());
        }
        function parseCircumfixUnary(start, operator, close, message) {
          const argument = parseExpression();
          expect("operator", close, message);
          return withLoc({
            type: "UnaryExpression",
            operator,
            argument,
            prefix: true
          }, start, previous());
        }
        function parseTemplateExpression(source, token) {
          try {
            return parse(tokenize(source), { expression: true });
          } catch (err) {
            if (err instanceof TranspilerSyntaxError || err instanceof UnsupportedSyntaxError) {
              throw new TranspilerSyntaxError("Invalid template interpolation", token);
            }
            throw err;
          }
        }
        function parseInterpolationParts(parts, token) {
          return parts.map((part) => {
            if (part.type === "text") {
              return withLoc({
                type: "StringLiteral",
                value: part.value
              }, token, token);
            }
            return parseTemplateExpression(part.value, token);
          });
        }
        if (options.expression) {
          return parseExpressionRoot();
        }
        return parseProgram();
      }
      module2.exports = {
        parse
      };
    }
  });

  // lib/transpiler-new/codegen.js
  var require_codegen = __commonJS({
    "lib/transpiler-new/codegen.js"(exports2, module2) {
      "use strict";
      var { UnsupportedSyntaxError } = require_errors();
      var loopCounter = 0;
      var chainCounter = 0;
      var emitContextStack = [];
      function currentEmitContext() {
        return emitContextStack.length > 0 ? emitContextStack[emitContextStack.length - 1] : {};
      }
      function withEmitContext(options, fn2) {
        emitContextStack.push(options || {});
        try {
          return fn2();
        } finally {
          emitContextStack.pop();
        }
      }
      function emitProgram(ast, options = {}) {
        loopCounter = 0;
        chainCounter = 0;
        const needsAsyncWrapper = programNeedsAsyncWrapper(ast);
        const syncEval = options.syncEval === true;
        const expressionDeclaredNames = collectExpressionDeclaredNames(ast.body);
        const sharedOptions = {
          ...options,
          asyncContext: needsAsyncWrapper && !syncEval,
          asyncNames: new Set(collectAsyncFunctionNames(ast.body)),
          evalNames: /* @__PURE__ */ new Set(["eval", ...collectEvalImportNames(ast.body)]),
          weakStorageNames: new Set(collectWeakDeclaredNames(ast.body)),
          scopeNames: /* @__PURE__ */ new Set([
            ...expressionDeclaredNames
          ]),
          bodylessFunctionNames: /* @__PURE__ */ new Set(),
          syncEval,
          topLevel: !syncEval
        };
        if (syncEval) {
          return `( () => {
${emitExpressionBlock({ body: ast.body }, sharedOptions)}
} )()`;
        }
        const body = ast.body.map((stmt) => emitStatement(stmt, {
          ...sharedOptions,
          topLevel: true
        })).join("\n");
        const prelude = emitPredeclaredNames(expressionDeclaredNames);
        const source = [prelude, body].filter(Boolean).join("\n");
        if (needsAsyncWrapper && !syncEval) {
          return `( async () => {
${source}
} )()`;
        }
        return source;
      }
      function marshalSourceSlice(node, options = currentEmitContext()) {
        if (!options.marshalSource || !node.loc || !node.loc.start || !node.loc.end) {
          return null;
        }
        return options.marshalSource.slice(node.loc.start.offset, node.loc.end.offset);
      }
      function marshalFunctionSource(node, options = currentEmitContext()) {
        const source = marshalSourceSlice(node, options);
        if (!source) {
          return null;
        }
        return source.replace(/^\s*async\s+function\s+[A-Za-z_][A-Za-z0-9_]*/u, "async function").replace(/^\s*function\s+[A-Za-z_][A-Za-z0-9_]*/u, "function");
      }
      function marshalCaptureNames(node, options = currentEmitContext()) {
        const names = /* @__PURE__ */ new Set();
        const declared = new Set([
          ...options.scopeNames || [],
          ...extractDeclaredParamNames(node.params || []),
          node.id && node.id.name,
          "self",
          "true",
          "false",
          "null",
          "__argc__",
          "__file__",
          "__global__",
          "__system__",
          ...options.evalNames || []
        ].filter(Boolean));
        const localKinds = /* @__PURE__ */ new Set([
          "FunctionDeclaration",
          "VariableDeclaration",
          "ClassDeclaration",
          "TraitDeclaration"
        ]);
        function visit(value, parent = null) {
          if (!value || typeof value !== "object") {
            return;
          }
          if (Array.isArray(value)) {
            for (const item of value) {
              visit(item, parent);
            }
            return;
          }
          if (value.type === "Identifier") {
            if (parent && (parent.type === "MemberExpression" && parent.property === value && !parent.computed || parent.type === "FieldDeclaration" && parent.id === value || parent.type === "MethodDeclaration" && parent.id === value)) {
              return;
            }
            if (!declared.has(value.name)) {
              names.add(value.name);
            }
            return;
          }
          if (value.type === "TryStatement") {
            visit(value.block, value);
            for (const handler of value.handlers || []) {
              const paramName = handler.paramName;
              const hadParam = paramName ? declared.has(paramName) : false;
              if (paramName) {
                declared.add(paramName);
              }
              visit(handler.body, handler);
              if (paramName && !hadParam) {
                declared.delete(paramName);
              }
            }
            return;
          }
          if (value.type === "VariableUnpackDeclaration") {
            visit(value.init, value);
            for (const entry of bindingEntriesForPattern(value.pattern)) {
              visit(entry.key, entry);
              visit(entry.defaultValue, entry);
            }
            for (const name2 of declaredNamesForStatement(value)) {
              declared.add(name2);
            }
            return;
          }
          if (localKinds.has(value.type)) {
            for (const name2 of declaredNamesForStatement(value)) {
              declared.add(name2);
            }
          }
          for (const [key, child] of Object.entries(value)) {
            if (key === "loc") {
              continue;
            }
            visit(child, value);
          }
        }
        visit(node.body || node);
        return [...names].filter((name2) => /^[A-Za-z_][A-Za-z0-9_]*$/u.test(name2));
      }
      function marshalMetaExpression(kind, name2, source, captureNames = []) {
        return `{ kind: ${JSON.stringify(kind)}, name: ${JSON.stringify(name2 || null)}, source: ${JSON.stringify(source || "")}, captures: ${marshalCapturesExpression(captureNames)} }`;
      }
      function marshalCapturesExpression(captureNames = []) {
        const captures = captureNames.map((capture) => `${JSON.stringify(capture)}: typeof ${capture} !== "undefined" ? ${capture} : null`).join(", ");
        return `{ ${captures} }`;
      }
      function marshalClassCaptureNames(node, options = currentEmitContext()) {
        const names = new Set(marshalCaptureNames(node, options));
        for (const trait of node.traits || []) {
          if (trait && trait.type === "Identifier") {
            names.add(trait.name);
          }
        }
        for (const field of node.body.filter((entry) => entry.type === "FieldDeclaration")) {
          names.delete(field.id.name);
        }
        for (const entry of node.body) {
          if (entry.id && entry.id.name) {
            names.delete(entry.id.name);
          }
          if (entry.type === "MethodDeclaration") {
            for (const param of extractDeclaredParamNames(entry.params || [])) {
              names.delete(param);
            }
          }
        }
        return [...names];
      }
      function marshalTraitCaptureNames(node, options = currentEmitContext()) {
        const names = new Set(marshalCaptureNames(node, options));
        for (const method of node.body || []) {
          if (method.id && method.id.name) {
            names.delete(method.id.name);
          }
          for (const param of extractDeclaredParamNames(method.params || [])) {
            names.delete(param);
          }
        }
        return [...names];
      }
      function nestedFunctionOptions(options = {}) {
        return {
          marshalSource: options.marshalSource,
          syncEval: options.syncEval,
          asyncContext: options.asyncContext,
          asyncNames: options.asyncNames,
          evalNames: options.evalNames,
          weakStorageNames: options.weakStorageNames,
          scopeNames: options.scopeNames,
          bodylessFunctionNames: options.bodylessFunctionNames,
          chainHereName: options.chainHereName
        };
      }
      function emitStatement(node, options = {}) {
        return withEmitContext(options, () => {
          if (node.exported) {
            return emitExportedStatement(node, options);
          }
          switch (node.type) {
            case "EmptyStatement":
              return ";";
            case "ImportDeclaration":
              return emitImportDeclaration(node, options);
            case "VariableDeclaration": {
              const value = emitVariableDeclarationValue(node);
              return `${node.kind} ${emitExpression(node.id)} = ${value};`;
            }
            case "VariableUnpackDeclaration":
              return emitVariableUnpackDeclaration(node, options);
            case "FunctionDeclaration": {
              const name2 = emitExpression(node.id);
              if (node.isPredeclared) {
                if (options.bodylessFunctionNames) {
                  options.bodylessFunctionNames.add(node.id.name);
                }
                const declaration2 = `let ${name2} = __zuzu_bodyless_function( ${JSON.stringify(node.id.name)} );`;
                return options.topLevel ? `${declaration2}
globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration2;
              }
              const fn2 = emitFunctionLike(node, `${node.isAsync ? "async " : ""}function ${name2}()`, {
                ...nestedFunctionOptions(options),
                returnTypeName: node.returnType,
                callableName: node.id.name,
                asyncContext: node.isAsync === true,
                syncEval: options.syncEval === true
              });
              const meta = marshalMetaExpression(
                "function",
                node.id.name,
                marshalFunctionSource(node, options),
                marshalCaptureNames(node, options)
              );
              if (options.bodylessFunctionNames && options.bodylessFunctionNames.has(node.id.name)) {
                options.bodylessFunctionNames.delete(node.id.name);
                return `${name2} = __zuzu_complete_function( ${name2}, ${fn2}, ${meta} );`;
              }
              const declaration = `const ${name2} = __zuzu_with_marshal_meta( ${fn2}, ${meta} );`;
              return options.topLevel ? `${declaration}
globalThis[${JSON.stringify(node.id.name)}] = ${name2};` : declaration;
            }
            case "ReturnStatement": {
              if (node.argument == null && !options.returnTypeName) {
                return options.inSwitchSection ? "return { __zuzu_return: true, value: undefined };" : "return;";
              }
              const value = node.argument ? emitReturnValue(node.argument, options) : emitReturnValue(null, options);
              if (options.inSwitchSection) {
                return `return { __zuzu_return: true, value: ${value} };`;
              }
              return node.argument ? `return ${value};` : `return ${value};`;
            }
            case "IfStatement":
              return [
                node.declaration ? emitStatement(node.declaration, options) : "",
                `if ( __zuzu_truthy( ${emitExpression(node.test)} ) ) ${emitBlock(node.consequent, options)}`,
                node.alternate ? `else ${node.alternate.type === "BlockStatement" ? emitBlock(node.alternate, options) : emitStatement(node.alternate, options)}` : ""
              ].filter(Boolean).join(" ");
            case "BlockStatement":
              return emitBlock(node, options);
            case "ExpressionStatement":
              return `${emitExpression(node.expression)};`;
            case "ForInStatement":
              return emitForInStatement(node, options);
            case "WhileStatement":
              return [
                node.declaration ? emitStatement(node.declaration, options) : "",
                `while ( __zuzu_truthy( ${emitExpression(node.test)} ) ) ${emitBlock(node.body, {
                  ...options,
                  loopDepth: (options.loopDepth || 0) + 1
                })}`
              ].filter(Boolean).join("\n");
            case "ContinueStatement":
              if (options.inSwitchSection && (options.loopDepth || 0) === 0) {
                return "return true;";
              }
              return "continue;";
            case "BreakStatement":
              return "break;";
            case "ThrowStatement":
              return `__zuzu_throw( ${emitExpression(node.argument)}, ${JSON.stringify(node.loc.start.line)} );`;
            case "DieStatement":
              return `__zuzu_die( ${emitExpression(node.argument)} );`;
            case "WarnStatement":
              return `__zuzu_warn( ${emitExpression(node.argument)} );`;
            case "AssertStatement":
              return `__zuzu_assert( () => ${emitExpression(node.argument)} );`;
            case "DebugStatement":
              return emitDebugStatement(node);
            case "TryStatement":
              return emitTryStatement(node, options);
            case "SwitchStatement":
              return emitSwitchStatement(node, options);
            case "ClassDeclaration":
              return emitClassDeclaration(node, options);
            case "TraitDeclaration":
              return emitTraitDeclaration(node, options);
            default:
              throw new UnsupportedSyntaxError(`Unsupported statement node ${node.type}`);
          }
        });
      }
      function emitExportedStatement(node, options = {}) {
        if (node.type === "VariableUnpackDeclaration") {
          const unexported2 = {
            ...node,
            exported: false
          };
          return [
            emitStatement(unexported2, options),
            ...declaredNamesForStatement(node).map((name3) => `module.exports[${JSON.stringify(name3)}] = ${name3};`)
          ].join("\n");
        }
        if (!node.id || !node.id.name) {
          throw new UnsupportedSyntaxError(`Cannot export statement node ${node.type}`);
        }
        const unexported = {
          ...node,
          exported: false
        };
        const name2 = node.id.name;
        return [
          emitStatement(unexported, options),
          `module.exports[${JSON.stringify(name2)}] = ${name2};`
        ].join("\n");
      }
      function emitDebugStatement(node) {
        const args = node.arguments || [];
        const level = args[0] ? emitExpression(args[0]) : "0";
        const message = args[1] ? emitExpression(args[1]) : '""';
        return `__zuzu_debug( () => ${level}, () => ${message} );`;
      }
      function emitFunctionLike(node, header, options = {}) {
        const signature = analyzeSpecialSignature(node.params);
        const functionOptions = createFunctionOptions(node, options);
        const cleanupNames = collectCleanupNames(node.body);
        const bodySource = withEmitContext(
          functionOptions,
          () => emitFunctionBlock(node.body, cleanupNames, functionOptions)
        );
        const cleanup = cleanupNames.map((name2) => `__zuzu_maybe_demolish( ${name2} );`).join("\n");
        const bodyWrapper = [
          "try {",
          bodySource,
          "} catch ( __zuzu_nonlocal ) {",
          "if ( __zuzu_nonlocal && __zuzu_nonlocal.__zuzu_nonlocal_return ) { return __zuzu_nonlocal.value; }",
          "throw __zuzu_nonlocal;",
          "}",
          cleanupNames.length > 0 ? "finally {" : "",
          cleanupNames.length > 0 ? cleanup : "",
          cleanupNames.length > 0 ? "}" : ""
        ].filter(Boolean).join("\n");
        if (node.isAsync === true) {
          const taskName = options.callableName || (node.id ? node.id.name : null) || "<async>";
          const line = node.loc && node.loc.start ? node.loc.start.line : null;
          const syncHeader = header.replace(/^async\s+/u, "");
          const taskHelper = options.syncEval ? "__zuzu_task_sync" : "__zuzu_task";
          const executorPrefix = options.syncEval ? "()" : "async ()";
          return [
            `${syncHeader} {`,
            `return ${taskHelper}( ${executorPrefix} => {`,
            emitFunctionPreamble(node.params, signature),
            options.extraPreamble || "",
            ...cleanupNames.map((name2) => `let ${name2} = null;`),
            bodyWrapper,
            `}, { name: ${JSON.stringify(taskName)}, line: ${JSON.stringify(line)} } );`,
            "}"
          ].filter(Boolean).join("\n");
        }
        return [
          `${header} {`,
          emitFunctionPreamble(node.params, signature),
          options.extraPreamble || "",
          ...cleanupNames.map((name2) => `let ${name2} = null;`),
          bodyWrapper,
          "}"
        ].filter(Boolean).join("\n");
      }
      function emitFunctionBodyStatement(node, cleanupNames, options = {}) {
        if (node.type === "VariableDeclaration" && node.id && cleanupNames.includes(node.id.name)) {
          return `${emitExpression(node.id)} = ${emitVariableDeclarationValue(node)};`;
        }
        if (node.type === "VariableUnpackDeclaration" && bindingEntriesForPattern(node.pattern).some((entry) => cleanupNames.includes(entry.name))) {
          return emitVariableUnpackAssignments(node);
        }
        return emitStatement(node, options);
      }
      function emitFunctionBlock(block, cleanupNames, options = {}) {
        if (!block || !Array.isArray(block.body) || block.body.length === 0) {
          return "";
        }
        return emitFunctionStatements(block.body, cleanupNames, options);
      }
      function emitFunctionStatements(statements, cleanupNames, options = {}) {
        const lines = [];
        const lastIndex = statements.length - 1;
        for (let i = 0; i < statements.length; i++) {
          const stmt = statements[i];
          if (stmt.type === "VariableUnpackDeclaration") {
            const unpack = emitVariableUnpackParts(stmt);
            const rest = emitFunctionStatements(
              statements.slice(i + 1),
              cleanupNames,
              {
                ...options,
                scopeNames: /* @__PURE__ */ new Set([
                  ...options.scopeNames || [],
                  ...declaredNamesForStatement(stmt)
                ])
              }
            );
            lines.push(...unpack.prelude);
            lines.push("{");
            lines.push(...unpack.declarations);
            lines.push(emitUnpackScopedRest(stmt, rest));
            lines.push("}");
            return lines.filter((line) => line !== "").join("\n");
          }
          if (i === lastIndex) {
            lines.push(emitFunctionTailStatement(stmt, cleanupNames, options));
          } else {
            lines.push(emitFunctionBodyStatement(stmt, cleanupNames, options));
          }
        }
        return lines.join("\n");
      }
      function emitFunctionTailStatement(stmt, cleanupNames, options = {}) {
        if (stmt.type === "ExpressionStatement") {
          return `return ${emitExpression(stmt.expression)};`;
        }
        if (stmt.type === "BlockStatement") {
          return emitBlock(stmt, options);
        }
        if (stmt.type === "IfStatement") {
          const prefix = stmt.declaration ? `${emitStatement(stmt.declaration, options)}
` : "";
          const alternate = stmt.alternate ? emitFunctionTailStatement(stmt.alternate, cleanupNames, options) : "return null;";
          return `${prefix}if ( __zuzu_truthy( ${emitExpression(stmt.test, options)} ) ) { ${emitFunctionBlock(stmt.consequent, cleanupNames, options)} } else { ${alternate} }`;
        }
        return emitFunctionBodyStatement(stmt, cleanupNames, options);
      }
      function collectCleanupNames(block) {
        const names = [];
        for (const stmt of block.body) {
          if (["VariableDeclaration", "ClassDeclaration", "TraitDeclaration"].includes(stmt.type)) {
            for (const name2 of declaredNamesForStatement(stmt)) {
              if (name2 !== "self") {
                names.push(name2);
              }
            }
          }
        }
        names.push(...collectExpressionDeclaredNames(block.body));
        return [...new Set(names)];
      }
      function collectWeakDeclaredNames(statements = []) {
        const names = [];
        for (const stmt of statements || []) {
          if (stmt.type === "VariableDeclaration" && stmt.isWeakStorage && stmt.id && stmt.id.name) {
            names.push(stmt.id.name);
          } else if (stmt.type === "VariableUnpackDeclaration") {
            for (const entry of bindingEntriesForPattern(stmt.pattern)) {
              if (entry.isWeakStorage && entry.name) {
                names.push(entry.name);
              }
            }
          }
        }
        names.push(...collectExpressionDeclaredEntries(statements).filter((entry) => entry.isWeakStorage).map((entry) => entry.name));
        return [...new Set(names)];
      }
      function createFunctionOptions(node, options = {}) {
        const signature = analyzeSpecialSignature(node.params);
        const paramNames = extractDeclaredParamNames(node.params);
        const body = node.body ? node.body.body : [];
        const expressionDeclaredNames = collectExpressionDeclaredNames(body);
        const hereParamName = (node.params || []).some((param) => param.type === "Parameter" && param.name === "^^") ? "__zuzu_here" : null;
        return {
          ...options,
          returnTypeName: options.returnTypeName || node.returnType || null,
          callableName: options.callableName || (node.id ? node.id.name : null),
          asyncContext: node.isAsync === true || options.asyncContext === true,
          asyncNames: /* @__PURE__ */ new Set([...options.asyncNames || [], ...collectAsyncFunctionNames(body)]),
          weakStorageNames: /* @__PURE__ */ new Set([
            ...options.weakStorageNames || [],
            ...collectWeakDeclaredNames(body)
          ]),
          scopeNames: /* @__PURE__ */ new Set([
            ...options.scopeNames || [],
            ...paramNames,
            ...hereParamName ? [hereParamName] : [],
            ...extractSpecialPreludeNames(signature),
            ...expressionDeclaredNames
          ]),
          bodylessFunctionNames: /* @__PURE__ */ new Set(),
          chainHereName: hereParamName || options.chainHereName
        };
      }
      function extractDeclaredParamNames(params) {
        const names = [];
        for (const param of params) {
          if (param.type === "Parameter") {
            names.push(param.name);
          } else if (param.type === "SpecialParameter") {
            if (param.leadName) {
              names.push(param.leadName);
            }
            names.push(param.name);
          }
        }
        return names;
      }
      function extractSpecialPreludeNames(signature) {
        if (!signature) {
          return [];
        }
        switch (signature.kind) {
          case "pairlist_only":
            return ["__zuzu_call_args", signature.namedName];
          case "pairlist_rest_array":
          case "rest_array_pairlist":
            return ["__zuzu_call_args", signature.namedName, signature.restName, "__a"];
          case "lead_pairlist":
            return ["__zuzu_call_args", signature.headName, signature.namedName, signature.restName, "__i", "__a"];
          case "trail_pairlist":
            return ["__zuzu_call_args", signature.headName, signature.restName, signature.namedName, "__i", "__a"];
          case "scalar_pairlist":
            return ["__zuzu_call_args", signature.headName, signature.namedName, "__i", "__a"];
          case "variadic":
            return ["__zuzu_call_args", signature.headName, signature.restName, "__i", "__a"];
          default:
            return [];
        }
      }
      function analyzeSpecialSignature(params) {
        if (params.length === 1 && params[0].type === "SpecialParameter" && params[0].special === "rest_only" && params[0].containerType === "PairList") {
          return {
            kind: "pairlist_only",
            namedName: params[0].name
          };
        }
        if (params.length === 2 && params[0].type === "SpecialParameter" && params[0].special === "rest_only" && params[0].containerType === "Array" && params[1].type === "Parameter" && params[1].typeName === "PairList") {
          return {
            kind: "rest_array_pairlist",
            restName: params[0].name,
            namedName: params[1].name
          };
        }
        if (params.length === 2 && params[0].type === "SpecialParameter" && params[0].special === "rest_only" && params[0].containerType === "PairList" && params[1].type === "Parameter" && (params[1].typeName === "Array" || params[1].typeName == null)) {
          return {
            kind: "pairlist_rest_array",
            namedName: params[0].name,
            restName: params[1].name
          };
        }
        if (params.length === 2 && params[0].type === "SpecialParameter" && params[0].special === "lead_rest" && params[0].containerType === "PairList" && params[1].type === "Parameter" && (params[1].typeName === "Array" || params[1].typeName == null)) {
          return {
            kind: "lead_pairlist",
            headName: params[0].leadName,
            namedName: params[0].name,
            restName: params[1].name
          };
        }
        if (params.length === 2 && params[0].type === "SpecialParameter" && params[0].special === "lead_rest" && params[0].containerType === "Array" && params[1].type === "Parameter" && params[1].typeName === "PairList") {
          return {
            kind: "trail_pairlist",
            headName: params[0].leadName,
            restName: params[0].name,
            namedName: params[1].name
          };
        }
        if (params.length === 2 && params[0].type === "Parameter" && params[1].type === "SpecialParameter" && params[1].special === "rest_only" && params[1].containerType === "PairList") {
          return {
            kind: "scalar_pairlist",
            headName: params[0].name,
            namedName: params[1].name
          };
        }
        if (params.length === 1 && params[0].type === "SpecialParameter" && params[0].special === "lead_rest" && params[0].containerType === "Array") {
          return {
            kind: "variadic",
            headName: params[0].leadName,
            restName: params[0].name
          };
        }
        return null;
      }
      function emitFunctionPreamble(params, signature = null) {
        if (signature) {
          return emitSpecialFunctionPreamble(signature);
        }
        const lines = [];
        const required = params.reduce((count, param) => {
          if (param.type === "Parameter") {
            return count + (!param.optional && param.defaultValue == null && !param.rest ? 1 : 0);
          }
          if (param.type === "SpecialParameter" && param.special === "lead_rest") {
            return count + 1;
          }
          return count;
        }, 0);
        lines.push("const __argc__ = arguments.length;");
        lines.push(`if ( arguments.length < ${required} ) { throw new Error( "Wrong number of arguments" ); }`);
        let argIndex = 0;
        for (const param of params) {
          if (param.type === "SpecialParameter") {
            if (param.special === "lead_rest") {
              lines.push(`const ${param.leadName} = arguments[${argIndex}];`);
              argIndex++;
              lines.push(`const ${param.name} = Array.prototype.slice.call( arguments, ${argIndex} );`);
              continue;
            }
            if (param.special === "rest_only") {
              if (param.containerType === "PairList") {
                lines.push(`let ${param.name} = __zuzu_pairlist_literal( [] );`);
                lines.push(`for ( let __i = ${argIndex}; __i < arguments.length; __i++ ) {`);
                lines.push("const __a = arguments[__i];");
                lines.push(`if ( __zuzu_is_pairlist( __a ) ) { ${param.name} = __a; } else { throw new Exception( "named PairList parameter only accepts named arguments" ); }`);
                lines.push("}");
              } else {
                lines.push(`const ${param.name} = Array.prototype.slice.call( arguments, ${argIndex} );`);
              }
              continue;
            }
          }
          if (param.type !== "Parameter") {
            continue;
          }
          const paramName = param.name === "^^" ? "__zuzu_here" : param.name;
          if (param.rest) {
            lines.push(`const ${paramName} = Array.prototype.slice.call( arguments, ${argIndex} );`);
            continue;
          }
          if (param.defaultValue) {
            lines.push(`const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : ${emitExpression(param.defaultValue)};`);
          } else if (param.optional) {
            lines.push(`const ${paramName} = __argc__ > ${argIndex} ? arguments[${argIndex}] : null;`);
          } else {
            lines.push(`const ${paramName} = arguments[${argIndex}];`);
          }
          if (param.typeName) {
            lines.push(
              `if ( ${paramName} != null && !__zuzu_type_matches( ${paramName}, ${JSON.stringify(param.typeName)} ) ) { throw new Error( \`TypeException: '${param.name}' must be ${param.typeName}, got \${ __zuzu_typeof( ${paramName} ) }\` ); }`
            );
          }
          argIndex++;
        }
        return lines.join("\n");
      }
      function emitSpecialFunctionPreamble(signature) {
        switch (signature.kind) {
          case "pairlist_only":
            return [
              `const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
              "let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
              "for ( const __a of __zuzu_call_args ) {",
              'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named PairList parameter only accepts named arguments" ); }',
              "}",
              `const ${signature.namedName} = __zuzu_named_args;`
            ].join("\n");
          case "pairlist_rest_array":
          case "rest_array_pairlist":
            return [
              `const __zuzu_call_args = Array.prototype.slice.call( arguments );`,
              "let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
              "const __zuzu_rest_args = [];",
              "for ( const __a of __zuzu_call_args ) {",
              "if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
              "}",
              `const ${signature.namedName} = __zuzu_named_args;`,
              `const ${signature.restName} = __zuzu_rest_args;`
            ].join("\n");
          case "lead_pairlist":
            return [
              "const __zuzu_call_args = Array.prototype.slice.call( arguments );",
              `const ${signature.headName} = __zuzu_call_args[0];`,
              "let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
              "const __zuzu_rest_args = [];",
              "for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
              "const __a = __zuzu_call_args[__i];",
              "if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
              "}",
              `const ${signature.namedName} = __zuzu_named_args;`,
              `const ${signature.restName} = __zuzu_rest_args;`
            ].join("\n");
          case "trail_pairlist":
            return [
              "const __zuzu_call_args = Array.prototype.slice.call( arguments );",
              `const ${signature.headName} = __zuzu_call_args[0];`,
              "const __zuzu_rest_args = [];",
              "let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
              "for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
              "const __a = __zuzu_call_args[__i];",
              "if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { __zuzu_rest_args.push( __a ); }",
              "}",
              `const ${signature.restName} = __zuzu_rest_args;`,
              `const ${signature.namedName} = __zuzu_named_args;`
            ].join("\n");
          case "scalar_pairlist":
            return [
              "const __zuzu_call_args = Array.prototype.slice.call( arguments );",
              `const ${signature.headName} = __zuzu_call_args[0];`,
              "let __zuzu_named_args = __zuzu_pairlist_literal( [] );",
              "for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
              "const __a = __zuzu_call_args[__i];",
              'if ( __zuzu_is_pairlist( __a ) ) { __zuzu_named_args = __a; } else { throw new Exception( "named arguments not allowed for this function" ); }',
              "}",
              `const ${signature.namedName} = __zuzu_named_args;`
            ].join("\n");
          case "variadic":
            return [
              "const __zuzu_call_args = Array.prototype.slice.call( arguments );",
              `const ${signature.headName} = __zuzu_call_args[0];`,
              "const __zuzu_rest_args = [];",
              "for ( let __i = 1; __i < __zuzu_call_args.length; __i++ ) {",
              "const __a = __zuzu_call_args[__i];",
              'if ( __zuzu_is_pairlist( __a ) ) { throw new Exception( "named arguments not allowed for this function" ); } __zuzu_rest_args.push( __a );',
              "}",
              `const ${signature.restName} = __zuzu_rest_args;`
            ].join("\n");
          default:
            return "";
        }
      }
      function emitReturnValue(argument, options = {}) {
        let value;
        if (argument == null) {
          value = "undefined";
        } else {
          value = emitExpression(argument);
        }
        if (options.returnTypeName && options.returnTypeName !== "Any") {
          return `__zuzu_checked_return( ${JSON.stringify(options.callableName || "")}, ${JSON.stringify(options.returnTypeName)}, ${value} )`;
        }
        return value;
      }
      function emitForInStatement(node, options = {}) {
        const loopId = loopCounter++;
        const implicitHere = node.left.name === "^^";
        const loopName = implicitHere ? `__zuzu_loop_here_${loopId}` : node.left.name;
        const iterName = `__zuzu_iterated_${implicitHere ? "here" : node.left.name}_${loopId}`;
        const elsePart = node.elseBlock ? `if ( !${iterName} ) ${emitBlock(node.elseBlock, options)}` : "";
        const loopKeyword = node.kind ? `${node.kind} ` : "";
        const bodyOptions = implicitHere ? {
          ...options,
          chainHereName: loopName
        } : options;
        return [
          `let ${iterName} = 0;`,
          `for ( ${loopKeyword}${loopName} of __zuzu_iter( ${emitExpression(node.iterable)} ) ) {`,
          `${iterName} = 1;`,
          node.body.body.map((stmt) => emitStatement(stmt, {
            ...bodyOptions,
            loopDepth: (options.loopDepth || 0) + 1
          })).join("\n"),
          "}",
          elsePart
        ].filter(Boolean).join("\n");
      }
      function emitTryStatement(node, options = {}) {
        const handlers = node.handlers || [];
        let catchBody = "throw __zuzu_err;";
        if (handlers.length > 0) {
          const branches = handlers.map((handler, index) => {
            const cond = handler.typeName === "Exception" || handler.typeName === "Any" ? "true" : `__zuzu_instanceof( __zuzu_err, ${handler.typeName} )`;
            const prefix = index === 0 ? `if ( ${cond} )` : `else if ( ${cond} )`;
            return `${prefix} { let ${handler.paramName} = __zuzu_err; ${handler.body.body.map((stmt) => emitStatement(stmt, options)).join("\n")} }`;
          });
          catchBody = `if ( __zuzu_err && __zuzu_err.__zuzu_nonlocal_return ) { throw __zuzu_err; } __zuzu_err = __zuzu_normalize_exception( __zuzu_err ); ${branches.join(" ")} else { throw __zuzu_err; }`;
        }
        return `try ${emitBlock(node.block, options)} catch ( __zuzu_err ) { ${catchBody} }`;
      }
      function emitImportDeclaration(node, options = {}) {
        if (node.importAll) {
          if (options.syncEval) {
            return `{ const __zuzu_star = __zuzu_import( ${JSON.stringify(node.source)} ); }`;
          }
          if (node.source === "std/eval") {
            return `{ const __zuzu_star = __zuzu_import( ${JSON.stringify(node.source)} ); for ( const __zuzu_key of Object.keys( __zuzu_star ) ) { if ( __zuzu_key === "eval" ) { continue; } const __zuzu_desc = Object.create( null ); __zuzu_desc.configurable = true; __zuzu_desc.enumerable = true; __zuzu_desc.get = function() { return __zuzu_star[ __zuzu_key ] ?? null; }; __zuzu_desc.set = function( value ) { __zuzu_star[ __zuzu_key ] = value; }; Object.defineProperty( globalThis, __zuzu_key, __zuzu_desc ); } }`;
          }
          return `{ const __zuzu_star = __zuzu_import( ${JSON.stringify(node.source)} ); if ( Object.prototype.hasOwnProperty.call( __zuzu_star, "done_testing" ) ) { var done_testing = __zuzu_star.done_testing ?? null; } for ( const __zuzu_key of Object.keys( __zuzu_star ) ) { if ( __zuzu_key === "done_testing" ) { continue; } const __zuzu_desc = Object.create( null ); __zuzu_desc.configurable = true; __zuzu_desc.enumerable = true; __zuzu_desc.get = function() { return __zuzu_star[ __zuzu_key ] ?? null; }; __zuzu_desc.set = function( value ) { __zuzu_star[ __zuzu_key ] = value; }; Object.defineProperty( globalThis, __zuzu_key, __zuzu_desc ); } }`;
        }
        const moduleName = `__zuzu_imported_${Math.abs(hashString(node.source))}_${node.specifiers.length}_${options.syncEval ? loopCounter++ : 0}`;
        const defineImports = node.specifiers.map((specifier) => {
          const importedName = normalizeImportedName(node.source, specifier.imported);
          if (node.source === "std/eval" && importedName === "eval") {
            return "";
          }
          return defineLiveImport(specifier.local, moduleName, importedName, options);
        }).filter(Boolean);
        const legacyImports = node.specifiers.map((specifier) => {
          const importedName = normalizeImportedName(node.source, specifier.imported);
          const mapped = importedName === specifier.local ? importedName : `${importedName}: ${specifier.local}`;
          return node.tryMode ? `${mapped} = null` : mapped;
        });
        const legacyShape = `/* const { ${legacyImports.join(", ")} } = __zuzu_import( ${JSON.stringify(node.source)} ); */`;
        const importCondition = node.condition ? node.condition.keyword === "unless" ? `!__zuzu_truthy( ${emitExpression(node.condition.test)} )` : `__zuzu_truthy( ${emitExpression(node.condition.test)} )` : null;
        const disabledImports = `{ ${node.specifiers.map((specifier) => {
          const importedName = normalizeImportedName(node.source, specifier.imported);
          return `${importedName}: null`;
        }).join(", ")} }`;
        if (options.syncEval) {
          if (node.tryMode) {
            return [
              `const ${moduleName} = ( () => {`,
              "try {",
              importCondition ? `if ( !( ${importCondition} ) ) { return {}; }` : "",
              `return __zuzu_import( ${JSON.stringify(node.source)} );`,
              "}",
              "catch ( __zuzu_err ) {",
              "if ( __zuzu_err && __zuzu_err.__zuzu_nonlocal_return ) { throw __zuzu_err; }",
              "return {};",
              "}",
              "} )();",
              ...defineImports
            ].filter(Boolean).join(" ");
          }
          if (importCondition) {
            return [
              `const ${moduleName} = ( () => {`,
              `if ( !( ${importCondition} ) ) { return ${disabledImports}; }`,
              `return __zuzu_import( ${JSON.stringify(node.source)} );`,
              "} )();",
              ...defineImports
            ].join(" ");
          }
          return `const ${moduleName} = __zuzu_import( ${JSON.stringify(node.source)} ); ${defineImports.join(" ")}`;
        }
        if (node.tryMode) {
          return [
            `{ ${legacyShape} const ${moduleName} = ( () => {`,
            "try {",
            importCondition ? `if ( !( ${importCondition} ) ) { return {}; }` : "",
            `return __zuzu_import( ${JSON.stringify(node.source)} );`,
            "}",
            "catch ( __zuzu_err ) {",
            "if ( __zuzu_err && __zuzu_err.__zuzu_nonlocal_return ) { throw __zuzu_err; }",
            "return {};",
            "}",
            "} )();",
            ...defineImports,
            "}"
          ].filter(Boolean).join(" ");
        }
        if (importCondition) {
          return [
            `{ ${legacyShape} const ${moduleName} = ( () => {`,
            `if ( !( ${importCondition} ) ) { return ${disabledImports}; }`,
            `return __zuzu_import( ${JSON.stringify(node.source)} );`,
            "} )();",
            ...defineImports,
            "}"
          ].join(" ");
        }
        return `{ ${legacyShape} const ${moduleName} = __zuzu_import( ${JSON.stringify(node.source)} ); ${defineImports.join(" ")} }`;
      }
      function normalizeImportedName(source, imported) {
        return source === "std/math" && imported === "pi" ? "\u03C0" : imported;
      }
      function hashString(value) {
        let hash = 0;
        for (let i = 0; i < value.length; i++) {
          hash = (hash << 5) - hash + value.charCodeAt(i);
          hash |= 0;
        }
        return hash;
      }
      function defineLiveImport(localName, moduleName, importedName, options = {}) {
        if (options.syncEval) {
          return `const ${localName} = ${moduleName}[${JSON.stringify(importedName)}] ?? null;`;
        }
        if (localName === "done_testing") {
          return `var done_testing = ${moduleName}[${JSON.stringify(importedName)}] ?? null;`;
        }
        return [
          "{",
          "const __zuzu_desc = Object.create( null );",
          "__zuzu_desc.configurable = true;",
          "__zuzu_desc.enumerable = true;",
          `__zuzu_desc.get = function() { return ${moduleName}[${JSON.stringify(importedName)}] ?? null; };`,
          `__zuzu_desc.set = function( value ) { ${moduleName}[${JSON.stringify(importedName)}] = value; };`,
          "Object.defineProperty( globalThis,",
          `${JSON.stringify(localName)},`,
          "__zuzu_desc );",
          "}"
        ].join(" ");
      }
      function emitBlock(node, options = {}) {
        const expressionDeclaredNames = collectExpressionDeclaredNames(node.body);
        const scopedOptions = {
          ...options,
          asyncNames: /* @__PURE__ */ new Set([...options.asyncNames || [], ...collectAsyncFunctionNames(node.body)]),
          weakStorageNames: /* @__PURE__ */ new Set([
            ...options.weakStorageNames || [],
            ...collectWeakDeclaredNames(node.body)
          ]),
          bodylessFunctionNames: /* @__PURE__ */ new Set(),
          scopeNames: /* @__PURE__ */ new Set([
            ...options.scopeNames || [],
            ...collectDeclaredNames(node.body),
            ...expressionDeclaredNames
          ])
        };
        const cleanupNames = collectCleanupNames(node);
        const body = emitBlockBodyStatements(node.body, cleanupNames, scopedOptions);
        if (cleanupNames.length === 0) {
          return `{
${body}
}`;
        }
        const cleanup = cleanupNames.map((name2) => `__zuzu_maybe_demolish( ${name2} );`).join("\n");
        return `{
${cleanupNames.map((name2) => `let ${name2} = null;`).join("\n")}
try {
${body}
} finally {
${cleanup}
}
}`;
      }
      function emitBlockBodyStatements(statements, cleanupNames, options = {}) {
        const lines = [];
        for (let i = 0; i < statements.length; i++) {
          const stmt = statements[i];
          if (stmt.type === "VariableUnpackDeclaration") {
            const unpack = emitVariableUnpackParts(stmt);
            const rest = emitBlockBodyStatements(
              statements.slice(i + 1),
              cleanupNames,
              {
                ...options,
                scopeNames: /* @__PURE__ */ new Set([
                  ...options.scopeNames || [],
                  ...declaredNamesForStatement(stmt)
                ])
              }
            );
            lines.push(...unpack.prelude);
            lines.push("{");
            lines.push(...unpack.declarations);
            lines.push(emitUnpackScopedRest(stmt, rest));
            lines.push("}");
            return lines.filter((line) => line !== "").join("\n");
          }
          lines.push(emitBlockStatement(stmt, cleanupNames, options));
        }
        return lines.join("\n");
      }
      function emitUnpackScopedRest(stmt, rest) {
        const cleanupNames = declaredNamesForStatement(stmt).filter((name2) => name2 !== "self");
        if (cleanupNames.length === 0) {
          return rest;
        }
        const cleanup = cleanupNames.map((name2) => `__zuzu_maybe_demolish( ${name2} );`).join("\n");
        return `try {
${rest}
} finally {
${cleanup}
}`;
      }
      function collectAsyncFunctionNames(statements = []) {
        const names = [];
        for (const stmt of statements) {
          if (stmt.type === "FunctionDeclaration" && stmt.isAsync && stmt.id && stmt.id.name) {
            names.push(stmt.id.name);
          } else if (stmt.type === "VariableDeclaration" && stmt.init && stmt.init.type === "FunctionExpression" && stmt.init.isAsync && stmt.id && stmt.id.name) {
            names.push(stmt.id.name);
          }
        }
        return names;
      }
      function collectEvalImportNames(statements = []) {
        const names = [];
        for (const stmt of statements) {
          if (stmt.type !== "ImportDeclaration" || stmt.source !== "std/eval") {
            continue;
          }
          for (const specifier of stmt.specifiers || []) {
            const importedName = normalizeImportedName(stmt.source, specifier.imported);
            if (importedName === "eval" && specifier.local) {
              names.push(specifier.local);
            }
          }
        }
        return names;
      }
      function collectDeclaredNames(statements) {
        const names = [];
        for (const stmt of statements || []) {
          names.push(...declaredNamesForStatement(stmt));
        }
        return names;
      }
      function declaredNamesForStatement(stmt) {
        if (!stmt) {
          return [];
        }
        if (["VariableDeclaration", "FunctionDeclaration", "ClassDeclaration", "TraitDeclaration"].includes(stmt.type) && stmt.id && stmt.id.name) {
          return [stmt.id.name];
        }
        if (stmt.type === "VariableUnpackDeclaration") {
          return bindingEntriesForPattern(stmt.pattern).map((entry) => entry.name).filter(Boolean);
        }
        return [];
      }
      function emitPredeclaredNames(names) {
        const unique = [...new Set(names || [])].filter(Boolean);
        return unique.length > 0 ? `let ${unique.map((name2) => `${name2} = null`).join(", ")};` : "";
      }
      function collectExpressionDeclaredNames(statements = []) {
        return collectExpressionDeclaredEntries(statements).map((entry) => entry.name).filter(Boolean);
      }
      function collectExpressionDeclaredEntries(statements = []) {
        const entries = [];
        for (const stmt of statements || []) {
          collectExpressionDeclaredEntriesFromNode(stmt, entries);
        }
        return entries;
      }
      function collectExpressionDeclaredEntriesFromNode(node, entries) {
        if (!node || typeof node !== "object") {
          return;
        }
        if (Array.isArray(node)) {
          for (const item of node) {
            collectExpressionDeclaredEntriesFromNode(item, entries);
          }
          return;
        }
        if (node.type === "LetExpression") {
          if (node.id && node.id.name) {
            entries.push({
              name: node.id.name,
              isWeakStorage: node.isWeakStorage === true
            });
          }
          collectExpressionDeclaredEntriesFromNode(node.init, entries);
          return;
        }
        if ([
          "BlockStatement",
          "ClassDeclaration",
          "DoExpression",
          "FunctionDeclaration",
          "FunctionExpression",
          "MethodDeclaration",
          "TraitDeclaration",
          "TryExpression",
          "AwaitExpression",
          "SpawnExpression"
        ].includes(node.type)) {
          return;
        }
        for (const [key, value] of Object.entries(node)) {
          if (key === "loc") {
            continue;
          }
          collectExpressionDeclaredEntriesFromNode(value, entries);
        }
      }
      function bindingEntriesForPattern(pattern) {
        return pattern && Array.isArray(pattern.entries) ? pattern.entries : [];
      }
      function scopeHasName(options, name2) {
        return !!(options.scopeNames && options.scopeNames.has(name2));
      }
      function emitStoredValue(value, isWeakStorage) {
        return isWeakStorage ? `__zuzu_make_weak_value( ${value} )` : `__zuzu_retain_value( ${value} )`;
      }
      function expressionRetainsCollectionValues(node) {
        return [
          "ArrayExpression",
          "BagLiteral",
          "ObjectExpression",
          "PairListLiteral",
          "SetLiteral"
        ].includes(node.type);
      }
      function emitVariableDeclarationValue(node) {
        let value = node.init ? emitExpression(node.init) : "null";
        if (node.init && node.declaredType && node.declaredType !== "Any") {
          value = `__zuzu_checked_declaration( ${JSON.stringify(node.id.name)}, ${JSON.stringify(node.declaredType)}, ${value} )`;
        }
        return emitStoredValue(value, node.isWeakStorage);
      }
      function emitLetExpression(node) {
        const name2 = emitExpression(node.id);
        const value = emitVariableDeclarationValue(node);
        return `( ${name2} = ${value}, __zuzu_resolve_weak_value( ${name2} ) )`;
      }
      function emitVariableUnpackDeclaration(node) {
        const parts = emitVariableUnpackParts(node);
        return [...parts.prelude, ...parts.declarations].join("\n");
      }
      function emitVariableUnpackParts(node) {
        const sourceName = `__zuzu_unpack_source_${loopCounter++}`;
        const entries = bindingEntriesForPattern(node.pattern);
        const prelude = [
          `const ${sourceName} = __zuzu_unpack_source( ${emitExpression(node.init)} );`
        ];
        const valueNames = entries.map(() => `__zuzu_unpack_value_${loopCounter++}`);
        for (let i = 0; i < entries.length; i++) {
          prelude.push(
            `const ${valueNames[i]} = ${emitUnpackEntryValue(sourceName, entries[i])};`
          );
        }
        if (node.init && expressionRetainsCollectionValues(node.init)) {
          prelude.push(`__zuzu_release_collection_values( ${sourceName} );`);
        }
        const declarations = [];
        for (let i = 0; i < entries.length; i++) {
          const entry = entries[i];
          declarations.push(
            `${node.kind} ${entry.name} = ${valueNames[i]};`
          );
        }
        return { prelude, declarations, entries, valueNames };
      }
      function emitVariableUnpackAssignments(node) {
        const sourceName = `__zuzu_unpack_source_${loopCounter++}`;
        const lines = [
          `const ${sourceName} = __zuzu_unpack_source( ${emitExpression(node.init)} );`
        ];
        const entries = bindingEntriesForPattern(node.pattern);
        const valueNames = entries.map(() => `__zuzu_unpack_value_${loopCounter++}`);
        for (let i = 0; i < entries.length; i++) {
          lines.push(
            `const ${valueNames[i]} = ${emitUnpackEntryValue(sourceName, entries[i])};`
          );
        }
        if (node.init && expressionRetainsCollectionValues(node.init)) {
          lines.push(`__zuzu_release_collection_values( ${sourceName} );`);
        }
        for (let i = 0; i < entries.length; i++) {
          lines.push(`${entries[i].name} = ${valueNames[i]};`);
        }
        return lines.join("\n");
      }
      function emitUnpackEntryValue(sourceName, entry) {
        const defaultThunk = entry.defaultValue ? `() => ${emitExpression(entry.defaultValue)}` : "null";
        return `__zuzu_unpack_value( ${sourceName}, ${emitExpression(entry.key)}, ${defaultThunk}, ${JSON.stringify(entry.name)}, ${entry.declaredType ? JSON.stringify(entry.declaredType) : "null"}, ${entry.isWeakStorage ? "true" : "false"} )`;
      }
      function emitBlockStatement(node, cleanupNames, options = {}) {
        if (node.type === "VariableDeclaration" && node.id && cleanupNames.includes(node.id.name)) {
          return `${emitExpression(node.id)} = ${emitVariableDeclarationValue(node)};`;
        }
        if (node.type === "VariableUnpackDeclaration" && bindingEntriesForPattern(node.pattern).some((entry) => cleanupNames.includes(entry.name))) {
          return emitVariableUnpackAssignments(node);
        }
        return emitStatement(node, options);
      }
      function emitSwitchStatement(node, options = {}) {
        if (options.asyncContext && !options.syncEval) {
          const cases2 = node.cases.map((section) => `{ values: [ ${section.values.map(emitExpression).join(", ")} ], body: async function() ${emitBlock(section.consequent, {
            ...options,
            inSwitchSection: true,
            loopDepth: 0
          })} }`);
          const defaultBody2 = node.defaultCase ? `async function() ${emitBlock(node.defaultCase.consequent, {
            ...options,
            inSwitchSection: true,
            loopDepth: 0
          })}` : "null";
          const tail2 = switchStatementContainsReturn(node) ? options.inSwitchSection ? "if ( __zuzu_switch_result && __zuzu_switch_result.__zuzu_return ) { return __zuzu_switch_result; }" : "if ( __zuzu_switch_result && __zuzu_switch_result.__zuzu_return ) { return __zuzu_switch_result.value; }" : "";
          return `{ let __zuzu_switch_result = await __zuzu_switch_async( ${emitExpression(node.discriminant)}, ${JSON.stringify(node.comparator)}, [ ${cases2.join(", ")} ], ${defaultBody2} ); ${tail2} }`;
        }
        const cases = node.cases.map((section) => `{ values: [ ${section.values.map(emitExpression).join(", ")} ], body: function() ${emitBlock(section.consequent, {
          ...options,
          inSwitchSection: true,
          loopDepth: 0
        })} }`);
        const defaultBody = node.defaultCase ? `function() ${emitBlock(node.defaultCase.consequent, {
          ...options,
          inSwitchSection: true,
          loopDepth: 0
        })}` : "null";
        const tail = switchStatementContainsReturn(node) ? options.inSwitchSection ? "if ( __zuzu_switch_result && __zuzu_switch_result.__zuzu_return ) { return __zuzu_switch_result; }" : "if ( __zuzu_switch_result && __zuzu_switch_result.__zuzu_return ) { return __zuzu_switch_result.value; }" : "";
        return `{ let __zuzu_switch_result = __zuzu_switch( ${emitExpression(node.discriminant)}, ${JSON.stringify(node.comparator)}, [ ${cases.join(", ")} ], ${defaultBody} ); ${tail} }`;
      }
      function emitTraitDeclaration(node, options = {}) {
        const methods = completeMethodDeclarations(node.body || []).map((method) => {
          const value = emitMethodFunction(method, {
            ...options,
            callableName: method.id.name,
            returnTypeName: method.returnType,
            fieldNames: [],
            className: null,
            isStatic: false,
            methodSelfName: "self"
          });
          return `${JSON.stringify(method.id.name)}: ${value}`;
        });
        return `let ${emitExpression(node.id)} = __zuzu_trait( ${JSON.stringify(node.id.name)}, { ${methods.join(", ")} }, ${JSON.stringify(marshalSourceSlice(node, options) || "")}, ${marshalCapturesExpression(marshalTraitCaptureNames(node, options))} );`;
      }
      function emitClassDeclaration(node, options = {}) {
        return emitClassDeclarationWithName(node, node.id.name, options);
      }
      function emitFieldSpec(node) {
        return `{ kind: ${JSON.stringify(node.kind || "let")}, name: ${JSON.stringify(node.id.name)}, typeName: ${node.typeName ? JSON.stringify(node.typeName) : "null"}, isWeakStorage: ${node.isWeakStorage ? "true" : "false"}, accessors: [ ${node.accessors.map((item) => JSON.stringify(item)).join(", ")} ], defaultValue: ${node.defaultValue ? `function() { return ${emitExpression(node.defaultValue)}; }` : "null"} }`;
      }
      function emitNestedDeclarationEntry(node, parentName, options = {}) {
        if (node.type === "ClassDeclaration") {
          const qualified = `${parentName}{${JSON.stringify(node.id.name)}}`;
          return `${JSON.stringify(node.id.name)}: ( function() { ${emitClassDeclarationWithName(node, qualified, options)} return ${node.id.name}; } )()`;
        }
        return `${JSON.stringify(node.id.name)}: ( function() { ${emitStatement(node, options)} return ${node.id.name}; } )()`;
      }
      function emitMethodFunction(node, meta) {
        if (node.isPredeclared) {
          return `__zuzu_bodyless_function( ${JSON.stringify(node.id.name)} )`;
        }
        return `( ${emitFunctionLike(node, `${node.isAsync ? "async " : ""}function()`, {
          ...meta,
          asyncContext: node.isAsync === true,
          extraPreamble: [
            "let self = this;",
            `let __zuzu_super_class__ = ${meta.className ? meta.className : "null"};`,
            `let __zuzu_super_method__ = ${JSON.stringify(node.id.name)};`,
            `let __zuzu_super_static__ = ${meta.isStatic ? 1 : 0};`,
            ...(meta.nestedNames || []).map((name2) => `let ${name2} = self[${JSON.stringify(name2)}];`)
          ].join("\n"),
          scopeNames: /* @__PURE__ */ new Set(["self", "__zuzu_super_class__", "__zuzu_super_method__", "__zuzu_super_static__"]),
          fieldNames: meta.fieldNames || [],
          methodSelfName: meta.methodSelfName || "self"
        })} )`;
      }
      function emitClassDeclarationWithName(node, runtimeName, options = {}) {
        if (node.shorthand && node.traits.length === 0) {
          return `let ${emitExpression(node.id)} = __zuzu_make_class( ${JSON.stringify(runtimeName)}, ${node.base ? emitExpression(node.base) : "Object"} );`;
        }
        const fields = node.body.filter((entry) => entry.type === "FieldDeclaration");
        const methodEntries = completeMethodDeclarations(node.body.filter((entry) => entry.type === "MethodDeclaration"));
        const methods = methodEntries.filter((entry) => !entry.static);
        const statics = methodEntries.filter((entry) => entry.static);
        const nested = node.body.filter((entry) => ["ClassDeclaration", "TraitDeclaration"].includes(entry.type));
        const fieldNames = fields.map((field) => field.id.name);
        const nestedNames = nested.map((entry) => entry.id.name);
        return `let ${emitExpression(node.id)} = __zuzu_define_class( ${JSON.stringify(runtimeName)}, ${node.base ? emitExpression(node.base) : "Object"}, { "marshalSource": ${JSON.stringify(marshalSourceSlice(node, options) || "")}, "marshalCaptures": ${marshalCapturesExpression(marshalClassCaptureNames(node, options))}, "traits": [ ${node.traits.map(emitExpression).join(", ")} ], "fields": [ ${fields.map(emitFieldSpec).join(", ")} ], "methods": { ${methods.map((method) => `${JSON.stringify(method.id.name)}: ${emitMethodFunction(method, {
          ...options,
          callableName: method.id.name,
          returnTypeName: method.returnType,
          fieldNames,
          className: node.id.name,
          isStatic: false,
          methodSelfName: "self",
          nestedNames
        })}`).join(", ")} }, "statics": { ${statics.map((method) => `${JSON.stringify(method.id.name)}: ${emitMethodFunction(method, {
          ...options,
          callableName: method.id.name,
          returnTypeName: method.returnType,
          fieldNames: [],
          className: node.id.name,
          isStatic: true,
          methodSelfName: "self",
          nestedNames
        })}`).join(", ")} }, "nested": { ${nested.map((entry) => emitNestedDeclarationEntry(entry, runtimeName, options)).join(", ")} } } );`;
      }
      function completeMethodDeclarations(entries) {
        const ordered = [];
        const indexes = /* @__PURE__ */ new Map();
        for (const entry of entries || []) {
          if (entry.type !== "MethodDeclaration") {
            continue;
          }
          const key = `${entry.static ? "static:" : "instance:"}${entry.id.name}`;
          if (indexes.has(key)) {
            const index = indexes.get(key);
            if (ordered[index].isPredeclared && !entry.isPredeclared) {
              ordered[index] = entry;
            }
            continue;
          }
          indexes.set(key, ordered.length);
          ordered.push(entry);
        }
        return ordered;
      }
      function switchStatementContainsReturn(node) {
        return node.cases.some((section) => blockContainsReturn(section.consequent)) || node.defaultCase && blockContainsReturn(node.defaultCase.consequent);
      }
      function blockContainsReturn(block) {
        return block.body.some(statementContainsReturn);
      }
      function statementContainsReturn(stmt) {
        switch (stmt.type) {
          case "ReturnStatement":
            return true;
          case "BlockStatement":
            return blockContainsReturn(stmt);
          case "IfStatement":
            return blockContainsReturn(stmt.consequent) || (stmt.alternate ? stmt.alternate.type === "BlockStatement" ? blockContainsReturn(stmt.alternate) : statementContainsReturn(stmt.alternate) : false);
          case "ForInStatement":
            return blockContainsReturn(stmt.body) || (stmt.elseBlock ? blockContainsReturn(stmt.elseBlock) : false);
          case "WhileStatement":
            return blockContainsReturn(stmt.body);
          case "TryStatement":
            return blockContainsReturn(stmt.block) || (stmt.handlers || []).some((handler) => blockContainsReturn(handler.body));
          case "SwitchStatement":
            return switchStatementContainsReturn(stmt);
          default:
            return false;
        }
      }
      function emitExpression(node) {
        const options = currentEmitContext();
        switch (node.type) {
          case "Identifier":
            if (node.name === "^^") {
              return options.chainHereName || `( () => { throw new Error( "Undeclared variable '^^'" ); } )()`;
            }
            if (options.fieldNames && options.fieldNames.includes(node.name) && !scopeHasName(options, node.name)) {
              return `${options.methodSelfName || "self"}[${JSON.stringify(node.name)}]`;
            }
            return node.name === "__argc__" ? "__argc__" : node.name;
          case "NumericLiteral":
            return String(node.value);
          case "StringLiteral":
            return JSON.stringify(node.value);
          case "BinaryStringLiteral":
            return `__zuzu_binary_literal( ${JSON.stringify(node.value)} )`;
          case "TemplateLiteral":
            return emitTemplateLiteral(node);
          case "RegExpLiteral":
            return `new RegExp( ${emitRegExpPattern(node)}, ${JSON.stringify(node.flags)} )`;
          case "Literal":
            if (node.value === null) {
              return "null";
            }
            return node.value ? "true" : "false";
          case "Super":
            throw new UnsupportedSyntaxError("super must be called like a method");
          case "GroupedExpression":
            return `( ${emitExpression(node.expression)} )`;
          case "ArrayExpression":
            return `__zuzu_array( [ ${node.elements.map((element) => {
              if (element.type === "BinaryExpression" && element.operator === "...") {
                return `...${emitExpression(element)}`;
              }
              return emitExpression(element);
            }).join(", ")} ] )`;
          case "SetLiteral":
            return `__zuzu_set( [ ${emitCollectionElements(node.elements)} ] )`;
          case "BagLiteral":
            return `__zuzu_bag( [ ${emitCollectionElements(node.elements)} ] )`;
          case "PairListLiteral":
            return `__zuzu_pairlist_literal( [ ${emitPairListEntries(node.entries)} ] )`;
          case "ObjectExpression":
            return `( () => { const __zuzu_obj = {}; ${node.properties.map(
              (prop) => `__zuzu_obj[${JSON.stringify(prop.key)}] = __zuzu_retain_collection_value( __zuzu_obj, ${emitExpression(prop.value)} );`
            ).join(" ")} return __zuzu_obj; } )()`;
          case "NamedArgument":
            return `[ ${emitExpression(node.keyExpr || { type: "StringLiteral", value: node.key })}, ${emitExpression(node.value)} ]`;
          case "BraceIdentifier":
            return JSON.stringify(node.name);
          case "SliceExpression":
            return emitSliceExpression(node);
          case "MemberExpression":
            if (node.computed) {
              if (node.property.type === "BraceIdentifier") {
                return `__zuzu_get_brace_member( ${emitExpression(node.object)}, ${JSON.stringify(node.property.name)}, () => ${node.property.name} )`;
              }
              return `__zuzu_get_index( ${emitExpression(node.object)}, ${emitExpression(node.property)} )`;
            }
            if (node.property.name === "length") {
              return `__zuzu_length( ${emitExpression(node.object)} )`;
            }
            return `__zuzu_call_member( ${emitExpression(node.object)}, ${JSON.stringify(node.property.name)} )`;
          case "CallExpression":
            return emitCallExpression(node, options);
          case "RegexReplaceExpression":
            return emitRegexReplaceExpression(node);
          case "RefExpression":
            return emitRefExpression(node);
          case "AssignmentExpression":
            return emitAssignmentExpression(node);
          case "LetExpression":
            return emitLetExpression(node);
          case "ConditionalExpression":
            return `( __zuzu_truthy( ${emitExpression(node.test)} ) ? ${emitExpression(node.consequent)} : ${emitExpression(node.alternate)} )`;
          case "ShortTernaryExpression":
            return `( __zuzu_truthy( ${emitExpression(node.test)} ) ? ${emitExpression(node.test)} : ${emitExpression(node.alternate)} )`;
          case "TryExpression":
            return emitTryExpression(node);
          case "DoExpression":
            return emitDoExpression(node);
          case "UnaryExpression":
            return emitUnaryExpression(node);
          case "BinaryExpression":
            return emitBinaryExpression(node);
          case "UpdateExpression":
            {
              const target = unwrapGroupedExpression(node.argument);
              if (target && target.type === "BinaryExpression" && ["@", "@@", "@?"].includes(target.operator)) {
                const mode = target.operator === "@@" ? "all" : target.operator === "@?" ? "maybe" : "first";
                return `__zuzu_path_update( ${emitExpression(target.left)}, ${emitExpression(target.right)}, "${mode}", ${JSON.stringify(node.operator)}, ${node.prefix ? "true" : "false"} )`;
              }
            }
            return node.prefix ? `( ${emitAssignmentTarget(node.argument)} = __zuzu_${node.operator === "++" ? "add" : "sub"}( ${emitAssignmentTarget(node.argument)}, 1 ) )` : `( () => { const __zuzu_old = __zuzu_num( ${emitAssignmentTarget(node.argument)} ); ${emitAssignmentTarget(node.argument)} = __zuzu_${node.operator === "++" ? "add" : "sub"}( __zuzu_old, 1 ); return __zuzu_old; } )()`;
          case "FunctionExpression": {
            const fn2 = emitFunctionLike(node, `${node.isAsync ? "async " : ""}function()`, {
              ...nestedFunctionOptions(options),
              asyncContext: node.isAsync === true,
              syncEval: options.syncEval === true
            });
            const meta = marshalMetaExpression(
              "function",
              node.id && node.id.name,
              marshalFunctionSource(node),
              marshalCaptureNames(node)
            );
            return `__zuzu_with_marshal_meta( ( ${fn2} ), ${meta} )`;
          }
          case "AwaitExpression":
            if (currentEmitContext().syncEval) {
              return `__zuzu_await_block_sync( ( () => { ${emitExpressionBlock(node.block, {
                ...options,
                asyncContext: false,
                nonLocalReturn: true,
                boxResult: true,
                syncEval: true
              })} } )() )`;
            }
            return `await __zuzu_await_block( ( async () => { ${emitExpressionBlock(node.block, {
              ...options,
              asyncContext: true,
              nonLocalReturn: true,
              boxResult: true
            })} } )() )`;
          case "SpawnExpression":
            return `__zuzu_spawn( async () => { ${emitExpressionBlock(node.block, {
              ...options,
              asyncContext: true,
              nonLocalReturn: true
            })} }, { name: "<spawn>", line: ${JSON.stringify(node.loc.start.line)} } )`;
          case "NewExpression":
            return emitNewExpression(node);
          default:
            throw new UnsupportedSyntaxError(`Unsupported expression node ${node.type}`);
        }
      }
      function emitNewExpression(node) {
        const traitList = Array.isArray(node.traits) && node.traits.length > 0 ? `[ ${node.traits.map(emitExpression).join(", ")} ]` : null;
        if (node.callee.type === "CallExpression") {
          const callee = emitExpression(node.callee.callee);
          const constructor = traitList ? `__zuzu_class_with_traits( ${callee}, ${traitList} )` : callee;
          const args = emitCallArgumentList(node.callee.arguments);
          if (traitList) {
            return `new (${constructor})( ${args} )`;
          }
          if (node.callee.callee.type === "Identifier" || node.callee.callee.type === "MemberExpression" && !node.callee.callee.computed) {
            return `new ${constructor}( ${args} )`;
          }
          return `new (${constructor})( ${args} )`;
        }
        if (traitList) {
          return `new (__zuzu_class_with_traits( ${emitExpression(node.callee)}, ${traitList} ))`;
        }
        return `new ${emitExpression(node.callee)}`;
      }
      function emitCallExpression(node, options = {}) {
        let source;
        if (node.callee.type === "Super") {
          const argArray = emitCallArgumentArray(node.arguments);
          source = `__zuzu_super_dispatch( __zuzu_super_static__, self, __zuzu_super_class__, __zuzu_super_method__, ${argArray} )`;
        } else if (node.callee.type === "Identifier" && (options.evalNames || /* @__PURE__ */ new Set(["eval"])).has(node.callee.name) && node.arguments.length > 0) {
          source = emitEvalCall(node.arguments);
        } else if (node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && node.callee.property.name === "length" && node.arguments.length === 0) {
          source = `__zuzu_length( ${emitExpression(node.callee.object)} )`;
        } else if (callReleasesTemporaryCollectionReceiver(node)) {
          const object = emitExpression(node.callee.object);
          const property = JSON.stringify(node.callee.property.name);
          source = `( () => { const __zuzu_receiver = ${object}; const __zuzu_result = __zuzu_call_member( __zuzu_receiver, ${property} ); __zuzu_release_collection_values( __zuzu_receiver ); return __zuzu_result; } )()`;
        } else if (node.callee.type === "MemberExpression") {
          const args = emitCallArgumentList(node.arguments);
          if (options.asyncContext && !options.syncEval && !node.callee.computed && node.callee.property.type === "Identifier" && ["map", "grep", "reduce"].includes(node.callee.property.name) && node.arguments.length > 0) {
            const object = emitExpression(node.callee.object);
            const method = node.callee.property.name;
            source = `await __zuzu_collection_${method}_async( ${object}, ${args} )`;
          } else if (node.arguments.length === 0) {
            const object = emitExpression(node.callee.object);
            const property = node.callee.computed ? node.callee.property.type === "BraceIdentifier" ? `__zuzu_resolve_brace_key( ${object}, ${JSON.stringify(node.callee.property.name)}, () => ${node.callee.property.name} )` : emitExpression(node.callee.property) : JSON.stringify(node.callee.property.name);
            source = `__zuzu_call_member( ${object}, ${property} )`;
          } else {
            const object = emitExpression(node.callee.object);
            if (node.callee.computed) {
              const property = node.callee.property.type === "BraceIdentifier" ? `__zuzu_resolve_brace_key( ${object}, ${JSON.stringify(node.callee.property.name)}, () => ${node.callee.property.name} )` : emitExpression(node.callee.property);
              source = `__zuzu_call_member( ${object}, ${property}, ${args} )`;
            } else {
              source = `__zuzu_call_member( ${object}, ${JSON.stringify(node.callee.property.name)}, ${args} )`;
            }
          }
        } else {
          source = `${emitExpression(node.callee)}( ${emitCallArgumentList(node.arguments)} )`;
        }
        if (!callNeedsTraceMetadata(node, options) || /\bawait\b/u.test(source)) {
          return source;
        }
        const line = node.loc && node.loc.start ? node.loc.start.line : null;
        return `__zuzu_callsite( { line: ${JSON.stringify(line)} }, () => ${source} )`;
      }
      function callReleasesTemporaryCollectionReceiver(node) {
        return node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier" && node.arguments.length === 0 && node.callee.object.type === "ArrayExpression" && ["copy", "to_Array", "to_Bag", "to_List", "to_Set"].includes(node.callee.property.name);
      }
      function callNeedsTraceMetadata(node, options = {}) {
        if (node.callee.type === "Identifier") {
          if (options.asyncNames && options.asyncNames.has(node.callee.name)) {
            return true;
          }
          return [
            "all",
            "failed",
            "race",
            "resolved",
            "sleep",
            "timeout",
            "yield"
          ].includes(node.callee.name);
        }
        if (node.callee.type === "MemberExpression" && !node.callee.computed && node.callee.property.type === "Identifier") {
          return [
            "append_async",
            "append_utf8_async",
            "each_line",
            "lines",
            "lines_async",
            "lines_utf8",
            "lines_utf8_async",
            "next_line",
            "pipeline",
            "pipeline_async",
            "recv",
            "request",
            "request_async",
            "run",
            "run_async",
            "send",
            "send_async",
            "sleep_async",
            "slurp",
            "slurp_async",
            "slurp_utf8",
            "slurp_utf8_async",
            "spew",
            "spew_async",
            "spew_utf8",
            "spew_utf8_async"
          ].includes(node.callee.property.name);
        }
        return false;
      }
      function emitUnaryExpression(node) {
        const target = unwrapGroupedExpression(node.argument);
        if ((node.operator === "++" || node.operator === "--") && target && target.type === "BinaryExpression" && ["@", "@@", "@?"].includes(target.operator)) {
          const mode = target.operator === "@@" ? "all" : target.operator === "@?" ? "maybe" : "first";
          return `__zuzu_path_update( ${emitExpression(target.left)}, ${emitExpression(target.right)}, "${mode}", ${JSON.stringify(node.operator)}, true )`;
        }
        if (node.operator === "not") {
          return `__zuzu_not( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "\xAC") {
          return `__zuzu_not( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "!") {
          return `__zuzu_not( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "~") {
          return `__zuzu_bit_not( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "typeof") {
          return `__zuzu_typeof( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "abs") {
          return `__zuzu_abs( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "sqrt") {
          return `__zuzu_sqrt( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "\u221A") {
          return `__zuzu_sqrt( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "floor") {
          return `__zuzu_floor( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "ceil") {
          return `__zuzu_ceil( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "round") {
          return `__zuzu_round( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "int") {
          return `__zuzu_int( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "length") {
          return `__zuzu_length( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "uc") {
          return `__zuzu_uc( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "lc") {
          return `__zuzu_lc( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "+") {
          return `__zuzu_num( ${emitExpression(node.argument)} )`;
        }
        if (node.operator === "-") {
          return `( -__zuzu_num( ${emitExpression(node.argument)} ) )`;
        }
        return `${node.operator}${emitExpression(node.argument)}`;
      }
      function emitTemplateLiteral(node) {
        if (!node.parts || node.parts.length === 0) {
          return '""';
        }
        let out = emitExpression(node.parts[0]);
        for (let i = 1; i < node.parts.length; i++) {
          out = `__zuzu_concat( ${out}, ${emitExpression(node.parts[i])} )`;
        }
        return out;
      }
      function emitRegExpPattern(node) {
        if (!node.parts || node.parts.length === 0) {
          return JSON.stringify(node.pattern);
        }
        return emitTemplateLiteral({
          type: "TemplateLiteral",
          parts: node.parts
        });
      }
      function emitCollectionElements(elements) {
        return elements.map((element) => {
          if (element.type === "BinaryExpression" && element.operator === "...") {
            return `...${emitExpression(element)}`;
          }
          return emitExpression(element);
        }).join(", ");
      }
      function emitPairListEntries(entries) {
        return entries.map((entry) => {
          if (entry.type === "PairListEntry") {
            const keyExpr = entry.keyExpr || { type: "StringLiteral", value: entry.key };
            return `[ ${emitExpression(keyExpr)}, ${emitExpression(entry.value)} ]`;
          }
          return emitExpression(entry);
        }).join(", ");
      }
      function emitBinaryExpression(node) {
        if (node.operator === "\u25B7" || node.operator === "|>") {
          const input = emitExpression(node.left);
          const hereName = `__zuzu_chain_${chainCounter++}`;
          const right2 = withEmitContext({
            ...currentEmitContext(),
            chainHereName: hereName
          }, () => emitExpression(node.right));
          return `( () => { const ${hereName} = ${input}; return ${right2}; } )()`;
        }
        if (node.operator === "\u25C1" || node.operator === "<|") {
          const input = emitExpression(node.right);
          const hereName = `__zuzu_chain_${chainCounter++}`;
          const left2 = withEmitContext({
            ...currentEmitContext(),
            chainHereName: hereName
          }, () => emitExpression(node.left));
          return `( () => { const ${hereName} = ${input}; return ${left2}; } )()`;
        }
        const left = emitExpression(node.left);
        const right = emitExpression(node.right);
        switch (node.operator) {
          case "and":
          case "\u22C0":
            return `( () => { const __zuzu_left = ${left}; return __zuzu_truthy( __zuzu_left ) ? ( __zuzu_truthy( ${right} ) ? 1 : 0 ) : 0; } )()`;
          case "or":
          case "\u22C1":
            return `( () => { const __zuzu_left = ${left}; return __zuzu_truthy( __zuzu_left ) ? 1 : ( __zuzu_truthy( ${right} ) ? 1 : 0 ); } )()`;
          case "xor":
          case "\u22BB":
            return `__zuzu_xor( ${left}, ${right} )`;
          case "nand":
          case "\u22BC":
            return `__zuzu_nand( ${left}, ${right} )`;
          case "eq":
            return `__zuzu_str_eq( ${left}, ${right} )`;
          case "ne":
            return `( __zuzu_str_eq( ${left}, ${right} ) ? 0 : 1 )`;
          case "default":
            return `__zuzu_default( ${left}, ${right} )`;
          case "==":
            return `__zuzu_eq( ${left}, ${right} )`;
          case "=":
            return `__zuzu_num_eq( ${left}, ${right} )`;
          case "\u2261":
            return `__zuzu_eq( ${left}, ${right} )`;
          case "\u2262":
            return `__zuzu_ne( ${left}, ${right} )`;
          case "!=":
          case "\u2260":
            return `__zuzu_ne( ${left}, ${right} )`;
          case "~":
            return `__zuzu_match( ${left}, ${right} )`;
          case "_":
            return `__zuzu_concat( ${left}, ${right} )`;
          case "+":
            return `__zuzu_add( ${left}, ${right} )`;
          case "-":
            return `__zuzu_sub( ${left}, ${right} )`;
          case "*":
          case "\xD7":
            return `__zuzu_mul( ${left}, ${right} )`;
          case "/":
          case "\xF7":
            return `__zuzu_div( ${left}, ${right} )`;
          case "**":
            return `__zuzu_pow( ${left}, ${right} )`;
          case "mod":
            return `( __zuzu_num( ${left} ) % __zuzu_num( ${right} ) )`;
          case "...":
            return `__zuzu_range( ${left}, ${right} )`;
          case "<=>":
          case "\u2276":
          case "\u2277":
            return `__zuzu_cmp( ${left}, ${right} )`;
          case "cmp":
            return `__zuzu_str_cmp( ${left}, ${right} )`;
          case "gt":
            return `__zuzu_str_gt( ${left}, ${right} )`;
          case "ge":
            return `__zuzu_str_ge( ${left}, ${right} )`;
          case "lt":
            return `__zuzu_str_lt( ${left}, ${right} )`;
          case "le":
            return `__zuzu_str_le( ${left}, ${right} )`;
          case "eqi":
            return `__zuzu_str_eqi( ${left}, ${right} )`;
          case "nei":
            return `__zuzu_str_nei( ${left}, ${right} )`;
          case "gti":
            return `__zuzu_str_gti( ${left}, ${right} )`;
          case "gei":
            return `__zuzu_str_gei( ${left}, ${right} )`;
          case "lti":
            return `__zuzu_str_lti( ${left}, ${right} )`;
          case "lei":
            return `__zuzu_str_lei( ${left}, ${right} )`;
          case "cmpi":
            return `__zuzu_str_cmpi( ${left}, ${right} )`;
          case "\u2264":
            return `__zuzu_num_lte( ${left}, ${right} )`;
          case "\u2265":
            return `__zuzu_num_gte( ${left}, ${right} )`;
          case "<":
            return `__zuzu_num_lt( ${left}, ${right} )`;
          case "<=":
            return `__zuzu_num_lte( ${left}, ${right} )`;
          case ">":
            return `__zuzu_num_gt( ${left}, ${right} )`;
          case ">=":
            return `__zuzu_num_gte( ${left}, ${right} )`;
          case "union":
          case "\u22C3":
            return `__zuzu_union( ${left}, ${right} )`;
          case "intersection":
          case "\u22C2":
            return `__zuzu_intersection( ${left}, ${right} )`;
          case "\\":
          case "\u2216":
          case "difference":
            return `__zuzu_difference( ${left}, ${right} )`;
          case "subsetof":
          case "\u2282":
            return `__zuzu_subsetof( ${left}, ${right} )`;
          case "supersetof":
          case "\u2283":
            return `__zuzu_supersetof( ${left}, ${right} )`;
          case "equivalentof":
          case "\u2282\u2283":
            return `__zuzu_equivalentof( ${left}, ${right} )`;
          case "instanceof":
            return `__zuzu_instanceof( ${left}, ${right} )`;
          case "does":
            return `__zuzu_does( ${left}, ${right} )`;
          case "can":
            if (node.right.type === "Identifier") {
              return `__zuzu_can( ${left}, ${JSON.stringify(node.right.name)} )`;
            }
            return `__zuzu_can( ${left}, ${right} )`;
          case "in":
          case "\u2208":
            return `__zuzu_contains( ${right}, ${left} )`;
          case "not_in":
          case "\u2209":
            return `( __zuzu_contains( ${right}, ${left} ) ? 0 : 1 )`;
          case "@":
            return `__zuzu_path_op( ${left}, ${right}, "first" )`;
          case "@@":
            return `__zuzu_path_op( ${left}, ${right}, "all" )`;
          case "@?":
            return `__zuzu_path_op( ${left}, ${right}, "exists" )`;
          case "&":
            return `__zuzu_bit_and( ${left}, ${right} )`;
          case "|":
            return `__zuzu_bit_or( ${left}, ${right} )`;
          case "^":
            return `__zuzu_bit_xor( ${left}, ${right} )`;
          default:
            return `( ${left} ${node.operator} ${right} )`;
        }
      }
      function emitAssignmentExpression(node) {
        const options = currentEmitContext();
        if (node.left && node.left.type === "BinaryExpression" && ["@", "@@", "@?"].includes(node.left.operator)) {
          const target = emitExpression(node.left.left);
          const path = emitExpression(node.left.right);
          const right2 = emitExpression(node.right);
          const mode = node.left.operator === "@@" ? "all" : node.left.operator === "@?" ? "maybe" : "first";
          return `__zuzu_path_assign( ${target}, ${path}, ${right2}, "${mode}", ${JSON.stringify(node.operator)}, ${node.isWeakWrite ? "true" : "false"} )`;
        }
        if (node.left && node.left.type === "SliceExpression" && node.operator === ":=") {
          const objectTarget = emitAssignmentTarget(node.left.object);
          const objectValue = emitExpression(node.left.object);
          const start = node.left.start ? emitExpression(node.left.start) : "0";
          const length = node.left.length == null ? "null" : emitExpression(node.left.length);
          const right2 = emitExpression(node.right);
          return `${objectTarget} = __zuzu_assign_slice( ${objectValue}, ${start}, ${length}, ${right2} )`;
        }
        const left = emitAssignmentTarget(node.left);
        const right = emitExpression(node.right);
        switch (node.operator) {
          case ":=":
            if (node.left && node.left.type === "Identifier") {
              const weakStorage = options.weakStorageNames && options.weakStorageNames.has(node.left.name);
              return weakStorage || node.isWeakWrite ? `${left} = __zuzu_assign_weak( ${left}, ${right} )` : `${left} = __zuzu_assign_strong( ${left}, ${right} )`;
            }
            if (node.left && node.left.type === "MemberExpression") {
              const object = emitExpression(node.left.object);
              const objectTarget = emitAssignmentTarget(node.left.object);
              const key = node.left.computed ? node.left.property.type === "BraceIdentifier" ? `__zuzu_resolve_brace_key( ${object}, ${JSON.stringify(node.left.property.name)}, () => ${node.left.property.name} )` : emitExpression(node.left.property) : JSON.stringify(node.left.property.name);
              return `__zuzu_assign_index( ${object}, ${key}, ${right}, ${node.isWeakWrite ? "true" : "false"}, ( __zuzu_updated ) => ( ${objectTarget} = __zuzu_updated ) )`;
            }
            return `${left} = ${right}`;
          case "+=":
            return `${left} = __zuzu_add( ${left}, ${right} )`;
          case "-=":
            return `${left} = __zuzu_sub( ${left}, ${right} )`;
          case "*=":
          case "\xD7=":
            return `${left} = __zuzu_mul( ${left}, ${right} )`;
          case "/=":
          case "\xF7=":
            return `${left} = __zuzu_div( ${left}, ${right} )`;
          case "%=":
            return `${left} = __zuzu_mod( ${left}, ${right} )`;
          case "**=":
            return `${left} = __zuzu_pow( ${left}, ${right} )`;
          case "_=":
            return `${left} = __zuzu_concat( ${left}, ${right} )`;
          case "?:=":
            return `( ${left} == null ? ( ${left} = ${right} ) : ${left} )`;
          default:
            throw new UnsupportedSyntaxError(`Unsupported assignment operator ${node.operator}`);
        }
      }
      function emitAssignmentTarget(node) {
        if (node && node.type === "MemberExpression" && node.computed && node.property) {
          if (node.property.type === "BraceIdentifier") {
            const object = emitExpression(node.object);
            return `${object}[__zuzu_resolve_brace_key( ${object}, ${JSON.stringify(node.property.name)}, () => ${node.property.name} )]`;
          }
          return `${emitExpression(node.object)}[${emitExpression(node.property)}]`;
        }
        return emitExpression(node);
      }
      function emitSliceExpression(node) {
        const object = emitExpression(node.object);
        const start = node.start ? emitExpression(node.start) : "0";
        const length = node.length == null ? "null" : emitExpression(node.length);
        return `__zuzu_get_slice( ${object}, ${start}, ${length} )`;
      }
      function unwrapGroupedExpression(node) {
        let current = node;
        while (current && current.type === "GroupedExpression") {
          current = current.expression;
        }
        return current;
      }
      function emitRegexReplaceExpression(node) {
        const leftTarget = unwrapGroupedExpression(node.left);
        if (leftTarget && leftTarget.type === "BinaryExpression" && ["@", "@@", "@?"].includes(leftTarget.operator)) {
          const mode = leftTarget.operator === "@@" ? "all" : leftTarget.operator === "@?" ? "maybe" : "first";
          const pattern2 = node.pattern.type === "RegExpLiteral" ? emitExpression(node.pattern) : `__zuzu_to_regexp( ${emitExpression(node.pattern)} )`;
          return `__zuzu_path_assign( ${emitExpression(leftTarget.left)}, ${emitExpression(leftTarget.right)}, [ ${pattern2}, ( m ) => ${emitExpression(node.replacement)} ], "${mode}", "~=" )`;
        }
        const left = emitExpression(node.left);
        const pattern = node.pattern.type === "RegExpLiteral" ? emitExpression(node.pattern) : `__zuzu_to_regexp( ${emitExpression(node.pattern)} )`;
        const replacement = emitExpression(node.replacement);
        return `${left} = __zuzu_regex_replace( ${left}, ${pattern}, ( ...__zuzu_match_args ) => { const m = __zuzu_match_args; return ${replacement}; } )`;
      }
      function emitRefExpression(node) {
        const arg = unwrapGroupedExpression(node.argument);
        if (arg && arg.type === "BinaryExpression" && ["@", "@@", "@?"].includes(arg.operator)) {
          const mode = arg.operator === "@@" ? "all" : arg.operator === "@?" ? "maybe" : "first";
          return `__zuzu_path_ref( ${emitExpression(arg.left)}, ${emitExpression(arg.right)}, "${mode}" )`;
        }
        if (arg.type === "SliceExpression") {
          return `__zuzu_ref_slice( ${emitExpression(arg.object)}, ${arg.start ? emitExpression(arg.start) : "0"}, ${arg.length == null ? "null" : emitExpression(arg.length)} )`;
        }
        if (arg.type === "MemberExpression") {
          if (arg.computed) {
            if (arg.property.type === "BraceIdentifier") {
              return `__zuzu_ref_index( ${emitExpression(arg.object)}, ${JSON.stringify(arg.property.name)} )`;
            }
            return `__zuzu_ref_index( ${emitExpression(arg.object)}, ${emitExpression(arg.property)} )`;
          }
          return `__zuzu_ref_key( ${emitExpression(arg.object)}, ${JSON.stringify(arg.property.name)} )`;
        }
        throw new UnsupportedSyntaxError("Unsupported reference target");
      }
      function emitExpressionBlock(block, options = {}) {
        return withEmitContext(options, () => {
          if (!block || !Array.isArray(block.body) || block.body.length === 0) {
            return options.boxResult ? "return { __zuzu_await_block_value: null };" : "return null;";
          }
          const expressionDeclaredNames = collectExpressionDeclaredNames(block.body);
          const scopedOptions = {
            ...options,
            weakStorageNames: /* @__PURE__ */ new Set([
              ...options.weakStorageNames || [],
              ...collectWeakDeclaredNames(block.body)
            ]),
            scopeNames: /* @__PURE__ */ new Set([
              ...options.scopeNames || [],
              ...expressionDeclaredNames
            ])
          };
          return withEmitContext(scopedOptions, () => {
            const lines = [];
            const prelude = emitPredeclaredNames(expressionDeclaredNames);
            if (prelude) {
              lines.push(prelude);
            }
            const lastIndex = block.body.length - 1;
            for (let i = 0; i < block.body.length; i++) {
              const stmt = block.body[i];
              if (i === lastIndex) {
                lines.push(emitExpressionTail(stmt, scopedOptions));
              } else {
                lines.push(emitExpressionInnerStatement(stmt, scopedOptions));
              }
            }
            return lines.join("\n");
          });
        });
      }
      function emitExpressionInnerStatement(stmt, options = {}) {
        if (options.nonLocalReturn && stmt.type === "ReturnStatement") {
          return emitDoReturnStatement(stmt);
        }
        return emitStatement(stmt, options);
      }
      function emitExpressionTail(stmt, options = {}) {
        if (stmt.type === "ExpressionStatement") {
          const value = emitExpression(stmt.expression);
          return options.boxResult ? `return { __zuzu_await_block_value: ${value} };` : `return ${value};`;
        }
        if (stmt.type === "ReturnStatement") {
          return options.nonLocalReturn ? emitDoReturnStatement(stmt) : emitStatement(stmt);
        }
        if (stmt.type === "BlockStatement") {
          return emitExpressionBlock(stmt, options);
        }
        if (stmt.type === "IfStatement") {
          const prefix = stmt.declaration ? `${emitStatement(stmt.declaration, options)}
` : "";
          const alternate = stmt.alternate ? emitExpressionTail(stmt.alternate, options) : options.boxResult ? "return { __zuzu_await_block_value: null };" : "return null;";
          return `${prefix}if ( __zuzu_truthy( ${emitExpression(stmt.test)} ) ) { ${emitExpressionBlock(stmt.consequent, options)} } else { ${alternate} }`;
        }
        return emitStatement(stmt, options);
      }
      function emitDoReturnStatement(stmt) {
        return `throw { __zuzu_nonlocal_return: true, value: ${stmt.argument ? emitExpression(stmt.argument) : "null"} };`;
      }
      function emitTryExpression(node) {
        const options = currentEmitContext();
        const handlers = node.handlers || [];
        let catchBody = "throw __zuzu_err;";
        if (handlers.length > 0) {
          const branches = handlers.map((handler, index) => {
            const cond = handler.typeName === "Exception" || handler.typeName === "Any" ? "true" : `__zuzu_instanceof( __zuzu_err, ${handler.typeName} )`;
            const prefix = index === 0 ? `if ( ${cond} )` : `else if ( ${cond} )`;
            return `${prefix} { let ${handler.paramName} = __zuzu_err; ${emitExpressionBlock(handler.body, options)} }`;
          });
          catchBody = `if ( __zuzu_err && __zuzu_err.__zuzu_nonlocal_return ) { throw __zuzu_err; } __zuzu_err = __zuzu_normalize_exception( __zuzu_err ); ${branches.join(" ")} else { throw __zuzu_err; }`;
        }
        return `( ${options.asyncContext ? "async " : ""}() => { try { ${emitExpressionBlock(node.block, options)} } catch ( __zuzu_err ) { ${catchBody} } } )()`;
      }
      function emitDoExpression(node) {
        return `( () => { ${emitExpressionBlock(node.block, {
          ...currentEmitContext(),
          nonLocalReturn: true
        })} } )()`;
      }
      function emitCallArguments(args) {
        const positional = [];
        const named = [];
        for (const arg of args) {
          if (arg.type === "NamedArgument") {
            named.push(arg);
          } else {
            positional.push(emitExpression(arg));
          }
        }
        if (named.length > 0) {
          positional.push(`__zuzu_temp_pairlist( [ ${named.map((arg) => emitExpression(arg)).join(", ")} ] )`);
        }
        return positional;
      }
      function emitCallArgumentList(args) {
        if (!callArgumentsHaveSpread(args)) {
          return emitCallArguments(args).join(", ");
        }
        return `...${emitSpreadCallArguments(args)}`;
      }
      function emitCallArgumentArray(args) {
        if (args.length === 0) {
          return "[]";
        }
        if (!callArgumentsHaveSpread(args)) {
          return `[ ${emitCallArguments(args).join(", ")} ]`;
        }
        return emitSpreadCallArguments(args);
      }
      function callArgumentsHaveSpread(args) {
        return args.some((arg) => arg.type === "SpreadArgument");
      }
      function emitSpreadCallArguments(args) {
        return `__zuzu_spread_call_args( [ ${args.map(emitSpreadCallArgumentPart).join(", ")} ] )`;
      }
      function emitSpreadCallArgumentPart(arg) {
        if (arg.type === "SpreadArgument") {
          return `__zuzu_snapshot_spread_arg( ${emitExpression(arg.argument)} )`;
        }
        if (arg.type === "NamedArgument") {
          return `{ type: "named", value: ${emitExpression(arg)} }`;
        }
        return `{ type: "positional", value: ${emitExpression(arg)} }`;
      }
      function emitEvalCall(args) {
        if (callArgumentsHaveSpread(args)) {
          return `eval( __zuzu_prepare_eval_call_args( ${emitSpreadCallArguments(args)} ) )`;
        }
        const positional = [];
        const named = [];
        for (const arg of args) {
          if (arg.type === "NamedArgument") {
            named.push(arg);
          } else {
            positional.push(arg);
          }
        }
        const source = positional.length > 0 ? emitExpression(positional[0]) : '""';
        const namedArgs = named.length > 0 ? `__zuzu_pairlist_literal( [ ${named.map((arg) => emitExpression(arg)).join(", ")} ] )` : "null";
        return `eval( __zuzu_prepare_eval( ${source}, ${namedArgs} ) )`;
      }
      module2.exports = {
        emitProgram
      };
      function programNeedsAsyncWrapper(ast) {
        return ast.body.some((stmt) => nodeContainsAsyncControl(stmt));
      }
      function nodeContainsAsyncControl(node) {
        if (!node || typeof node !== "object") {
          return false;
        }
        if (node.type === "AwaitExpression" || node.type === "SpawnExpression") {
          return true;
        }
        if (["FunctionDeclaration", "FunctionExpression", "MethodDeclaration"].includes(node.type)) {
          return false;
        }
        for (const value of Object.values(node)) {
          if (Array.isArray(value)) {
            if (value.some(nodeContainsAsyncControl)) {
              return true;
            }
          } else if (nodeContainsAsyncControl(value)) {
            return true;
          }
        }
        return false;
      }
    }
  });

  // lib/transpiler-new/validate-bindings.js
  var require_validate_bindings = __commonJS({
    "lib/transpiler-new/validate-bindings.js"(exports2, module2) {
      "use strict";
      var { TranspilerSyntaxError } = require_errors();
      var Scope = class {
        constructor(parent = null) {
          this.parent = parent;
          this.bindings = /* @__PURE__ */ new Map();
        }
        declare(name2, mutable, node) {
          if (!name2) {
            return;
          }
          if (this.bindings.has(name2)) {
            throw syntaxError(`Redeclaration of '${name2}' in the same scope`, node);
          }
          this.bindings.set(name2, { mutable, bodylessFunction: false });
        }
        declareFunction(node) {
          const name2 = node.id && node.id.name;
          if (!name2) {
            return;
          }
          const existing = this.bindings.get(name2);
          if (existing && existing.bodylessFunction && !node.isPredeclared) {
            existing.bodylessFunction = false;
            return;
          }
          if (existing) {
            throw syntaxError(`Redeclaration of '${name2}' in the same scope`, node);
          }
          this.bindings.set(name2, {
            mutable: false,
            bodylessFunction: node.isPredeclared === true
          });
        }
        lookup(name2) {
          if (this.bindings.has(name2)) {
            return this.bindings.get(name2);
          }
          return this.parent ? this.parent.lookup(name2) : null;
        }
      };
      function tokenFor(node) {
        const start = node && node.loc && node.loc.start;
        if (!start) {
          return null;
        }
        return {
          line: start.line,
          column: start.column
        };
      }
      function syntaxError(message, node) {
        return new TranspilerSyntaxError(message, tokenFor(node));
      }
      function validateBindings(ast) {
        const scope = new Scope();
        for (const name2 of [
          "__argc__",
          "__file__",
          "__global__",
          "__system__"
        ]) {
          scope.declare(name2, false, null);
        }
        validateStatements(ast.body || [], scope);
        return ast;
      }
      function validateStatements(statements, scope) {
        for (const statement of statements || []) {
          validateStatement(statement, scope);
        }
      }
      function validateStatement(node, scope) {
        if (!node) {
          return;
        }
        switch (node.type) {
          case "BlockStatement":
            validateStatements(node.body, new Scope(scope));
            return;
          case "VariableDeclaration":
            validateExpression(node.init, scope);
            scope.declare(node.id && node.id.name, node.kind !== "const", node);
            return;
          case "VariableUnpackDeclaration":
            validateVariableUnpackDeclaration(node, scope);
            return;
          case "FunctionDeclaration":
            scope.declareFunction(node);
            if (!node.isPredeclared) {
              validateFunctionBody(node, scope);
            }
            return;
          case "ClassDeclaration":
            scope.declare(node.id && node.id.name, false, node);
            validateClassBody(node, scope);
            return;
          case "TraitDeclaration":
            scope.declare(node.id && node.id.name, false, node);
            validateTraitBody(node, scope);
            return;
          case "ForInStatement":
            validateExpression(node.iterable, scope);
            validateForBody(node, scope);
            return;
          case "ExpressionStatement":
            validateExpression(node.expression, scope);
            return;
          default:
            validateChildNodes(node, scope);
        }
      }
      function validateVariableUnpackDeclaration(node, scope) {
        validateExpression(node.init, scope);
        const names = /* @__PURE__ */ new Set();
        for (const entry of bindingEntriesForPattern(node.pattern)) {
          if (names.has(entry.name)) {
            throw syntaxError(
              `Duplicate unpacked binding '${entry.name}' in declaration`,
              entry
            );
          }
          names.add(entry.name);
        }
        for (const entry of bindingEntriesForPattern(node.pattern)) {
          validateExpression(entry.key, scope);
          validateExpression(entry.defaultValue, scope);
        }
        for (const entry of bindingEntriesForPattern(node.pattern)) {
          scope.declare(entry.name, node.kind !== "const", entry);
        }
      }
      function bindingEntriesForPattern(pattern) {
        return pattern && Array.isArray(pattern.entries) ? pattern.entries : [];
      }
      function validateForBody(node, scope) {
        const loopScope = new Scope(scope);
        loopScope.declare(
          node.left && node.left.name,
          node.kind !== "const",
          node.left || node
        );
        validateStatement(node.body, loopScope);
        validateStatement(node.elseBlock, new Scope(scope));
      }
      function validateFunctionBody(node, parentScope) {
        const scope = new Scope(parentScope);
        for (const param of node.params || []) {
          if (param.type === "Parameter") {
            scope.declare(param.name, true, param);
          } else if (param.type === "SpecialParameter") {
            scope.declare(param.leadName, true, param);
            scope.declare(param.name, true, param);
          }
        }
        validateStatements(node.body && node.body.body, scope);
      }
      function validateClassBody(node, scope) {
        const classScope = new Scope(scope);
        const methodNames = /* @__PURE__ */ new Map();
        validateExpression(node.base, scope);
        for (const trait of node.traits || []) {
          validateExpression(trait, scope);
        }
        for (const entry of node.body || []) {
          if (entry.type === "FieldDeclaration") {
            validateExpression(entry.defaultValue, classScope);
          } else if (entry.type === "MethodDeclaration") {
            recordMethodDeclaration(methodNames, entry);
            if (!entry.isPredeclared) {
              validateFunctionBody(entry, classScope);
            }
          } else {
            validateStatement(entry, classScope);
          }
        }
      }
      function validateTraitBody(node, scope) {
        const methodNames = /* @__PURE__ */ new Map();
        for (const entry of node.body || []) {
          recordMethodDeclaration(methodNames, entry);
          if (!entry.isPredeclared) {
            validateFunctionBody(entry, scope);
          }
        }
      }
      function recordMethodDeclaration(methodNames, node) {
        const name2 = node.id && node.id.name;
        const existing = methodNames.get(name2);
        if (existing && existing.bodyless && !node.isPredeclared) {
          existing.bodyless = false;
          return;
        }
        if (existing) {
          throw syntaxError(`Redeclaration of '${name2}' in the same scope`, node);
        }
        methodNames.set(name2, { bodyless: node.isPredeclared === true });
      }
      function validateExpression(node, scope) {
        if (!node) {
          return;
        }
        switch (node.type) {
          case "AssignmentExpression":
            validateExpression(node.right, scope);
            requireValidAssignmentTarget(node.left);
            if (node.left && node.left.type === "Identifier") {
              requireMutable(node.left, scope);
            } else {
              validateExpression(node.left, scope);
            }
            return;
          case "UpdateExpression":
            if (node.argument && node.argument.type === "Identifier") {
              requireMutable(node.argument, scope);
            } else {
              validateExpression(node.argument, scope);
            }
            return;
          case "FunctionExpression":
            validateFunctionBody(node, scope);
            return;
          case "LetExpression":
            validateExpression(node.init, scope);
            scope.declare(node.id && node.id.name, node.kind !== "const", node);
            return;
          default:
            validateChildNodes(node, scope);
        }
      }
      function requireValidAssignmentTarget(node) {
        const target = unwrapGroupedExpression(node);
        if (!target) {
          throw syntaxError("Invalid assignment target", node);
        }
        if (target.type === "Identifier" || target.type === "MemberExpression" || target.type === "SliceExpression") {
          return;
        }
        if (target.type === "BinaryExpression" && ["@", "@@", "@?"].includes(target.operator)) {
          return;
        }
        throw syntaxError("Invalid assignment target", node);
      }
      function unwrapGroupedExpression(node) {
        let current = node;
        while (current && current.type === "GroupedExpression") {
          current = current.expression;
        }
        return current;
      }
      function requireMutable(node, scope) {
        const binding = scope.lookup(node.name);
        if (binding && !binding.mutable) {
          throw syntaxError(`Cannot assign to const '${node.name}' (compile-time)`, node);
        }
      }
      function validateChildNodes(node, scope) {
        if (!node || typeof node !== "object") {
          return;
        }
        for (const value of Object.values(node)) {
          if (!value) {
            continue;
          }
          if (Array.isArray(value)) {
            for (const item of value) {
              validateChildNode(item, scope);
            }
          } else {
            validateChildNode(value, scope);
          }
        }
      }
      function validateChildNode(node, scope) {
        if (!node || typeof node !== "object" || typeof node.type !== "string") {
          return;
        }
        if (node.type.endsWith("Statement") || node.type.endsWith("Declaration")) {
          validateStatement(node, scope);
        } else {
          validateExpression(node, scope);
        }
      }
      module2.exports = {
        validateBindings
      };
    }
  });

  // lib/transpiler-new/index.js
  var require_transpiler_new = __commonJS({
    "lib/transpiler-new/index.js"(exports2, module2) {
      "use strict";
      var { stripPod } = require_transpiler_utils();
      var { tokenize } = require_lexer();
      var { parse } = require_parser();
      var { emitProgram } = require_codegen();
      var { validateBindings } = require_validate_bindings();
      function transpileWithoutFallback(source, options = {}) {
        const preprocessed = stripPod(String(source ?? ""));
        const tokens = tokenize(preprocessed);
        const ast = parse(tokens);
        validateBindings(ast);
        return emitProgram(ast, { ...options, marshalSource: preprocessed });
      }
      function transpile(source, options = {}) {
        return transpileWithoutFallback(source, options);
      }
      module2.exports = {
        tokenize,
        parse,
        transpileWithoutFallback,
        transpile
      };
    }
  });

  // lib/transpiler.js
  var require_transpiler = __commonJS({
    "lib/transpiler.js"(exports2, module2) {
      "use strict";
      var { stripPod } = require_transpiler_utils();
      var { transpile: transpileNew } = require_transpiler_new();
      var DEFAULT_TRANSPILER = "new-only";
      var VALID_TRANSPILERS = /* @__PURE__ */ new Set([DEFAULT_TRANSPILER]);
      function normalizeTranspilerName(value) {
        if (value == null || value === "") {
          return DEFAULT_TRANSPILER;
        }
        const name2 = String(value).trim().toLowerCase();
        if (!VALID_TRANSPILERS.has(name2)) {
          throw new Error(
            `Unknown transpiler: ${value}. Expected: ${DEFAULT_TRANSPILER}`
          );
        }
        return name2;
      }
      function transpile(source, options = {}) {
        normalizeTranspilerName(options.transpiler);
        return transpileNew(source, options);
      }
      module2.exports = {
        DEFAULT_TRANSPILER,
        VALID_TRANSPILERS,
        normalizeTranspilerName,
        transpile,
        stripPod
      };
    }
  });

  // lib/host/capabilities.js
  var require_capabilities = __commonJS({
    "lib/host/capabilities.js"(exports2, module2) {
      "use strict";
      var MODULE_CAPABILITIES = {
        "std/io": ["fs"],
        "std/io/socks": ["fs", "net"],
        "std/proc": ["proc"],
        "std/db": ["db"],
        "std/clib": ["clib"],
        "std/gui/objects": ["gui"],
        "std/net/dns": ["net"],
        "std/net/http": ["http"],
        "std/worker": ["worker"],
        "perl": ["perl"],
        "javascript": ["js"]
      };
      var BROWSER_SAFE_MODULES = /* @__PURE__ */ new Set([
        "std/string",
        "std/time",
        "std/data/json",
        "std/data/xml",
        "std/net/http",
        "std/net/smtp",
        "std/secure",
        "std/math",
        "std/eval",
        "std/colour",
        "std/gui",
        "std/gui/dialogue",
        "std/gui/objects",
        "std/tui"
      ]);
      function capabilitiesForModule(moduleName) {
        for (const [prefix, capabilities2] of Object.entries(MODULE_CAPABILITIES)) {
          if (moduleName === prefix || moduleName.startsWith(`${prefix}/`)) {
            return capabilities2.slice();
          }
        }
        return [];
      }
      module2.exports = {
        MODULE_CAPABILITIES,
        BROWSER_SAFE_MODULES,
        capabilitiesForModule
      };
    }
  });

  // lib/execution-metadata.js
  var require_execution_metadata = __commonJS({
    "lib/execution-metadata.js"(exports2, module2) {
      "use strict";
      var compiledSources = /* @__PURE__ */ new Map();
      function setCompiledSource(filename, source) {
        if (typeof filename === "string" && typeof source === "string") {
          compiledSources.set(filename, source);
        }
      }
      function getCompiledSource(filename) {
        return compiledSources.get(filename) || null;
      }
      module2.exports = {
        getCompiledSource,
        setCompiledSource
      };
    }
  });

  // modules/std/task.js
  var require_task = __commonJS({
    "modules/std/task.js"(exports2, module2) {
      "use strict";
      var AsyncLocalStorage = null;
      try {
        AsyncLocalStorage = __require("node:async_hooks").AsyncLocalStorage;
      } catch (_err) {
      }
      var Exception = class extends Error {
        constructor(message = "") {
          super(String(message ?? ""));
          this.name = "Exception";
        }
        to_String() {
          const name2 = this.name || this.constructor.name || "Exception";
          const message = String(this.message ?? "");
          if (message === name2 || message.startsWith(`${name2}:`)) {
            return message;
          }
          return message === "" ? name2 : `${name2}: ${message}`;
        }
      };
      var CancelledException = class extends Exception {
        constructor(message = "Task cancelled") {
          super(message);
          this.name = "CancelledException";
        }
      };
      var TimeoutException = class extends Exception {
        constructor(message = "timeout") {
          super(message);
          this.name = "TimeoutException";
        }
      };
      var ChannelClosedException = class extends Exception {
        constructor(message = "send on closed channel") {
          super(message);
          this.name = "ChannelClosedException";
        }
      };
      var taskStorage = AsyncLocalStorage ? new AsyncLocalStorage() : null;
      var fallbackCurrentTask = null;
      var debugLevel = 0;
      var nextTaskId = 1;
      var activeTasks = /* @__PURE__ */ new Map();
      var traceEvents = [];
      var callsiteStack = [];
      function globalTimerRoot() {
        if (typeof globalThis !== "undefined") {
          return globalThis;
        }
        if (typeof global !== "undefined") {
          return global;
        }
        return {};
      }
      function safeSetTimeout(callback, delay) {
        const root = globalTimerRoot();
        return root.setTimeout.call(root, callback, delay);
      }
      function safeClearTimeout(timer) {
        const root = globalTimerRoot();
        return root.clearTimeout.call(root, timer);
      }
      function safeQueueMicrotask(callback) {
        const root = globalTimerRoot();
        if (typeof root.queueMicrotask === "function") {
          return root.queueMicrotask.call(root, callback);
        }
        return safeSetTimeout(callback, 0);
      }
      function currentTask() {
        return taskStorage ? taskStorage.getStore() : fallbackCurrentTask;
      }
      function runWithTask(task2, fn2) {
        if (taskStorage) {
          return taskStorage.run(task2, fn2);
        }
        const previous = fallbackCurrentTask;
        fallbackCurrentTask = task2;
        try {
          return fn2();
        } finally {
          fallbackCurrentTask = previous;
        }
      }
      function normalizeException(value, ExceptionClass = Exception) {
        if (value instanceof Error) {
          return value;
        }
        return new ExceptionClass(value == null ? "" : String(value));
      }
      function currentCallsite() {
        return callsiteStack.length > 0 ? callsiteStack[callsiteStack.length - 1] : null;
      }
      function withCallsite(metadata, fn2) {
        callsiteStack.push(metadata || null);
        try {
          return fn2();
        } finally {
          callsiteStack.pop();
        }
      }
      function traceTask(event, task2 = null, extra = null) {
        if (debugLevel <= 0) {
          return null;
        }
        const record = {
          event,
          task_id: task2 ? task2._id : null,
          parent_task_id: task2 ? task2._parentId : null,
          name: task2 ? task2._name : null,
          status: task2 ? task2._status : null,
          file: task2 ? task2._file : null,
          line: task2 ? task2._line : null
        };
        if (extra && typeof extra === "object") {
          Object.assign(record, extra);
        }
        traceEvents.push(record);
        return record;
      }
      function cleanupTask(task2) {
        if (!task2 || !task2.done()) {
          return;
        }
        activeTasks.delete(task2._id);
        traceTask("cleanup", task2);
      }
      var Task = class _Task {
        constructor(executor = null, options = {}) {
          const parent = currentTask();
          const callsite = currentCallsite();
          this._id = nextTaskId++;
          this._parentId = options.parentTaskId != null ? options.parentTaskId : parent ? parent._id : null;
          this._name = options.name || "<task>";
          this._file = options.file || (callsite ? callsite.file : null) || null;
          this._line = options.line || (callsite ? callsite.line : null) || null;
          this._status = options.status || "pending";
          this._value = void 0;
          this._reason = null;
          this._children = /* @__PURE__ */ new Set();
          this._cancelHook = typeof options.cancel === "function" ? options.cancel : null;
          this._pollHook = typeof options.poll === "function" ? options.poll : null;
          activeTasks.set(this._id, this);
          traceTask("schedule", this);
          this._promise = new Promise((resolve, reject) => {
            this._resolve = (value) => {
              if (this.done()) {
                return;
              }
              this._status = "fulfilled";
              this._value = value;
              traceTask("fulfill", this);
              resolve(value);
              cleanupTask(this);
            };
            this._reject = (err, forcedStatus = null) => {
              if (this.done()) {
                return;
              }
              this._status = forcedStatus || (err instanceof CancelledException ? "cancelled" : "rejected");
              this._reason = err;
              traceTask(this._status === "cancelled" ? "cancel" : "reject", this);
              reject(err);
              cleanupTask(this);
            };
          });
          this._promise.catch(() => {
          });
          if (executor) {
            safeQueueMicrotask(() => {
              if (this.done()) {
                return;
              }
              this._status = options.status || "running";
              traceTask("start", this);
              runWithTask(this, async () => {
                try {
                  this._resolve(await executor());
                } catch (err) {
                  this._reject(err);
                }
              });
            });
          }
        }
        static resolved(value = null) {
          const task2 = new _Task();
          task2._resolve(value);
          return task2;
        }
        static failed(value) {
          const task2 = new _Task();
          task2._reject(normalizeException(value));
          return task2;
        }
        static from(value) {
          if (value instanceof _Task) {
            return value;
          }
          if (value && typeof value.then === "function") {
            const task2 = new _Task();
            Promise.resolve(value).then(
              (result) => task2._resolve(result),
              (err) => task2._reject(err)
            );
            return task2;
          }
          return _Task.resolved(value);
        }
        then(resolve, reject) {
          return this._promise.then(resolve, reject);
        }
        catch(reject) {
          return this._promise.catch(reject);
        }
        finally(callback) {
          return this._promise.finally(callback);
        }
        status() {
          return this._status;
        }
        id() {
          return this._id;
        }
        parent_id() {
          return this._parentId;
        }
        name() {
          return this._name;
        }
        is_done() {
          return this.done();
        }
        done() {
          return ["fulfilled", "rejected", "cancelled"].includes(this._status) ? 1 : 0;
        }
        poll() {
          if (!this.done() && this._pollHook) {
            try {
              this._pollHook();
            } catch (err) {
              this._reject(err);
            }
          }
          return this.done();
        }
        to_String() {
          return `[Task ${this._status}]`;
        }
        cancel(reason = null) {
          if (this.done()) {
            return this;
          }
          const err = normalizeException(
            reason == null ? "Task cancelled" : reason,
            CancelledException
          );
          this._reason = err;
          for (const child of this._children) {
            if (child && typeof child.cancel === "function") {
              child.cancel(err);
            }
          }
          if (this._cancelHook) {
            try {
              this._cancelHook(err);
            } catch (_err) {
            }
          }
          this._reject(err, "cancelled");
          return this;
        }
        _track(child) {
          if (child instanceof _Task) {
            this._children.add(child);
          }
        }
        _untrack(child) {
          if (child instanceof _Task) {
            this._children.delete(child);
          }
        }
      };
      Object.defineProperty(Task.prototype, "__zuzu_type_name", {
        value: "Task",
        enumerable: false,
        configurable: true,
        writable: true
      });
      async function awaitValueWithParent(value, parent) {
        if (parent && parent.status() === "cancelled") {
          throw parent._reason || new CancelledException();
        }
        const task2 = Task.from(value);
        if (parent) {
          parent._track(task2);
        }
        try {
          return await task2;
        } finally {
          if (parent) {
            parent._untrack(task2);
            if (parent.status() === "cancelled") {
              throw parent._reason || new CancelledException();
            }
          }
        }
      }
      async function awaitValue(value) {
        return awaitValueWithParent(value, currentTask());
      }
      async function awaitBlock(value) {
        const parent = currentTask();
        const boxedValue = value && typeof value.then === "function" ? await value : value;
        const resolvedValue = boxedValue && typeof boxedValue === "object" && Object.prototype.hasOwnProperty.call(boxedValue, "__zuzu_await_block_value") ? boxedValue.__zuzu_await_block_value : boxedValue;
        if (!(resolvedValue instanceof Task)) {
          throw new Exception("await block must return a Task");
        }
        return awaitValueWithParent(resolvedValue, parent);
      }
      function awaitValueSync(value) {
        const task2 = Task.from(value);
        if (task2.status() === "fulfilled") {
          return task2._value;
        }
        if (task2.status() === "rejected" || task2.status() === "cancelled") {
          throw task2._reason || new Exception("Task failed");
        }
        throw new Exception("cannot synchronously await pending task");
      }
      function awaitBlockSync(value) {
        const resolvedValue = value && typeof value === "object" && Object.prototype.hasOwnProperty.call(value, "__zuzu_await_block_value") ? value.__zuzu_await_block_value : value;
        if (!(resolvedValue instanceof Task)) {
          throw new Exception("await block must return a Task");
        }
        return awaitValueSync(resolvedValue);
      }
      function task(fn2, _metadata = {}) {
        const callsite = currentCallsite();
        return new Task(async () => fn2(), {
          name: _metadata.name || "<async>",
          file: (callsite ? callsite.file : null) || _metadata.file || null,
          line: (callsite ? callsite.line : null) || _metadata.line || null
        });
      }
      function taskSync(fn2, _metadata = {}) {
        const callsite = currentCallsite();
        const task2 = new Task(null, {
          name: _metadata.name || "<async>",
          file: (callsite ? callsite.file : null) || _metadata.file || null,
          line: (callsite ? callsite.line : null) || _metadata.line || null
        });
        task2._status = "running";
        traceTask("start", task2);
        try {
          const value = runWithTask(task2, () => fn2());
          if (value instanceof Task) {
            if (value.status() === "fulfilled") {
              task2._resolve(value._value);
            } else if (value.status() === "rejected" || value.status() === "cancelled") {
              task2._reject(value._reason || new Exception("Task failed"));
            } else {
              task2._reject(new Exception("cannot synchronously await pending task"));
            }
          } else if (value && typeof value.then === "function") {
            Task.from(value).then(
              (result) => task2._resolve(result),
              (err) => task2._reject(err)
            );
          } else {
            task2._resolve(value);
          }
        } catch (err) {
          task2._reject(err);
        }
        return task2;
      }
      function spawn(fn2, _metadata = {}) {
        return new Task(async () => fn2(), {
          status: "running",
          name: _metadata.name || "<spawn>",
          file: _metadata.file || (currentCallsite() ? currentCallsite().file : null) || null,
          line: _metadata.line || (currentCallsite() ? currentCallsite().line : null) || null
        });
      }
      function resolved(value = null) {
        return Task.resolved(value);
      }
      function failed(value) {
        return Task.failed(value == null ? "Task failed" : value);
      }
      function sleep(seconds = 0) {
        let timer = null;
        const readyAt = Date.now() + Math.max(0, Number(seconds) || 0) * 1e3;
        const task2 = new Task(null, {
          status: "sleeping",
          name: "sleep",
          poll() {
            if (Date.now() >= readyAt) {
              if (timer != null) {
                safeClearTimeout(timer);
                timer = null;
              }
              task2._resolve(null);
            }
          },
          cancel() {
            if (timer != null) {
              safeClearTimeout(timer);
              timer = null;
            }
          }
        });
        timer = safeSetTimeout(() => {
          timer = null;
          task2._resolve(null);
        }, Math.max(0, Number(seconds) || 0) * 1e3);
        return task2;
      }
      function yieldTask() {
        let timer = null;
        const task2 = new Task(null, {
          status: "waiting",
          name: "yield",
          cancel() {
            if (timer != null) {
              safeClearTimeout(timer);
              timer = null;
            }
          }
        });
        timer = safeSetTimeout(() => {
          timer = null;
          task2._resolve(null);
        }, 0);
        return task2;
      }
      function all(values = []) {
        const tasks = taskItems(values, "all");
        return new Task(
          () => new Promise((resolve, reject) => {
            if (tasks.length === 0) {
              resolve([]);
              return;
            }
            const results = new Array(tasks.length);
            let remaining = tasks.length;
            let settled = false;
            tasks.forEach((task2, index) => {
              task2.then(
                (value) => {
                  if (settled) {
                    return;
                  }
                  results[index] = value;
                  remaining--;
                  if (remaining === 0) {
                    settled = true;
                    resolve(results);
                  }
                },
                (err) => {
                  if (settled) {
                    return;
                  }
                  settled = true;
                  for (const child of tasks) {
                    if (child !== task2) {
                      child.cancel();
                    }
                  }
                  reject(err);
                }
              );
            });
          }),
          {
            status: "waiting",
            name: "all",
            cancel(reason) {
              for (const task2 of tasks) {
                task2.cancel(reason);
              }
            }
          }
        );
      }
      function race(values = []) {
        const tasks = taskItems(values, "race");
        if (tasks.length === 0) {
          return Task.failed(new Exception("race expects at least one task"));
        }
        return new Task(
          () => new Promise((resolve, reject) => {
            let settled = false;
            for (const task2 of tasks) {
              task2.then(
                (value) => {
                  if (settled) {
                    return;
                  }
                  settled = true;
                  for (const loser of tasks) {
                    if (loser !== task2) {
                      loser.cancel(new CancelledException("race loser cancelled"));
                    }
                  }
                  resolve(value);
                },
                (err) => {
                  if (settled) {
                    return;
                  }
                  settled = true;
                  for (const loser of tasks) {
                    if (loser !== task2) {
                      loser.cancel(new CancelledException("race loser cancelled"));
                    }
                  }
                  reject(err);
                }
              );
            }
          }),
          {
            status: "waiting",
            name: "race",
            cancel(reason) {
              for (const task2 of tasks) {
                task2.cancel(reason);
              }
            }
          }
        );
      }
      function timeout(seconds, value) {
        if (!(value instanceof Task)) {
          throw new Exception("timeout expects a Task");
        }
        const waited = value;
        const timeoutError = () => new TimeoutException(`timeout after ${Number(seconds) || 0}s`);
        let settled = false;
        let timer = null;
        return new Task(
          () => new Promise((resolve, reject) => {
            timer = safeSetTimeout(() => {
              if (settled) {
                return;
              }
              settled = true;
              const err = timeoutError();
              waited.cancel(err);
              reject(err);
            }, Math.max(0, Number(seconds) || 0) * 1e3);
            waited.then(
              (result) => {
                if (settled) {
                  return;
                }
                settled = true;
                if (timer != null) {
                  safeClearTimeout(timer);
                  timer = null;
                }
                resolve(result);
              },
              (err) => {
                if (settled) {
                  return;
                }
                settled = true;
                if (timer != null) {
                  safeClearTimeout(timer);
                  timer = null;
                }
                reject(err);
              }
            );
          }),
          {
            status: "waiting",
            name: "timeout",
            cancel(reason) {
              settled = true;
              if (timer != null) {
                safeClearTimeout(timer);
                timer = null;
              }
              waited.cancel(reason);
            }
          }
        );
      }
      var Channel = class {
        constructor() {
          this._closed = false;
          this._queue = [];
          this._receivers = [];
        }
        send(value = null) {
          if (this._closed) {
            return Task.failed(new ChannelClosedException());
          }
          const receiver = this._receivers.shift();
          if (receiver) {
            receiver._resolve(value);
          } else {
            this._queue.push(value);
          }
          return Task.resolved(value);
        }
        recv() {
          if (this._queue.length > 0) {
            return Task.resolved(this._queue.shift());
          }
          if (this._closed) {
            return Task.resolved(null);
          }
          const task2 = new Task(null, {
            status: "waiting",
            name: "channel.recv",
            cancel: () => {
              this._receivers = this._receivers.filter((item) => item !== task2);
            }
          });
          this._receivers.push(task2);
          return task2;
        }
        close() {
          this._closed = true;
          while (this._receivers.length > 0) {
            this._receivers.shift()._resolve(null);
          }
          return null;
        }
      };
      var CancellationToken = class {
        constructor() {
          this._cancelled = false;
          this._reason = null;
          this._tasks = /* @__PURE__ */ new Set();
        }
        cancelled() {
          return this._cancelled ? 1 : 0;
        }
        reason() {
          return this._reason;
        }
        throw_if_cancelled() {
          if (this._cancelled) {
            throw this._reason || new CancelledException();
          }
          return null;
        }
        watch(task2) {
          if (!(task2 instanceof Task)) {
            throw new Exception("CancellationToken.watch expects a Task");
          }
          if (this._cancelled) {
            task2.cancel(this._reason);
          } else {
            this._tasks.add(task2);
          }
          return task2;
        }
      };
      var CancellationSource = class {
        constructor() {
          this._token = new CancellationToken();
        }
        token() {
          return this._token;
        }
        cancel(reason = null) {
          if (this._token._cancelled) {
            return this;
          }
          this._token._cancelled = true;
          this._token._reason = normalizeException(
            reason == null ? "Task cancelled" : reason,
            CancelledException
          );
          for (const task2 of this._token._tasks) {
            task2.cancel(this._token._reason);
          }
          this._token._tasks.clear();
          return this;
        }
        cancelled() {
          return this._token.cancelled();
        }
        reason() {
          return this._token.reason();
        }
      };
      function setDebugLevel(level = 0) {
        debugLevel = Number(level) || 0;
      }
      function clearTrace() {
        traceEvents.length = 0;
        return null;
      }
      function taskTrace() {
        return traceEvents.map((record) => ({ ...record }));
      }
      function activeCount() {
        for (const task2 of [...activeTasks.values()]) {
          cleanupTask(task2);
        }
        return activeTasks.size;
      }
      function traceBlockingOperation(operation, metadata = {}) {
        const task2 = currentTask();
        if (!task2 || debugLevel <= 0) {
          return null;
        }
        return traceTask("blocked_operation", task2, {
          operation: String(operation ?? ""),
          ...metadata
        });
      }
      function shutdown(reason = null) {
        for (const task2 of [...activeTasks.values()]) {
          if (!task2.done()) {
            task2.cancel(reason == null ? "Task cancelled" : reason);
          }
        }
        traceTask("shutdown", null);
        return null;
      }
      function resetForRun(level = 0) {
        const previousDebugLevel = debugLevel;
        debugLevel = 0;
        shutdown("Task cancelled");
        debugLevel = Number(level) || 0;
        traceEvents.length = 0;
        nextTaskId = 1;
        fallbackCurrentTask = null;
        callsiteStack.length = 0;
        return previousDebugLevel;
      }
      function withoutAsyncLocalStorageForTesting(fn2) {
        const previous = taskStorage;
        taskStorage = null;
        try {
          const result = fn2();
          if (result && typeof result.then === "function") {
            return Promise.resolve(result).finally(() => {
              taskStorage = previous;
              fallbackCurrentTask = null;
            });
          }
          taskStorage = previous;
          fallbackCurrentTask = null;
          return result;
        } catch (err) {
          taskStorage = previous;
          fallbackCurrentTask = null;
          throw err;
        }
      }
      function taskItems(values, label) {
        if (!Array.isArray(values)) {
          throw new Exception("TypeException: task combinator expects Array");
        }
        const out = [];
        for (const value of values) {
          if (!(value instanceof Task)) {
            throw new Exception(`${label} expects only Task values`);
          }
          out.push(value);
        }
        return out;
      }
      module2.exports = {
        Task,
        Exception,
        CancelledException,
        TimeoutException,
        ChannelClosedException,
        Channel,
        CancellationToken,
        CancellationSource,
        awaitValue,
        awaitBlock,
        awaitValueSync,
        awaitBlockSync,
        withCallsite,
        runWithTask,
        currentTask,
        setDebugLevel,
        clearTrace,
        taskTrace,
        activeCount,
        traceBlockingOperation,
        shutdown,
        resetForRun,
        withoutAsyncLocalStorageForTesting,
        task,
        taskSync,
        spawn,
        resolved,
        failed,
        sleep,
        yield: yieldTask,
        all,
        race,
        timeout
      };
    }
  });

  // modules/std/io.js
  var require_io = __commonJS({
    "modules/std/io.js"(exports2, module2) {
      "use strict";
      var fs = __require("node:fs");
      var os = __require("node:os");
      var path = __require("node:path");
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var { Task, traceBlockingOperation } = require_task();
      var runtimePolicy2 = {};
      function typeName2(value) {
        if (value == null) {
          return "Null";
        }
        if (typeof value === "string") {
          return "String";
        }
        if (value.bytes instanceof Uint8Array) {
          return "BinaryString";
        }
        return value.constructor && value.constructor.name ? value.constructor.name : typeof value;
      }
      function bool(value) {
        return value ? 1 : 0;
      }
      function formatSizeHuman(size) {
        const units = ["B", "KB", "MB", "GB", "TB"];
        let value = Number(size);
        let unit = 0;
        while (value >= 1024 && unit < units.length - 1) {
          value /= 1024;
          unit++;
        }
        if (unit === 0) {
          return `${value} ${units[unit]}`;
        }
        return `${value.toFixed(1)} ${units[unit]}`;
      }
      function binaryLinesFromBuffer(buffer) {
        const out = [];
        let start = 0;
        for (let i = 0; i < buffer.length; i++) {
          if (buffer[i] === 10) {
            out.push(new BinaryString2(Uint8Array.from(buffer.slice(start, i + 1))));
            start = i + 1;
          }
        }
        if (start < buffer.length) {
          out.push(new BinaryString2(Uint8Array.from(buffer.slice(start))));
        }
        return out;
      }
      function textLinesFromString(text) {
        const out = [];
        let start = 0;
        for (let i = 0; i < text.length; i++) {
          if (text[i] === "\n") {
            out.push(text.slice(start, i + 1));
            start = i + 1;
          }
        }
        if (start < text.length) {
          out.push(text.slice(start));
        }
        return out;
      }
      function renderValue(value) {
        if (value && value.bytes instanceof Uint8Array) {
          return value.to_String();
        }
        if (typeof runtimePolicy2.to_String === "function") {
          return runtimePolicy2.to_String(value);
        }
        return String(value ?? "");
      }
      function writeStdout(text) {
        if (typeof runtimePolicy2.stdout_write === "function") {
          runtimePolicy2.stdout_write(text);
          return;
        }
        process.stdout.write(text);
      }
      function writeStderr(text) {
        if (typeof runtimePolicy2.stderr_write === "function") {
          runtimePolicy2.stderr_write(text);
          return;
        }
        process.stderr.write(text);
      }
      function streamPayload(values, newline) {
        const text = values.map(renderValue).join("");
        return newline ? `${text}
` : text;
      }
      var StandardOutputStream = class {
        print(...values) {
          writeStdout(streamPayload(values, false));
          return null;
        }
        say(...values) {
          writeStdout(streamPayload(values, true));
          return null;
        }
      };
      var StandardErrorStream = class {
        print(...values) {
          writeStderr(streamPayload(values, false));
          return null;
        }
        say(...values) {
          writeStderr(streamPayload(values, true));
          return null;
        }
      };
      var StandardInputStream = class {
        constructor() {
          this._buffer = null;
          this._linePos = 0;
          this._lineMode = "text";
        }
        _bufferBytes() {
          if (this._buffer == null) {
            this._buffer = fs.readFileSync(0);
          }
          return this._buffer;
        }
        _lines(raw) {
          const buffer = this._bufferBytes();
          return raw ? binaryLinesFromBuffer(buffer) : textLinesFromString(buffer.toString("utf8"));
        }
        next_line(raw = false) {
          const mode = raw ? "raw" : "text";
          if (this._lineMode !== mode) {
            this._lineMode = mode;
            this._linePos = 0;
          }
          const lines = this._lines(raw);
          if (this._linePos >= lines.length) {
            return null;
          }
          return lines[this._linePos++];
        }
        each_line(fn2, raw = false) {
          for (const line of this._lines(raw).slice(this._linePos)) {
            fn2(line);
            this._linePos++;
          }
          return this;
        }
      };
      function statToDict(stats) {
        if (!stats) {
          return null;
        }
        const out = {
          dev: stats.dev,
          ino: stats.ino,
          mode: stats.mode,
          nlink: stats.nlink,
          uid: stats.uid,
          gid: stats.gid,
          rdev: stats.rdev,
          size: stats.size,
          atime: Math.floor(stats.atimeMs / 1e3),
          mtime: Math.floor(stats.mtimeMs / 1e3),
          ctime: Math.floor(stats.ctimeMs / 1e3),
          blksize: stats.blksize ?? 0,
          blocks: stats.blocks ?? 0
        };
        Object.defineProperty(out, "has", {
          value(key) {
            return Object.prototype.hasOwnProperty.call(out, String(key)) ? 1 : 0;
          },
          enumerable: false
        });
        Object.defineProperty(out, "get", {
          value(key, fallback = null) {
            return Object.prototype.hasOwnProperty.call(out, String(key)) ? out[String(key)] : fallback;
          },
          enumerable: false
        });
        return out;
      }
      var Path = class _Path {
        constructor(rawPath) {
          const pathValue = rawPath && typeof rawPath === "object" && !Array.isArray(rawPath) && (Object.prototype.hasOwnProperty.call(rawPath, "path") || typeof rawPath.get === "function" && typeof rawPath.has === "function" && rawPath.has("path")) ? typeof rawPath.get === "function" ? rawPath.get("path") : rawPath.path : rawPath;
          this.value = String(pathValue ?? "");
          this._linePos = 0;
          this._lineMode = "text";
        }
        to_String() {
          return this.value;
        }
        parent() {
          const dir = path.dirname(this.value);
          return new _Path(dir === "" ? "." : dir);
        }
        sibling(name2) {
          return this.parent().child(name2);
        }
        absolute() {
          return new _Path(path.resolve(this.value));
        }
        realpath() {
          try {
            return new _Path(fs.realpathSync(this.value));
          } catch (_err) {
            return null;
          }
        }
        is_absolute() {
          return path.isAbsolute(this.value) ? 1 : 0;
        }
        basename() {
          return path.basename(this.value);
        }
        exists() {
          return bool(fs.existsSync(this.value));
        }
        is_file() {
          try {
            return bool(fs.statSync(this.value).isFile());
          } catch (_err) {
            return 0;
          }
        }
        is_dir() {
          try {
            return bool(fs.statSync(this.value).isDirectory());
          } catch (_err) {
            return 0;
          }
        }
        size() {
          return fs.statSync(this.value).size;
        }
        size_human() {
          return formatSizeHuman(this.size());
        }
        stat() {
          return statToDict(fs.statSync(this.value));
        }
        lstat() {
          return statToDict(fs.lstatSync(this.value));
        }
        child(name2) {
          return new _Path(path.join(this.value, String(name2)));
        }
        children() {
          return fs.readdirSync(this.value).map((name2) => new _Path(path.join(this.value, name2)));
        }
        iterator() {
          const kids = this.children();
          let i = 0;
          return {
            next() {
              if (i >= kids.length) {
                return null;
              }
              return kids[i++];
            }
          };
        }
        chmod(mode) {
          fs.chmodSync(this.value, Number(mode));
          return Number(mode);
        }
        copy(target) {
          const dest = target instanceof _Path ? target : new _Path(target);
          fs.copyFileSync(this.value, dest.value);
          return dest;
        }
        move(target) {
          const dest = target instanceof _Path ? target : new _Path(target);
          fs.renameSync(this.value, dest.value);
          return dest;
        }
        remove() {
          try {
            fs.rmSync(this.value, { force: true });
            return 1;
          } catch (_err) {
            return 0;
          }
        }
        remove_tree() {
          try {
            fs.rmSync(this.value, { recursive: true, force: true });
            return 1;
          } catch (_err) {
            return 0;
          }
        }
        touchpath() {
          fs.mkdirSync(path.dirname(this.value), { recursive: true });
          if (!fs.existsSync(this.value)) {
            fs.writeFileSync(this.value, "");
          }
          return this;
        }
        mkdir() {
          fs.mkdirSync(this.value, { recursive: true });
          return 1;
        }
        mkdir_exclusive() {
          try {
            fs.mkdirSync(this.value);
            return 1;
          } catch (err) {
            if (err && err.code === "EEXIST") {
              return 0;
            }
            throw err;
          }
        }
        spew(value) {
          traceBlockingOperation("std/io Path.spew");
          if (!(value && value.bytes instanceof Uint8Array)) {
            throw new Error(`TypeException: Path.spew expects BinaryString, got ${typeName2(value)}`);
          }
          fs.writeFileSync(this.value, Buffer.from(value.bytes));
          return this;
        }
        spew_async(value) {
          return new Task(async () => {
            this.spew(value);
            return this;
          });
        }
        slurp() {
          traceBlockingOperation("std/io Path.slurp");
          return new BinaryString2(Uint8Array.from(fs.readFileSync(this.value)));
        }
        slurp_async() {
          return new Task(async () => new BinaryString2(Uint8Array.from(await fs.promises.readFile(this.value))));
        }
        spew_utf8(text) {
          traceBlockingOperation("std/io Path.spew_utf8");
          if (typeof text !== "string") {
            throw new Error(`TypeException: Path.spew_utf8 expects String, got ${typeName2(text)}`);
          }
          fs.writeFileSync(this.value, text, "utf8");
          return this;
        }
        spew_utf8_async(text) {
          return new Task(async () => {
            if (typeof text !== "string") {
              throw new Error(`TypeException: Path.spew_utf8 expects String, got ${typeName2(text)}`);
            }
            await fs.promises.writeFile(this.value, text, "utf8");
            return this;
          });
        }
        slurp_utf8() {
          traceBlockingOperation("std/io Path.slurp_utf8");
          return fs.readFileSync(this.value, "utf8");
        }
        slurp_utf8_async() {
          return new Task(async () => fs.promises.readFile(this.value, "utf8"));
        }
        append(value) {
          traceBlockingOperation("std/io Path.append");
          if (!(value && value.bytes instanceof Uint8Array)) {
            throw new Error(`TypeException: Path.append expects BinaryString, got ${typeName2(value)}`);
          }
          fs.appendFileSync(this.value, Buffer.from(value.bytes));
          return this;
        }
        append_async(value) {
          return new Task(async () => {
            if (!(value && value.bytes instanceof Uint8Array)) {
              throw new Error(`TypeException: Path.append expects BinaryString, got ${typeName2(value)}`);
            }
            await fs.promises.appendFile(this.value, Buffer.from(value.bytes));
            return this;
          });
        }
        append_utf8(text) {
          traceBlockingOperation("std/io Path.append_utf8");
          if (typeof text !== "string") {
            throw new Error(`TypeException: Path.append_utf8 expects String, got ${typeName2(text)}`);
          }
          fs.appendFileSync(this.value, text, "utf8");
          return this;
        }
        append_utf8_async(text) {
          return new Task(async () => {
            if (typeof text !== "string") {
              throw new Error(`TypeException: Path.append_utf8 expects String, got ${typeName2(text)}`);
            }
            await fs.promises.appendFile(this.value, text, "utf8");
            return this;
          });
        }
        lines_async() {
          return new Task(async () => binaryLinesFromBuffer(await fs.promises.readFile(this.value)));
        }
        lines_utf8_async() {
          return new Task(async () => textLinesFromString(await fs.promises.readFile(this.value, "utf8")));
        }
        each_line(fn2, raw = false) {
          traceBlockingOperation("std/io Path.each_line");
          const lines = raw ? binaryLinesFromBuffer(fs.readFileSync(this.value)) : textLinesFromString(this.slurp_utf8());
          for (const line of lines) {
            fn2(line);
          }
          return this;
        }
        next_line(raw = false) {
          traceBlockingOperation("std/io Path.next_line");
          const mode = raw ? "raw" : "text";
          if (this._lineMode !== mode) {
            this._lineMode = mode;
            this._linePos = 0;
          }
          const lines = raw ? binaryLinesFromBuffer(fs.readFileSync(this.value)) : textLinesFromString(this.slurp_utf8());
          if (this._linePos >= lines.length) {
            return null;
          }
          return lines[this._linePos++];
        }
        static cwd() {
          return new _Path(process.cwd());
        }
        static tempfile() {
          const dir = fs.mkdtempSync(path.join(os.tmpdir(), "zuzu-js-"));
          return new _Path(path.join(dir, "tmp.txt"));
        }
        static tempdir() {
          return new _Path(fs.mkdtempSync(path.join(os.tmpdir(), "zuzu-js-dir-")));
        }
        static join(parts) {
          return new _Path(path.join(...parts.map((p) => String(p))));
        }
        static split(source) {
          return path.normalize(String(source)).split(path.sep).filter(Boolean);
        }
        static normalize(source) {
          return new _Path(path.normalize(String(source)));
        }
        static glob(pattern) {
          const text = String(pattern ?? "");
          const star = text.indexOf("*");
          if (star < 0) {
            return fs.existsSync(text) ? [new _Path(text)] : [];
          }
          const dir = path.dirname(text);
          const ext = text.slice(star + 1);
          return fs.readdirSync(dir).filter((name2) => ext === "" || name2.endsWith(ext.replace(/^\./u, "."))).map((name2) => new _Path(path.join(dir, name2)));
        }
      };
      module2.exports = {
        Path,
        STDIN: new StandardInputStream(),
        STDOUT: new StandardOutputStream(),
        STDERR: new StandardErrorStream()
      };
      Object.defineProperty(module2.exports, "__zuzu_set_runtime_policy", {
        value(policy = {}) {
          runtimePolicy2 = policy || {};
        },
        enumerable: false
      });
    }
  });

  // lib/runtime.js
  var require_runtime = __commonJS({
    "lib/runtime.js"(exports2, module2) {
      "use strict";
      var { capabilitiesForModule } = require_capabilities();
      var { setCompiledSource } = require_execution_metadata();
      var {
        DEFAULT_TRANSPILER,
        normalizeTranspilerName,
        transpile,
        stripPod
      } = require_transpiler();
      var {
        collectTopLevelDeclarations,
        runSwitch,
        runMatch,
        contains,
        collectionUnion,
        collectionIntersection,
        collectionDifference,
        collectionSubsetOf,
        collectionSupersetOf,
        collectionEquivalentOf,
        makeArray,
        makeSet,
        makeBag,
        makePairList,
        makeTemporaryPairList,
        lengthOf,
        operatorString,
        operatorRegexp,
        ZuzuBinary,
        BinaryString: BinaryString2,
        Pair,
        PairList,
        withArrayMethods,
        ZuzuBag,
        isPairListLike,
        isWeakableValue,
        makeWeakValue,
        resolveWeakValue,
        retainValue,
        releaseValue,
        retainCollectionValue,
        releaseCollectionValue,
        releaseCollectionValues,
        addSetValue,
        assignStrongValue,
        assignWeakValue
      } = require_runtime_helpers();
      var taskRuntime2 = require_task();
      var textEncoder = new TextEncoder();
      var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
      var ZUZU_SKIP_BUILD = /* @__PURE__ */ Symbol.for("zuzu.skip_build");
      function defaultModuleSearchRoots(host, repoRoot, includePaths) {
        if (host.name === "browser") {
          return [
            host.join(repoRoot, "modules"),
            ...includePaths
          ];
        }
        const pathsModule = "./paths";
        return __require(pathsModule).defaultModuleSearchRoots({
          includePaths,
          packageRoot: repoRoot,
          initialCwd: host.cwd()
        });
      }
      function installHostCollectionMethods() {
        withArrayMethods();
        const define = (proto, name2, fn2) => {
          if (!Object.prototype.hasOwnProperty.call(proto, name2)) {
            const desc = /* @__PURE__ */ Object.create(null);
            desc.value = fn2;
            desc.enumerable = false;
            desc.configurable = true;
            desc.writable = true;
            Object.defineProperty(proto, name2, desc);
          }
        };
        define(Array.prototype, "push_weak", function _pushWeak(...values) {
          this.push(...values.map(makeWeakValue));
          return this;
        });
        define(Array.prototype, "unshift_weak", function _unshiftWeak(...values) {
          this.unshift(...values.map(makeWeakValue));
          return this;
        });
        define(Array.prototype, "set_weak", function _setWeak(index, value) {
          releaseCollectionValue(this, this[index]);
          this[index] = makeWeakValue(value);
          return this;
        });
        define(Set.prototype, "add_weak", function _addWeak(value) {
          this.add(makeWeakValue(value));
          return this;
        });
        define(Set.prototype, "copy", function _copy() {
          return makeSet(this);
        });
        define(ZuzuBag.prototype, "add_weak", function _addWeak(...values) {
          this.items.push(...values.map(makeWeakValue));
          return this;
        });
        define(ZuzuBag.prototype, "push_weak", function _pushWeak(...values) {
          return this.add_weak(...values);
        });
        define(PairList.prototype, "add_weak", function _addWeak(key, value) {
          this.list.push([String(key), makeWeakValue(value)]);
          return this;
        });
        define(PairList.prototype, "set_weak", function _setWeak(key, value) {
          return this.add_weak(key, value);
        });
        Object.defineProperty(ZuzuBag.prototype, "contains", {
          value: function _containsWeakAware(value) {
            const resolved = resolveWeakValue(value);
            return this.items.some((item) => resolveWeakValue(item) === resolved) ? 1 : 0;
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
        Object.defineProperty(Set.prototype, "contains", {
          value: function _containsWeakAware(value) {
            const resolved = resolveWeakValue(value);
            for (const item of this) {
              if (resolveWeakValue(item) === resolved) {
                return 1;
              }
            }
            return 0;
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
      }
      function createObjectFacade() {
        function ZuzuContextObject(value) {
          if (new.target) {
            return void 0;
          }
          return Object(value);
        }
        Object.setPrototypeOf(ZuzuContextObject, Object);
        Object.defineProperty(ZuzuContextObject, "prototype", {
          value: Object.prototype,
          enumerable: false,
          configurable: false,
          writable: false
        });
        return ZuzuContextObject;
      }
      function zuzuStringify(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return "";
        }
        if (typeof value === "boolean") {
          return value ? "1" : "0";
        }
        if (value instanceof RegExp) {
          return value.source;
        }
        if (value instanceof ZuzuBinary) {
          return value.to_String();
        }
        if (value && typeof value.to_String === "function") {
          return String(value.to_String());
        }
        if (value instanceof Error) {
          return value.message || value.name || String(value);
        }
        return String(value);
      }
      function zuzuOperatorString(value) {
        return operatorString(value);
      }
      function binaryFromLiteral(value) {
        const text = String(value ?? "");
        const bytes = [];
        for (let i = 0; i < text.length; i++) {
          bytes.push(text.charCodeAt(i) & 255);
        }
        return new BinaryString2(bytes);
      }
      function toBinaryValue(value) {
        value = resolveWeakValue(value);
        if (value instanceof ZuzuBinary) {
          return new BinaryString2(value);
        }
        if (typeof value === "string") {
          return new BinaryString2(textEncoder.encode(value));
        }
        throw new Error(`TypeException: expected String for to_binary, got ${zuzuTypeof(value)}`);
      }
      function toStringValue(value) {
        value = resolveWeakValue(value);
        if (typeof value === "string") {
          return value;
        }
        if (value instanceof ZuzuBinary) {
          try {
            return utf8Decoder.decode(value.bytes);
          } catch (err) {
            return Array.from(value.bytes, (byte) => String.fromCharCode(byte)).join("");
          }
        }
        throw new Error(`TypeException: expected BinaryString for to_string, got ${zuzuTypeof(value)}`);
      }
      function stringCompare(left, right, options = {}) {
        const l = options.insensitive ? zuzuOperatorString(left).toLowerCase() : zuzuOperatorString(left);
        const r = options.insensitive ? zuzuOperatorString(right).toLowerCase() : zuzuOperatorString(right);
        return l.localeCompare(r);
      }
      function parseNumericString(value) {
        const text = String(value).trim();
        const match = text.match(/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?$/);
        if (!match) {
          throw new Error(`TypeException: cannot coerce String to Number: ${JSON.stringify(String(value))}`);
        }
        const parsed = Number(text);
        if (Number.isNaN(parsed)) {
          throw new Error(`TypeException: cannot coerce String to Number: ${JSON.stringify(String(value))}`);
        }
        return parsed;
      }
      function zuzuToNumber(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return 0;
        }
        if (typeof value === "number" || Object.prototype.toString.call(value) === "[object Number]") {
          return Number(value);
        }
        if (typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]") {
          return value.valueOf() ? 1 : 0;
        }
        if (typeof value === "string" || Object.prototype.toString.call(value) === "[object String]") {
          return parseNumericString(value);
        }
        if (typeof value === "function") {
          throw new Error(`TypeException: cannot coerce ${zuzuTypeof(value)} to Number`);
        }
        if (value && typeof value.to_Number === "function") {
          return zuzuToNumber(value.to_Number());
        }
        throw new Error(`TypeException: cannot coerce ${zuzuTypeof(value)} to Number`);
      }
      function zuzuTruthy(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return false;
        }
        if (value && typeof value.to_Boolean === "function") {
          return zuzuTruthy(value.to_Boolean());
        }
        if (value instanceof ZuzuBinary) {
          return value.byteLength() > 0;
        }
        if (typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]") {
          return value.valueOf() === true;
        }
        if (typeof value === "number" || Object.prototype.toString.call(value) === "[object Number]") {
          return Number(value) !== 0;
        }
        if (typeof value === "string" || Object.prototype.toString.call(value) === "[object String]") {
          return String(value) !== "";
        }
        if (Array.isArray(value)) {
          return value.length > 0;
        }
        if (isPairListLike(value)) {
          return value.length() > 0;
        }
        if (value instanceof ZuzuBag) {
          return value.length() > 0;
        }
        if (isSetLike(value)) {
          return value.size > 0;
        }
        const ctorName = value && value.constructor && value.constructor.name;
        if (value && typeof value === "object" && (ctorName === "Object" || ctorName == null)) {
          return Object.keys(value).length > 0;
        }
        return Boolean(value);
      }
      function defaultOperator(leftInput, rightInput) {
        const left = resolveWeakValue(leftInput);
        const right = resolveWeakValue(rightInput);
        const leftType = zuzuTypeof(left);
        if (left != null && leftType !== "Dict" && !isPairListLike(left)) {
          throw new Error(
            `TypeException: default operator left operand expects Dict, PairList, or Null, got ${leftType}`
          );
        }
        if (zuzuTypeof(right) !== "Dict" && !isPairListLike(right)) {
          throw new Error(
            `TypeException: default operator right operand expects Dict or PairList, got ${zuzuTypeof(right)}`
          );
        }
        if (leftType === "Dict") {
          const result = {};
          for (const key of Object.keys(left)) {
            result[key] = left[key];
          }
          if (isPairListLike(right)) {
            for (const [key, value] of right.list) {
              if (!Object.prototype.hasOwnProperty.call(result, key)) {
                result[key] = value;
              }
            }
          } else {
            for (const key of Object.keys(right).sort()) {
              if (!Object.prototype.hasOwnProperty.call(result, key)) {
                result[key] = right[key];
              }
            }
          }
          return result;
        }
        const values = isPairListLike(left) ? left.list.map(([key, value]) => [key, value]) : [];
        const originalKeys = new Set(values.map(([key]) => key));
        if (isPairListLike(right)) {
          for (const [key, value] of right.list) {
            if (!originalKeys.has(key)) {
              values.push([key, value]);
            }
          }
        } else {
          for (const key of Object.keys(right).sort()) {
            if (!originalKeys.has(key)) {
              values.push([key, right[key]]);
            }
          }
        }
        return makePairList(values);
      }
      function isNumericComparable(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return true;
        }
        if (typeof value === "number" || typeof value === "string" || typeof value === "boolean") {
          return true;
        }
        const tag = Object.prototype.toString.call(value);
        if (tag === "[object Number]" || tag === "[object String]" || tag === "[object Boolean]") {
          return true;
        }
        return Boolean(value && typeof value.to_Number === "function");
      }
      function numericEqual(left, right) {
        const leftNum = zuzuToNumber(left);
        const rightNum = zuzuToNumber(right);
        if (Object.is(leftNum, rightNum)) {
          return true;
        }
        if (Number.isInteger(leftNum) && Number.isInteger(rightNum)) {
          return false;
        }
        const scale = Math.max(1, Math.abs(leftNum), Math.abs(rightNum));
        return Math.abs(leftNum - rightNum) <= Number.EPSILON * 16 * scale;
      }
      function isExhaustedIteratorError(err) {
        if (!err) {
          return false;
        }
        const name2 = String(err.name || err.constructor && err.constructor.name || "");
        if (name2 === "ExhaustedException") {
          return true;
        }
        const message = String(err.message || "");
        if (/\bExhaustedException\b/.test(message)) {
          return true;
        }
        const stack = String(err.stack || "");
        return /\bExhaustedException\b/.test(stack);
      }
      function formatRuntimeError(err) {
        if (err && err.name === "SyntaxError" && typeof err.stack === "string" && err.stack.trim()) {
          return `${err.stack}
`;
        }
        if (err && err.name && err.message) {
          return `${err.name}: ${err.message}
`;
        }
        return `${String(err)}
`;
      }
      async function runSwitchAsync(value, comparator, cases, defaultBody) {
        const cmp = (left, right) => {
          switch (comparator) {
            case "eq":
              return stringCompare(left, right) === 0;
            case "ne":
              return stringCompare(left, right) !== 0;
            case "=":
              return numericEqual(zuzuToNumber(left), zuzuToNumber(right));
            case "==":
            default:
              return !!zuzuEqual(left, right);
          }
        };
        let runNext = false;
        for (const section of cases) {
          const matched = section.values.some((item) => cmp(value, item));
          if (matched || runNext) {
            const result = await taskRuntime2.awaitValue(section.body());
            runNext = result === true;
            if (!runNext && result && typeof result === "object" && result.__zuzu_return) {
              return result;
            }
            if (!runNext) {
              return null;
            }
          }
        }
        if (defaultBody) {
          const result = await taskRuntime2.awaitValue(defaultBody());
          if (result && typeof result === "object" && result.__zuzu_return) {
            return result;
          }
        }
        return null;
      }
      function concatValue(left, right) {
        left = resolveWeakValue(left);
        right = resolveWeakValue(right);
        if (left instanceof ZuzuBinary && right instanceof ZuzuBinary) {
          const merged = new Uint8Array(left.length + right.length);
          merged.set(left.bytes, 0);
          merged.set(right.bytes, left.length);
          return new BinaryString2(merged);
        }
        if (typeof left === "string" && typeof right === "string") {
          return left + right;
        }
        if (left instanceof ZuzuBinary && typeof right === "string") {
          if (!left.isAscii()) {
            throw new Error("TypeException: Cannot implicitly concatenate non-ASCII BinaryString with String");
          }
          return left.to_String() + right;
        }
        if (typeof left === "string" && right instanceof ZuzuBinary) {
          if (!right.isAscii()) {
            throw new Error("TypeException: Cannot implicitly concatenate non-ASCII BinaryString with String");
          }
          return left + right.to_String();
        }
        return zuzuOperatorString(left) + zuzuOperatorString(right);
      }
      function operatorLength(value) {
        value = resolveWeakValue(value);
        if (value instanceof ZuzuBinary) {
          return value.byteLength();
        }
        if (Array.isArray(value) || isPairListLike(value) || value instanceof ZuzuBag || isSetLike(value) || value && typeof value === "object" && value.constructor && value.constructor.name === "Object") {
          return lengthOf(value);
        }
        return [...zuzuOperatorString(value)].length;
      }
      function regexReplaceValue(current, pattern, replacement) {
        const source = zuzuOperatorString(current);
        const regex = operatorRegexp(pattern);
        return source.replace(regex, replacement);
      }
      function bitwiseBinaryPair(left, right, opName) {
        if (left.length !== right.length) {
          throw new Error("Exception: BinaryString bitwise operands must be equal length");
        }
        const out = new Uint8Array(left.length);
        for (let i = 0; i < left.length; i++) {
          const a = left.bytes[i];
          const b = right.bytes[i];
          if (opName === "and") {
            out[i] = a & b;
          } else if (opName === "or") {
            out[i] = a | b;
          } else {
            out[i] = a ^ b;
          }
        }
        return new BinaryString2(out);
      }
      function bitwiseAnd(left, right) {
        if (left instanceof ZuzuBinary && right instanceof ZuzuBinary) {
          return bitwiseBinaryPair(left, right, "and");
        }
        return (zuzuToNumber(left) >>> 0 & zuzuToNumber(right) >>> 0) >>> 0;
      }
      function bitwiseOr(left, right) {
        if (left instanceof ZuzuBinary && right instanceof ZuzuBinary) {
          return bitwiseBinaryPair(left, right, "or");
        }
        return (zuzuToNumber(left) >>> 0 | zuzuToNumber(right) >>> 0) >>> 0;
      }
      function bitwiseXor(left, right) {
        if (left instanceof ZuzuBinary && right instanceof ZuzuBinary) {
          return bitwiseBinaryPair(left, right, "xor");
        }
        return (zuzuToNumber(left) >>> 0 ^ zuzuToNumber(right) >>> 0) >>> 0;
      }
      function bitwiseNot(value) {
        value = resolveWeakValue(value);
        if (value instanceof ZuzuBinary) {
          const out = new Uint8Array(value.length);
          for (let i = 0; i < value.length; i++) {
            out[i] = ~value.bytes[i] & 255;
          }
          return new BinaryString2(out);
        }
        return ~(zuzuToNumber(value) >>> 0) >>> 0;
      }
      function zuzuComparableValue(value) {
        value = resolveWeakValue(value);
        if (typeof value === "function" && value.length === 0) {
          try {
            return value();
          } catch (_err) {
            return value;
          }
        }
        return value;
      }
      function zuzuEqual(left, right) {
        const a = zuzuComparableValue(left);
        const b = zuzuComparableValue(right);
        if (a === b) {
          return 1;
        }
        if (a == null || b == null) {
          return 0;
        }
        if (a instanceof ZuzuBinary && b instanceof ZuzuBinary) {
          if (a.bytes.length !== b.bytes.length) {
            return 0;
          }
          for (let i = 0; i < a.bytes.length; i++) {
            if (a.bytes[i] !== b.bytes[i]) {
              return 0;
            }
          }
          return 1;
        }
        if (Array.isArray(a) && Array.isArray(b)) {
          if (a.length !== b.length) {
            return 0;
          }
          for (let i = 0; i < a.length; i++) {
            if (!zuzuEqual(a[i], b[i])) {
              return 0;
            }
          }
          return 1;
        }
        if (isSetLike(a) && isSetLike(b)) {
          return collectionEquivalentOf(a, b) ? 1 : 0;
        }
        if (isBagLike(a) && isBagLike(b)) {
          return zuzuEqual(a.to_Array(), b.to_Array());
        }
        if (isPairListLike(a) && isPairListLike(b)) {
          if (a.list.length !== b.list.length) {
            return 0;
          }
          for (let i = 0; i < a.list.length; i++) {
            if (a.list[i][0] !== b.list[i][0]) {
              return 0;
            }
            if (!zuzuEqual(a.list[i][1], b.list[i][1])) {
              return 0;
            }
          }
          return 1;
        }
        if (isPlainObjectLike(a) && isPlainObjectLike(b)) {
          const keysA = Object.keys(a).sort();
          const keysB = Object.keys(b).sort();
          if (!zuzuEqual(keysA, keysB)) {
            return 0;
          }
          for (const key of keysA) {
            if (!zuzuEqual(a[key], b[key])) {
              return 0;
            }
          }
          return 1;
        }
        return 0;
      }
      function isSetLike(value) {
        return Object.prototype.toString.call(value) === "[object Set]";
      }
      function isBagLike(value) {
        return value instanceof ZuzuBag || value && value.constructor && value.constructor.name === "ZuzuBag";
      }
      function isPlainObjectLike(value) {
        return Object.prototype.toString.call(value) === "[object Object]" && !(value.constructor && value.constructor.__zuzu_class_name);
      }
      function isDictMethodReceiver(value) {
        return value && typeof value === "object" && !Array.isArray(value) && !isPairListLike(value) && !isSetLike(value) && !isBagLike(value);
      }
      function normalizeDictKey(key) {
        key = resolveWeakValue(key);
        if (key == null) {
          return "";
        }
        if (typeof key === "string") {
          return key;
        }
        if (key instanceof ZuzuBinary) {
          return key.to_String();
        }
        if (key && typeof key.to_String === "function") {
          return String(key.to_String());
        }
        return String(key);
      }
      var DICT_METHODS = Object.freeze({
        length(self) {
          return isDictMethodReceiver(self) ? Object.keys(self).length : 0;
        },
        keys(self) {
          return isDictMethodReceiver(self) ? Object.keys(self).sort() : [];
        },
        values(self) {
          if (!isDictMethodReceiver(self)) {
            return [];
          }
          return DICT_METHODS.keys(self).map((key) => resolveWeakValue(self[key]));
        },
        copy(self) {
          if (!isDictMethodReceiver(self)) {
            return {};
          }
          const out = {};
          for (const key of Object.keys(self)) {
            out[key] = retainCollectionValue(out, self[key]);
          }
          return out;
        },
        enumerate(self) {
          if (!isDictMethodReceiver(self)) {
            return [];
          }
          return DICT_METHODS.keys(self).map(
            (key) => new Pair({ pair: [key, resolveWeakValue(self[key])] })
          );
        },
        has(self, key) {
          return isDictMethodReceiver(self) && Object.prototype.hasOwnProperty.call(self, normalizeDictKey(key)) ? 1 : 0;
        },
        contains(self, key) {
          return DICT_METHODS.has(self, key);
        },
        exists(self, key) {
          return DICT_METHODS.has(self, key);
        },
        defined(self, key) {
          const normalized = normalizeDictKey(key);
          return isDictMethodReceiver(self) && resolveWeakValue(self[normalized]) != null ? 1 : 0;
        },
        get(self, key, fallback = null) {
          const normalized = normalizeDictKey(key);
          return DICT_METHODS.has(self, normalized) ? resolveWeakValue(self[normalized]) : fallback;
        },
        add(self, key, value) {
          if (!isDictMethodReceiver(self) || key instanceof Pair) {
            return self;
          }
          const normalized = normalizeDictKey(key);
          releaseCollectionValue(self, self[normalized]);
          self[normalized] = retainCollectionValue(self, value);
          return self;
        },
        set(self, key, value) {
          return DICT_METHODS.add(self, key, value);
        },
        add_weak(self, key, value) {
          if (!isDictMethodReceiver(self) || key instanceof Pair) {
            return self;
          }
          const normalized = normalizeDictKey(key);
          releaseCollectionValue(self, self[normalized]);
          self[normalized] = makeWeakValue(value);
          return self;
        },
        set_weak(self, key, value) {
          return DICT_METHODS.add_weak(self, key, value);
        },
        kv(self) {
          if (!isDictMethodReceiver(self)) {
            return [];
          }
          const out = [];
          for (const key of DICT_METHODS.keys(self)) {
            out.push(key, resolveWeakValue(self[key]));
          }
          return out;
        },
        sorted_keys(self) {
          return DICT_METHODS.keys(self);
        },
        remove(self, key) {
          if (!isDictMethodReceiver(self)) {
            return self;
          }
          if (typeof key === "function") {
            for (const [k, v] of Object.entries(self)) {
              if (key(new Pair({ pair: [k, v] }))) {
                releaseCollectionValue(self, self[k]);
                delete self[k];
              }
            }
            return self;
          }
          if (key instanceof Pair) {
            return self;
          }
          const normalized = normalizeDictKey(key);
          releaseCollectionValue(self, self[normalized]);
          delete self[normalized];
          return self;
        },
        count(self) {
          return DICT_METHODS.length(self);
        },
        empty(self) {
          return DICT_METHODS.length(self) === 0 ? 1 : 0;
        },
        is_empty(self) {
          return DICT_METHODS.empty(self);
        },
        to_Array(self) {
          return DICT_METHODS.enumerate(self);
        },
        to_Iterator(self) {
          return DICT_METHODS.keys(self)[Symbol.iterator]();
        },
        for_each_key(self, fn2) {
          for (const key of DICT_METHODS.keys(self)) {
            fn2(key);
          }
          return self;
        },
        for_each_value(self, fn2) {
          for (const value of DICT_METHODS.values(self)) {
            fn2(value);
          }
          return self;
        },
        for_each_pair(self, fn2) {
          for (const pair of DICT_METHODS.enumerate(self)) {
            fn2(pair);
          }
          return self;
        },
        clear(self) {
          if (isDictMethodReceiver(self)) {
            for (const key of Object.keys(self)) {
              releaseCollectionValue(self, self[key]);
              delete self[key];
            }
          }
          return self;
        }
      });
      var DICT_ZERO_ARG_METHODS = /* @__PURE__ */ new Set([
        "clear",
        "copy",
        "count",
        "empty",
        "enumerate",
        "is_empty",
        "keys",
        "kv",
        "length",
        "sorted_keys",
        "to_Array",
        "to_Iterator",
        "values"
      ]);
      function getDictMethod(object, property) {
        if (typeof property === "symbol") {
          return null;
        }
        const name2 = String(property);
        if (!isDictMethodReceiver(object) || Object.prototype.hasOwnProperty.call(object, name2) || !Object.prototype.hasOwnProperty.call(DICT_METHODS, name2)) {
          return null;
        }
        return function zuzuDictMethod(...args) {
          return DICT_METHODS[name2](object, ...args);
        };
      }
      var ZuzuMethod = class {
        constructor(name2, fn2) {
          this.name = String(name2 || "");
          this.fn = fn2;
        }
        invoke(self, args = []) {
          return this.fn.apply(self, args);
        }
        to_String() {
          return this.name;
        }
      };
      function zuzuBoundMethod(receiver, name2, fn2) {
        const methodName = String(name2 || "");
        const bound = function __zuzu_bound_method(...args) {
          return fn2.apply(receiver, args);
        };
        Object.defineProperty(bound, "__zuzu_method", {
          value: true,
          enumerable: false,
          configurable: true
        });
        Object.defineProperty(bound, "__zuzu_bound_receiver", {
          value: receiver,
          enumerable: false,
          configurable: true
        });
        Object.defineProperty(bound, "__zuzu_bound_method_name", {
          value: methodName,
          enumerable: false,
          configurable: true
        });
        bound.invoke = function invoke(_self, args = []) {
          return fn2.apply(receiver, args);
        };
        bound.to_String = function to_String() {
          return methodName;
        };
        return bound;
      }
      function zuzuTypeof(value) {
        value = resolveWeakValue(value);
        if (value == null) {
          return "Null";
        }
        if (value && value.__zuzu_method) {
          return "Method";
        }
        if (value instanceof ZuzuMethod) {
          return "Method";
        }
        if (isPairListLike(value)) {
          return "PairList";
        }
        if (value && (typeof value === "object" || typeof value === "function") && typeof value.__zuzu_type_name === "string") {
          return value.__zuzu_type_name;
        }
        if (isBagLike(value)) {
          return "Bag";
        }
        if (isSetLike(value)) {
          return "Set";
        }
        if (Array.isArray(value)) {
          return "Array";
        }
        if (value instanceof Pair) {
          return "Pair";
        }
        if (value instanceof RegExp) {
          return "Regexp";
        }
        if (Object.prototype.toString.call(value) === "[object RegExp]") {
          return "Regexp";
        }
        if (typeof value === "boolean") {
          return "Boolean";
        }
        if (typeof value === "number") {
          return "Number";
        }
        if (typeof value === "string") {
          return "String";
        }
        if (value instanceof ZuzuBinary) {
          return "BinaryString";
        }
        if (typeof value === "function") {
          const source = Function.prototype.toString.call(value);
          if (/^\s*class\b/.test(source)) {
            return "Class";
          }
          return "Function";
        }
        if (value && value.constructor) {
          const ctorName = value.constructor.name || "Object";
          if (ctorName === "Object") {
            return "Dict";
          }
          if (ctorName === "Error") {
            return "Exception";
          }
          return ctorName;
        }
        return "Object";
      }
      function zuzuInstanceof(value, klass) {
        value = resolveWeakValue(value);
        klass = resolveWeakValue(klass);
        if (klass == null) {
          return value == null ? 1 : 0;
        }
        const klassName = typeof klass === "function" && klass.name ? klass.name : "";
        if (klassName === "Any") {
          return 1;
        }
        if (klassName === "Null") {
          return value == null ? 1 : 0;
        }
        if (klassName === "Boolean" || klass === Boolean) {
          return typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]" ? 1 : 0;
        }
        if (klassName === "Number" || klass === Number) {
          return typeof value === "number" || Object.prototype.toString.call(value) === "[object Number]" ? 1 : 0;
        }
        if (klassName === "String" || klass === String) {
          return typeof value === "string" || Object.prototype.toString.call(value) === "[object String]" ? 1 : 0;
        }
        if (klassName === "Array" || klass === Array) {
          return Array.isArray(value) ? 1 : 0;
        }
        if (klassName === "BinaryString") {
          return value instanceof ZuzuBinary ? 1 : 0;
        }
        if (klassName === "Function" || klass === Function) {
          return typeof value === "function" ? 1 : 0;
        }
        if (klassName === "Exception") {
          if (value == null) {
            return 0;
          }
          if (value instanceof Error) {
            return 1;
          }
          const valueName = String(
            value.name || value.constructor && value.constructor.name || ""
          );
          return [
            "Exception",
            "TypeException",
            "ExhaustedException",
            "CancelledException",
            "TimeoutException",
            "ChannelClosedException"
          ].includes(valueName) ? 1 : 0;
        }
        if (klassName === "TypeException") {
          if (value == null) {
            return 0;
          }
          const valueName = String(
            value.name || value.constructor && value.constructor.name || ""
          );
          return valueName === "TypeException" ? 1 : 0;
        }
        if (klassName === "ExhaustedException") {
          if (value == null) {
            return 0;
          }
          const valueName = String(
            value.name || value.constructor && value.constructor.name || ""
          );
          return valueName === "ExhaustedException" ? 1 : 0;
        }
        if ([
          "CancelledException",
          "TimeoutException",
          "ChannelClosedException"
        ].includes(klassName)) {
          if (value == null) {
            return 0;
          }
          const valueName = String(
            value.name || value.constructor && value.constructor.name || ""
          );
          return valueName === klassName ? 1 : 0;
        }
        if (klassName === "Collection") {
          return Array.isArray(value) || isSetLike(value) || isBagLike(value) || zuzuTypeof(value) === "Dict" ? 1 : 0;
        }
        if (klassName === "Dict") {
          return zuzuTypeof(value) === "Dict" ? 1 : 0;
        }
        if (klassName === "Set") {
          return isSetLike(value) ? 1 : 0;
        }
        if (klassName === "Bag") {
          return isBagLike(value) ? 1 : 0;
        }
        if (klassName === "Class") {
          return typeof value === "function" ? 1 : 0;
        }
        if (klassName === "Object" || klass === Object) {
          return value !== null && typeof value === "object" ? 1 : 0;
        }
        try {
          return value instanceof klass ? 1 : 0;
        } catch (_err) {
          return 0;
        }
      }
      function isNativeErrorConstructorName(name2) {
        return [
          "Error",
          "EvalError",
          "RangeError",
          "ReferenceError",
          "SyntaxError",
          "TypeError",
          "URIError"
        ].includes(String(name2 || ""));
      }
      function zuzuTrait(name2, methods, source = null, captures = {}) {
        const trait = {
          __zuzu_trait_name: String(name2 || ""),
          __zuzu_trait_methods: methods || {}
        };
        if (source != null) {
          Object.defineProperty(trait, "__zuzu_marshal_meta", {
            value: {
              kind: "trait",
              name: String(name2 || ""),
              source: String(source),
              captures: captures || {}
            },
            enumerable: false,
            configurable: true,
            writable: true
          });
        }
        return trait;
      }
      var perObjectTraitClassCache = /* @__PURE__ */ new WeakMap();
      function isZuzuIdentifierName(name2) {
        return /^[A-Za-z_][A-Za-z0-9_]*$/u.test(String(name2 || ""));
      }
      function zuzuClassWithTraits(base, traits) {
        if (typeof base !== "function") {
          throw new Error(`TypeException: new with traits expects Class, got ${zuzuTypeof(base)}`);
        }
        const traitList = Array.isArray(traits) ? traits : [];
        let node = perObjectTraitClassCache.get(base);
        if (!node) {
          node = /* @__PURE__ */ new WeakMap();
          perObjectTraitClassCache.set(base, node);
        }
        for (const trait of traitList) {
          if (!trait || !trait.__zuzu_trait_methods) {
            throw new Error(`TypeException: new with traits expects Trait, got ${zuzuTypeof(trait)}`);
          }
          let next = node.get(trait);
          if (!next) {
            next = /* @__PURE__ */ new WeakMap();
            node.set(trait, next);
          }
          node = next;
        }
        if (node.__zuzu_class) {
          return node.__zuzu_class;
        }
        const rawName = base.__zuzu_class_name || base.name || "Object";
        const name2 = isZuzuIdentifierName(rawName) ? rawName : "__zuzu_per_object_class";
        const captures = { __zuzu_per_object_base: base };
        const traitNames = traitList.map((trait, index) => {
          const captureName = `__zuzu_per_object_trait_${index}`;
          captures[captureName] = trait;
          return captureName;
        });
        const source = `class ${name2} extends __zuzu_per_object_base with ${traitNames.join(", ")};`;
        const klass = defineZuzuClass(rawName, base, {
          marshalSource: source,
          marshalCaptures: captures,
          traits: traitList,
          fields: [],
          methods: {},
          statics: {},
          nested: {}
        });
        Object.defineProperty(node, "__zuzu_class", {
          value: klass,
          enumerable: false,
          configurable: true,
          writable: true
        });
        return klass;
      }
      function zuzuApplyTraits(klass, traits) {
        if (!klass || !klass.prototype || !Array.isArray(traits)) {
          return klass;
        }
        if (!Object.prototype.hasOwnProperty.call(klass, "__zuzu_traits")) {
          const desc = /* @__PURE__ */ Object.create(null);
          desc.value = /* @__PURE__ */ new Set();
          desc.enumerable = false;
          desc.configurable = true;
          desc.writable = true;
          Object.defineProperty(klass, "__zuzu_traits", desc);
        }
        for (const trait of traits) {
          if (!trait || !trait.__zuzu_trait_methods) {
            continue;
          }
          klass.__zuzu_traits.add(trait.__zuzu_trait_name || "");
          for (const [name2, fn2] of Object.entries(trait.__zuzu_trait_methods)) {
            if (typeof fn2 !== "function") {
              continue;
            }
            if (Object.prototype.hasOwnProperty.call(klass.prototype, name2) && typeof klass.prototype[name2] === "function") {
              klass.prototype[`__zuzu_trait_super__${name2}`] = fn2;
            } else {
              klass.prototype[name2] = fn2;
            }
          }
        }
        return klass;
      }
      function zuzuDoes(value, trait) {
        value = resolveWeakValue(value);
        if (value == null || !trait) {
          return 0;
        }
        const name2 = trait.__zuzu_trait_name || trait.name || String(trait);
        let ctor = value.constructor;
        while (ctor) {
          if (ctor.__zuzu_traits instanceof Set && ctor.__zuzu_traits.has(name2)) {
            return 1;
          }
          ctor = Object.getPrototypeOf(ctor);
        }
        return 0;
      }
      function zuzuStoreField(object, field, value) {
        const stored = field.isWeakStorage ? makeWeakValue(value) : retainValue(value);
        releaseValue(object[field.name]);
        object[field.name] = stored;
        return stored;
      }
      function defineZuzuClass(name2, base, spec = {}) {
        const parent = typeof base === "function" ? base : Object;
        const fields = Array.isArray(spec.fields) ? spec.fields : [];
        const traits = Array.isArray(spec.traits) ? spec.traits : [];
        const methods = spec.methods && typeof spec.methods === "object" ? spec.methods : {};
        const statics = spec.statics && typeof spec.statics === "object" ? spec.statics : {};
        const nested = spec.nested && typeof spec.nested === "object" ? spec.nested : {};
        const ctor = {
          [name2]: class extends parent {
            constructor(...args) {
              const skipBuild = args[0] === ZUZU_SKIP_BUILD;
              const ctorArgs = skipBuild ? args.slice(1) : args;
              const superArgs = parent.__zuzu_class_name ? skipBuild ? args : [ZUZU_SKIP_BUILD, ...ctorArgs] : ctorArgs;
              super(...superArgs);
              if (this instanceof Error) {
                this.name = name2;
              }
              for (const field of fields) {
                let value = null;
                if (field.defaultValue && typeof field.defaultValue === "function") {
                  value = field.defaultValue.call(this);
                }
                zuzuStoreField(this, field, value);
              }
              let named = null;
              if (ctorArgs.length === 1 && isPairListLike(ctorArgs[0])) {
                named = ctorArgs[0];
              } else if (ctorArgs.length === 1 && ctorArgs[0] && typeof ctorArgs[0] === "object" && !Array.isArray(ctorArgs[0])) {
                named = ctorArgs[0];
              }
              const releaseTemporaryNamed = !skipBuild && isPairListLike(named) && named.__zuzu_temporary_call_args === true;
              try {
                if (named) {
                  for (const field of fields) {
                    const incoming = isPairListLike(named) ? named.get(field.name, resolveWeakValue(this[field.name])) : Object.prototype.hasOwnProperty.call(named, field.name) ? named[field.name] : resolveWeakValue(this[field.name]);
                    if (field.typeName && incoming != null && !zuzuTypeMatches(incoming, field.typeName)) {
                      throw new Error(`TypeException: field '${field.name}' must be ${field.typeName}, got ${zuzuTypeof(incoming)}`);
                    }
                    zuzuStoreField(this, field, incoming);
                  }
                }
                for (const [nestedName, nestedClass] of Object.entries(nested)) {
                  this[nestedName] = nestedClass;
                }
                if (!skipBuild && typeof this.__build__ === "function") {
                  this.__build__();
                }
              } finally {
                if (releaseTemporaryNamed) {
                  releaseCollectionValues(named);
                }
              }
            }
          }
        }[name2];
        for (const field of fields) {
          if (Array.isArray(field.accessors)) {
            if (field.accessors.includes("get") && typeof ctor.prototype[`get_${field.name}`] !== "function") {
              ctor.prototype[`get_${field.name}`] = function _get_field() {
                return resolveWeakValue(this[field.name]);
              };
            }
            if (field.accessors.includes("set") && typeof ctor.prototype[`set_${field.name}`] !== "function") {
              ctor.prototype[`set_${field.name}`] = function _set_field(value) {
                if (field.typeName && value != null && !zuzuTypeMatches(value, field.typeName)) {
                  throw new Error(`TypeException: field '${field.name}' must be ${field.typeName}, got ${zuzuTypeof(value)}`);
                }
                zuzuStoreField(this, field, value);
                return this;
              };
            }
            if (field.accessors.includes("clear") && typeof ctor.prototype[`clear_${field.name}`] !== "function") {
              ctor.prototype[`clear_${field.name}`] = function _clear_field() {
                zuzuStoreField(this, field, null);
                return this;
              };
            }
            if (field.accessors.includes("has") && typeof ctor.prototype[`has_${field.name}`] !== "function") {
              ctor.prototype[`has_${field.name}`] = function _has_field() {
                return resolveWeakValue(this[field.name]) != null ? 1 : 0;
              };
            }
          }
        }
        for (const [methodName, fn2] of Object.entries(methods)) {
          ctor.prototype[methodName] = fn2;
        }
        for (const [methodName, fn2] of Object.entries(statics)) {
          ctor[methodName] = fn2;
        }
        for (const [nestedName, nestedClass] of Object.entries(nested)) {
          ctor[nestedName] = nestedClass;
        }
        zuzuApplyTraits(ctor, traits);
        Object.defineProperty(ctor, "__zuzu_class_name", {
          value: name2,
          enumerable: false,
          configurable: true,
          writable: true
        });
        Object.defineProperty(ctor, "__zuzu_class_spec", {
          value: {
            fields: fields.map((field) => ({ ...field })),
            traits: traits.slice(),
            methods: { ...methods },
            statics: { ...statics },
            nested: { ...nested }
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
        if (typeof spec.marshalSource === "string") {
          Object.defineProperty(ctor, "__zuzu_marshal_meta", {
            value: {
              kind: "class",
              name: name2,
              source: spec.marshalSource,
              captures: spec.marshalCaptures || {}
            },
            enumerable: false,
            configurable: true,
            writable: true
          });
        }
        return ctor;
      }
      function zuzuGetMember(object, property) {
        object = resolveWeakValue(object);
        if (object == null) {
          return null;
        }
        const value = resolveWeakValue(object[property]);
        if (typeof value === "function" && value.length === 0 && !value.__zuzu_marshal_meta) {
          return value.call(object);
        }
        const dictMethod = getDictMethod(object, property);
        if (dictMethod && DICT_ZERO_ARG_METHODS.has(String(property))) {
          return dictMethod();
        }
        if (dictMethod) {
          return dictMethod;
        }
        return resolveWeakValue(value);
      }
      function zuzuResolveBraceKey(_object, literalProperty, _getDynamicProperty) {
        const literal = String(literalProperty || "");
        return literal;
      }
      function zuzuGetBraceMember(object, literalProperty, getDynamicProperty) {
        object = resolveWeakValue(object);
        if (object == null) {
          return null;
        }
        return zuzuGetIndex(object, zuzuResolveBraceKey(object, literalProperty, getDynamicProperty));
      }
      function zuzuCallMember(object, property, ...args) {
        object = resolveWeakValue(object);
        if (object == null) {
          throw new TypeError(`Cannot call member ${String(property)} of null`);
        }
        if (property instanceof ZuzuMethod || property && property.__zuzu_method) {
          return property.invoke(object, args);
        }
        const value = resolveWeakValue(object[property]);
        if (typeof value === "function") {
          return value.apply(object, args);
        }
        let proto = Object.getPrototypeOf(object);
        while (proto) {
          const descriptor = Object.getOwnPropertyDescriptor(proto, property);
          if (descriptor && typeof descriptor.value === "function") {
            return descriptor.value.apply(object, args);
          }
          proto = Object.getPrototypeOf(proto);
        }
        const dictMethod = getDictMethod(object, property);
        if (dictMethod) {
          return dictMethod(...args);
        }
        if (args.length === 0) {
          return value;
        }
        throw new TypeError(`${String(property)} is not a function`);
      }
      function zuzuMaybeDemolish(value) {
        const original = value;
        value = resolveWeakValue(value);
        let result = null;
        if (value && typeof value.__demolish__ === "function") {
          result = value.__demolish__();
        }
        releaseValue(original);
        return result;
      }
      function zuzuCan(value, methodName) {
        value = resolveWeakValue(value);
        if (value == null) {
          return 0;
        }
        const key = String(methodName || "");
        if (getDictMethod(value, key)) {
          return 1;
        }
        if (typeof value[key] === "function") {
          return 1;
        }
        let proto = Object.getPrototypeOf(value);
        while (proto) {
          const descriptor = Object.getOwnPropertyDescriptor(proto, key);
          if (descriptor && typeof descriptor.value === "function") {
            return 1;
          }
          proto = Object.getPrototypeOf(proto);
        }
        return 0;
      }
      function zuzuSuperCall(self, klass, methodName, args = []) {
        const method = String(methodName || "");
        const argv = Array.isArray(args) ? args : [];
        if (klass && self && typeof self[`__zuzu_trait_super__${method}`] === "function") {
          return self[`__zuzu_trait_super__${method}`].apply(self, argv);
        }
        if (!klass && self && self.constructor) {
          klass = self.constructor;
        }
        if (klass && klass.prototype) {
          const parentProto = Object.getPrototypeOf(klass.prototype);
          if (parentProto && typeof parentProto[method] === "function") {
            return parentProto[method].apply(self, argv);
          }
        }
        return null;
      }
      function zuzuSuperStaticCall(klass, methodName, args = []) {
        const method = String(methodName || "");
        const argv = Array.isArray(args) ? args : [];
        if (!klass) {
          return null;
        }
        const parentClass = Object.getPrototypeOf(klass);
        if (parentClass && typeof parentClass[method] === "function") {
          return parentClass[method].apply(klass, argv);
        }
        return null;
      }
      function zuzuSuperDispatch(isStatic, self, klass, methodName, args = []) {
        return isStatic ? zuzuSuperStaticCall(klass, methodName, args) : zuzuSuperCall(self, klass, methodName, args);
      }
      function refIndex(target, index) {
        target = resolveWeakValue(target);
        return function refValue(maybeValue) {
          if (arguments.length === 0) {
            if (target instanceof ZuzuBinary) {
              return target.at(index);
            }
            return resolveWeakValue(target[index]);
          }
          if (target instanceof ZuzuBinary) {
            throw new Error("Exception: BinaryString index assignment is not supported");
          }
          target[index] = maybeValue;
          return maybeValue;
        };
      }
      function zuzuGetIndex(target, index) {
        target = resolveWeakValue(target);
        if (target == null) {
          return null;
        }
        const key = String(index);
        if (typeof target === "function" && target.prototype) {
          if (typeof target.prototype[key] === "function") {
            return new ZuzuMethod(key, target.prototype[key]);
          }
        }
        if (target instanceof ZuzuBinary) {
          return target.at(index);
        }
        if (isPairListLike(target)) {
          return resolveWeakValue(target.get(index, null));
        }
        if (typeof target === "string" || Array.isArray(target)) {
          let resolved = Number(index);
          if (Number.isFinite(resolved)) {
            const indexed = typeof target === "string" ? [...target] : target;
            if (resolved < 0) {
              resolved = indexed.length + resolved;
            }
            return resolveWeakValue(indexed[resolved] ?? null);
          }
        }
        if (target && typeof target === "object" && target.constructor && typeof target.constructor.__zuzu_class_name === "string" && !Object.prototype.hasOwnProperty.call(target, key) && typeof target[key] === "function") {
          return zuzuBoundMethod(target, key, target[key]);
        }
        return resolveWeakValue(target[index]);
      }
      function zuzuSliceBounds(size, from, length) {
        let start = Number(from ?? 0);
        if (!Number.isFinite(start)) {
          start = 0;
        }
        if (start < 0) {
          start = size + start;
        }
        start = Math.max(0, Math.min(size, start));
        if (length == null) {
          return [start, size];
        }
        const span = Number(length);
        if (!Number.isFinite(span)) {
          return [start, start];
        }
        const end = span < 0 ? Math.max(0, Math.min(size, size + span)) : Math.max(0, Math.min(size, start + span));
        return [Math.min(start, end), Math.max(start, end)];
      }
      function zuzuGetSlice(target, from, length) {
        target = resolveWeakValue(target);
        if (target == null) {
          return null;
        }
        if (typeof target === "string") {
          const chars = [...target];
          const [start, end] = zuzuSliceBounds(chars.length, from, length);
          return chars.slice(start, end).join("");
        }
        if (target instanceof ZuzuBinary) {
          const [start, end] = zuzuSliceBounds(target.length, from, length);
          return target.slice(start, end);
        }
        if (Array.isArray(target)) {
          const [start, end] = zuzuSliceBounds(target.length, from, length);
          return target.slice(start, end);
        }
        return target.slice(from, length == null ? void 0 : Number(from) + Number(length));
      }
      function zuzuAssignSlice(target, from, length, value) {
        const hasLength = length != null;
        const replacement = value == null ? "" : value;
        if (typeof target === "string") {
          const chars = [...target];
          const [start2, end] = zuzuSliceBounds(chars.length, from, length);
          chars.splice(start2, end - start2, ...[...String(replacement)]);
          return chars.join("");
        }
        const start = Number(from);
        if (Array.isArray(target)) {
          const items = Array.isArray(replacement) ? replacement : [replacement];
          const span = hasLength ? Number(length) : null;
          if (hasLength) {
            target.splice(start, span, ...items);
          } else {
            target.splice(start, target.length - start, ...items);
          }
          return target;
        }
        if (target instanceof ZuzuBinary) {
          if (!(value instanceof ZuzuBinary)) {
            throw new Error(`TypeException: BinaryString slice assignment expects BinaryString, got ${zuzuTypeof(value)}`);
          }
          const [byteStart, byteEnd] = zuzuSliceBounds(target.length, from, length);
          const next = new Uint8Array(target.length - (byteEnd - byteStart) + value.bytes.length);
          next.set(target.bytes.slice(0, byteStart), 0);
          next.set(value.bytes, byteStart);
          next.set(target.bytes.slice(byteEnd), byteStart + value.bytes.length);
          target.bytes = next;
          return target;
        }
        throw new Error(`TypeException: slice assignment expects String or Array, got ${zuzuTypeof(target)}`);
      }
      function refKey(target, key) {
        target = resolveWeakValue(target);
        return function refValue(maybeValue) {
          if (arguments.length === 0) {
            return resolveWeakValue(target[key]);
          }
          target[key] = maybeValue;
          return maybeValue;
        };
      }
      function assignIndexedValue(target, index, value, isWeakWrite = false, assignTarget = null) {
        target = resolveWeakValue(target);
        if (target == null) {
          throw new Error("TypeException: cannot assign to null");
        }
        if (target instanceof ZuzuBinary) {
          if (!(value instanceof ZuzuBinary)) {
            throw new Error(`TypeException: BinaryString index assignment expects BinaryString, got ${zuzuTypeof(value)}`);
          }
          zuzuAssignSlice(target, index, 1, value);
          if (typeof assignTarget === "function") {
            assignTarget(target);
          }
          return target;
        }
        if (typeof target === "string") {
          let resolved = Number(index);
          if (!Number.isFinite(resolved)) {
            throw new Error("TypeException: String index assignment expects numeric index");
          }
          const chars = [...target];
          if (resolved < 0) {
            resolved = chars.length + resolved;
          }
          resolved = Math.max(0, Math.min(chars.length, resolved));
          chars.splice(resolved, resolved < chars.length ? 1 : 0, ...[...String(value ?? "")]);
          const updated = chars.join("");
          return typeof assignTarget === "function" ? assignTarget(updated) : updated;
        }
        if (isPairListLike(target)) {
          const stored2 = isWeakWrite ? makeWeakValue(value) : retainCollectionValue(target, value);
          target.list.push([String(index), stored2]);
          return stored2;
        }
        const stored = isWeakWrite ? makeWeakValue(value) : retainCollectionValue(target, value);
        releaseCollectionValue(target, target[index]);
        target[index] = stored;
        return stored;
      }
      function refSlice(target, from, length) {
        target = resolveWeakValue(target);
        return function refSliceValue(maybeValue) {
          const start = Number(from);
          const hasLength = length != null;
          const span = hasLength ? Number(length) : null;
          if (arguments.length === 0) {
            return zuzuGetSlice(target, start, hasLength ? span : null);
          }
          if (target instanceof ZuzuBinary || typeof target === "string") {
            return zuzuAssignSlice(target, start, hasLength ? span : null, maybeValue);
          }
          if (!hasLength) {
            target.splice(start, target.length - start, ...maybeValue);
            return maybeValue;
          }
          target.splice(start, span, ...maybeValue);
          return maybeValue;
        };
      }
      function makePathOperator(runtime, filename) {
        return function zuzuPathOp(haystack, pathSpec, mode = "first") {
          const pathObj = resolvePathObject(runtime, filename, pathSpec);
          if (mode === "all") {
            return pathObj.query(haystack);
          }
          if (mode === "exists") {
            return pathObj.exists(haystack);
          }
          return pathObj.first(haystack, null);
        };
      }
      function resolveActivePathClass(runtime, filename) {
        const internals = runtime.loadModule("std/internals", filename);
        if (!internals || typeof internals.getupperprop !== "function") {
          return null;
        }
        return internals.getupperprop(0, "paths");
      }
      function resolvePathObject(runtime, filename, pathSpec) {
        let PathClass = resolveActivePathClass(runtime, filename);
        const pathText = String(pathSpec ?? "");
        if (!PathClass) {
          const zzpath = runtime.loadModule("std/path/zz", filename);
          PathClass = zzpath && zzpath.ZZPath ? zzpath.ZZPath : null;
        }
        if (!PathClass) {
          throw new Error("Exception: no path implementation available");
        }
        return pathSpec && typeof pathSpec === "object" && typeof pathSpec.query === "function" ? pathSpec : new PathClass({ path: pathText });
      }
      function makePathAssignmentOperator(runtime, filename) {
        return function zuzuPathAssign(haystack, pathSpec, value, mode = "first", op = ":=", isWeakWrite = false) {
          const pathObj = resolvePathObject(runtime, filename, pathSpec);
          const storedValue = isWeakWrite ? makeWeakValue(value) : value;
          if (mode === "all") {
            return pathObj.assign_all(haystack, storedValue, op);
          }
          if (mode === "maybe") {
            return pathObj.assign_maybe(haystack, storedValue, op);
          }
          return pathObj.assign_first(haystack, storedValue, op);
        };
      }
      function makePathReferenceOperator(runtime, filename) {
        return function zuzuPathRef(haystack, pathSpec, mode = "first") {
          const pathObj = resolvePathObject(runtime, filename, pathSpec);
          if (mode === "all") {
            return pathObj.ref_all(haystack);
          }
          if (mode === "maybe") {
            return pathObj.ref_maybe(haystack);
          }
          return pathObj.ref_first(haystack);
        };
      }
      function callPathRef(refFn) {
        if (typeof refFn !== "function") {
          throw new Error("Exception: path reference target is not assignable");
        }
        return refFn();
      }
      function setPathRef(refFn, value) {
        if (typeof refFn !== "function") {
          throw new Error("Exception: path reference target is not assignable");
        }
        return refFn(value);
      }
      function makePathUpdateOperator(runtime, filename) {
        return function zuzuPathUpdate(haystack, pathSpec, mode, operator, prefix) {
          const pathObj = resolvePathObject(runtime, filename, pathSpec);
          if (mode === "all") {
            const refs = pathObj.ref_all(haystack);
            const oldValues = [];
            const newValues = [];
            for (const refFn2 of refs) {
              const oldValue2 = zuzuToNumber(callPathRef(refFn2));
              const newValue2 = operator === "++" ? oldValue2 + 1 : oldValue2 - 1;
              setPathRef(refFn2, newValue2);
              oldValues.push(oldValue2);
              newValues.push(newValue2);
            }
            return prefix ? newValues : oldValues;
          }
          if (mode === "maybe") {
            const refFn2 = pathObj.ref_maybe(haystack);
            if (refFn2 == null) {
              return false;
            }
            const oldValue2 = zuzuToNumber(callPathRef(refFn2));
            const newValue2 = operator === "++" ? oldValue2 + 1 : oldValue2 - 1;
            setPathRef(refFn2, newValue2);
            return true;
          }
          const refFn = pathObj.ref_first(haystack);
          const oldValue = zuzuToNumber(callPathRef(refFn));
          const newValue = operator === "++" ? oldValue + 1 : oldValue - 1;
          setPathRef(refFn, newValue);
          return prefix ? newValue : oldValue;
        };
      }
      function zuzuTypeMatches(value, typeName2) {
        value = resolveWeakValue(value);
        if (typeName2 === "Any") {
          return 1;
        }
        if (value == null) {
          return 0;
        }
        if (typeName2 === "Number" || typeName2 === "String" || typeName2 === "Array" || typeName2 === "Dict" || typeName2 === "Set" || typeName2 === "Bag" || typeName2 === "PairList" || typeName2 === "Collection" || typeName2 === "Class" || typeName2 === "Function" || typeName2 === "Object" || typeName2 === "Exception" || typeName2 === "Regexp") {
          if (typeName2 === "Collection") {
            return Array.isArray(value) || isSetLike(value) || isBagLike(value) || isPairListLike(value) || zuzuTypeof(value) === "Dict" ? 1 : 0;
          }
          if (typeName2 === "Object") {
            return value !== null && typeof value === "object" ? 1 : 0;
          }
          if (typeName2 === "PairList") {
            return isPairListLike(value) ? 1 : 0;
          }
          if (typeName2 === "Exception") {
            const globalType2 = globalThis.Exception;
            if (globalType2 != null && zuzuInstanceof(value, globalType2)) {
              return 1;
            }
            return value instanceof Error ? 1 : 0;
          }
          return zuzuTypeof(value) === typeName2 ? 1 : 0;
        }
        if (typeName2 === "BinaryString") {
          return value instanceof ZuzuBinary ? 1 : 0;
        }
        if (typeName2 === "Boolean") {
          if (typeof value === "boolean" || Object.prototype.toString.call(value) === "[object Boolean]") {
            return 1;
          }
          if (typeof value === "number") {
            return value === 0 || value === 1 ? 1 : 0;
          }
        }
        if (typeName2 === "Regexp") {
          return Object.prototype.toString.call(value) === "[object RegExp]" ? 1 : 0;
        }
        if (zuzuTypeof(value) === typeName2) {
          return 1;
        }
        if (Array.isArray(value.__zuzu_type_names) && value.__zuzu_type_names.includes(typeName2)) {
          return 1;
        }
        let proto = Object.getPrototypeOf(value);
        while (proto) {
          const ctor = proto.constructor;
          if (ctor && ctor.name === typeName2) {
            return 1;
          }
          proto = Object.getPrototypeOf(proto);
        }
        const globalType = globalThis[typeName2];
        if (globalType == null) {
          return 0;
        }
        return zuzuInstanceof(value, globalType) ? 1 : 0;
      }
      var ZuzuScript = class {
        constructor(options = {}) {
          if (options.host) {
            this.host = options.host;
          } else {
            const { createNodeHost } = __require("./host/node-host");
            this.host = createNodeHost(options);
          }
          this.repoRoot = this.host.repoRoot;
          this.includePaths = this.host.includePaths;
          this.moduleSearchRoots = defaultModuleSearchRoots(
            this.host,
            this.repoRoot,
            this.includePaths
          );
          const allowCapabilities = new Set(Array.isArray(options.allowCapabilities) ? options.allowCapabilities.map((item) => String(item)) : []);
          this.denyCapabilities = new Set(Array.isArray(options.denyCapabilities) ? options.denyCapabilities.map((item) => String(item)) : []);
          for (const capability of ["gui"]) {
            if (!allowCapabilities.has(capability) && !this.host.capabilities.has(capability)) {
              this.denyCapabilities.add(capability);
            }
          }
          this.denyModules = new Set(Array.isArray(options.denyModules) ? options.denyModules.map((item) => String(item)) : []);
          this.debugLevel = Number.isFinite(Number(options.debugLevel)) ? Number(options.debugLevel) : 0;
          this.moduleCache = /* @__PURE__ */ new Map();
          this.moduleLoading = /* @__PURE__ */ new Set();
          this.evalCapabilityOverrides = null;
          this.outputLines = null;
          this.stdoutHandler = null;
          this.stderrHandler = null;
          this.executionTimeoutMs = Number.isFinite(Number(options.executionTimeoutMs)) ? Number(options.executionTimeoutMs) : null;
          this.transpiler = normalizeTranspilerName(
            options.transpiler || DEFAULT_TRANSPILER
          );
          if (typeof this.host.loadJsModule !== "function") {
            this.host.loadJsModule = (filename) => __require(filename);
          }
        }
        transpile(source, options = {}) {
          return transpile(source, {
            ...options,
            transpiler: options.transpiler || this.transpiler
          });
        }
        getModuleSearchRoots() {
          return this.moduleSearchRoots.slice();
        }
        isDeniedByCapability(moduleName) {
          const required = capabilitiesForModule(moduleName);
          for (const capability of required) {
            if (this.isCapabilityDenied(capability)) {
              return capability;
            }
            if (!this.host.capabilities.has(capability)) {
              return capability;
            }
          }
          return null;
        }
        isCapabilityDenied(capability) {
          if (this.denyCapabilities.has(capability)) {
            return true;
          }
          if (this.evalCapabilityOverrides) {
            const flagName = `deny_${capability}`;
            if (this.evalCapabilityOverrides[flagName]) {
              return true;
            }
          }
          return false;
        }
        enforceModulePolicy(moduleName) {
          if (this.denyModules.has(moduleName)) {
            throw new Error(`Denied module: ${moduleName}`);
          }
          const capability = this.isDeniedByCapability(moduleName);
          if (capability) {
            if (this.denyCapabilities.has(capability)) {
              throw new Error(`Denied capability '${capability}' blocks module '${moduleName}'`);
            }
            throw new Error(`Module '${moduleName}' requires unsupported capability '${capability}' on host '${this.host.name}'`);
          }
        }
        fileValueForFilename(filename) {
          if (this.isCapabilityDenied("fs") || !this.host.capabilities.has("fs") || !filename || String(filename).startsWith("<") || String(filename).startsWith("(")) {
            return null;
          }
          const { Path } = require_io();
          return new Path(filename);
        }
        resolveModulePath(moduleName, fromFile) {
          const fromDir = fromFile ? this.host.dirname(fromFile) : this.repoRoot;
          if (!moduleName.startsWith(".") && !moduleName.startsWith("/")) {
            const runtimeSupported = this.host.resolve(
              this.repoRoot,
              "modules",
              `${moduleName}.js`
            );
            if (this.host.fileExists(runtimeSupported)) {
              return runtimeSupported;
            }
          }
          const candidates = [];
          if (moduleName.startsWith(".") || moduleName.startsWith("/")) {
            candidates.push(this.host.resolve(fromDir, moduleName));
          } else {
            for (const base of this.getModuleSearchRoots()) {
              candidates.push(this.host.resolve(base, moduleName));
            }
          }
          const withExt = [];
          for (const candidate of candidates) {
            withExt.push(candidate, `${candidate}.zzs`, `${candidate}.zzm`, `${candidate}.js`);
          }
          for (const candidate of withExt) {
            if (this.host.fileExists(candidate)) {
              return candidate;
            }
          }
          throw new Error(`Unable to resolve module: ${moduleName}`);
        }
        buildContext(options = {}) {
          const filename = options.filename;
          const runtime = this;
          taskRuntime2.setDebugLevel(this.debugLevel);
          let context;
          const capabilityFlags = /* @__PURE__ */ Object.create(null);
          for (const name2 of this.host.capabilities) {
            if (!this.denyCapabilities.has(name2)) {
              capabilityFlags[name2] = 1;
            }
          }
          if (this.evalCapabilityOverrides) {
            for (const [flagName, denied] of Object.entries(this.evalCapabilityOverrides)) {
              const capability = flagName.replace(/^deny_/, "");
              if (denied) {
                delete capabilityFlags[capability];
              } else if (this.host.capabilities.has(capability) && !this.denyCapabilities.has(capability)) {
                capabilityFlags[capability] = 1;
              }
            }
          }
          const moduleSearchRoots = this.getModuleSearchRoots();
          const emit = (value) => {
            const line = String(value);
            if (this.outputLines) {
              this.outputLines.push(line);
            }
            if (typeof this.stdoutHandler === "function") {
              this.stdoutHandler(`${line}
`);
            } else if (!this.outputLines) {
              this.host.consoleLog(line);
            }
          };
          const emitStderr = (value) => {
            const line = String(value);
            if (typeof this.stderrHandler === "function") {
              this.stderrHandler(`${line}
`);
            } else if (typeof console !== "undefined" && typeof console.warn === "function") {
              console.warn(line);
            }
          };
          installHostCollectionMethods();
          const ZuzuException = class Exception extends Error {
            constructor(value = "") {
              if (isPairListLike(value)) {
                super(value.get("message", ""));
                this.name = "Exception";
                this.file = value.get("file", null);
                this.line = value.get("line", null);
                this.code = value.get("code", null);
                return;
              }
              if (value && typeof value === "object" && !Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "message")) {
                super(value.message);
                this.name = "Exception";
                this.file = Object.prototype.hasOwnProperty.call(value, "file") ? value.file : null;
                this.line = Object.prototype.hasOwnProperty.call(value, "line") ? value.line : null;
                this.code = Object.prototype.hasOwnProperty.call(value, "code") ? value.code : null;
                return;
              }
              super(value);
              this.name = "Exception";
              this.file = null;
              this.line = null;
              this.code = null;
            }
            to_String() {
              const name2 = this.name || this.constructor.name || "Exception";
              const message = String(this.message ?? "");
              if (message === name2 || message.startsWith(`${name2}:`)) {
                return message;
              }
              return message === "" ? name2 : `${name2}: ${message}`;
            }
            message() {
              return String(this.message ?? "");
            }
          };
          const ZuzuTypeException = class TypeException extends ZuzuException {
            constructor(value = "") {
              super(value);
              this.name = "TypeException";
            }
          };
          const snapshotSpreadArg = (input) => {
            const value = resolveWeakValue(input);
            if (Array.isArray(value)) {
              return {
                type: "spread_positional",
                values: value.slice()
              };
            }
            if (isPairListLike(value)) {
              return {
                type: "spread_named",
                entries: value.list.map((pair) => [pair[0], pair[1]])
              };
            }
            if (zuzuTypeof(value) === "Dict") {
              return {
                type: "spread_named",
                entries: Object.keys(value).sort().map((key) => [key, value[key]])
              };
            }
            throw new ZuzuTypeException(
              `argument spread expects Array, Dict, or PairList, got ${zuzuTypeof(value)}`
            );
          };
          const unpackDeclarationSource = (input) => {
            const value = resolveWeakValue(input);
            if (isPairListLike(value) || zuzuTypeof(value) === "Dict") {
              return value;
            }
            throw new ZuzuTypeException(
              `Declaration unpacking expects Dict or PairList, got ${zuzuTypeof(value)}`
            );
          };
          const unpackDeclarationValue = (source, key, defaultThunk, name2, typeName2, isWeakStorage) => {
            const valueSource = unpackDeclarationSource(source);
            const normalized = normalizeDictKey(key);
            let value;
            let found = false;
            if (isPairListLike(valueSource)) {
              const pair = valueSource.list.find(
                (entry) => entry[0] === normalized
              );
              if (pair) {
                value = pair[1];
                found = true;
              }
            } else if (Object.prototype.hasOwnProperty.call(valueSource, normalized)) {
              value = valueSource[normalized];
              found = true;
            }
            if (!found) {
              value = typeof defaultThunk === "function" ? defaultThunk() : null;
            }
            if (typeName2 && typeName2 !== "Any" && !zuzuTypeMatches(value, typeName2)) {
              throw new ZuzuTypeException(
                `'${name2}' must be ${typeName2}, got ${zuzuTypeof(value)}`
              );
            }
            return isWeakStorage ? makeWeakValue(value) : retainValue(value);
          };
          const spreadCallArgs = (parts) => {
            const positional = [];
            const named = [];
            for (const part of parts) {
              if (part.type === "positional") {
                positional.push(part.value);
                continue;
              }
              if (part.type === "named") {
                named.push(part.value);
                continue;
              }
              if (part.type === "spread_positional") {
                positional.push(...part.values);
                continue;
              }
              if (part.type === "spread_named") {
                for (const entry of part.entries) {
                  named.push(entry);
                }
                continue;
              }
              throw new ZuzuTypeException("invalid call argument descriptor");
            }
            if (named.length > 0) {
              positional.push(makeTemporaryPairList(named));
            }
            return positional;
          };
          const normalizeZuzuException = (err) => {
            if (err instanceof ZuzuException) {
              return err;
            }
            if (err && err.__zuzu_nonlocal_return) {
              return err;
            }
            if (err instanceof Error && [
              "CancelledException",
              "TimeoutException",
              "ChannelClosedException"
            ].includes(err.name)) {
              return err;
            }
            if (err && typeof err === "object") {
              const ctorName = err.constructor && err.constructor.name;
              if (!isNativeErrorConstructorName(ctorName)) {
                return err;
              }
            }
            const message = err && err.message != null ? String(err.message) : String(err);
            if (message.startsWith("TypeException:")) {
              return new ZuzuTypeException({
                message,
                file: err && err.file != null ? err.file : null,
                line: err && err.line != null ? err.line : null,
                code: err && err.code != null ? err.code : null
              });
            }
            return new ZuzuException({
              message: message.startsWith("Exception: ") ? message.slice("Exception: ".length) : message,
              file: err && err.file != null ? err.file : null,
              line: err && err.line != null ? err.line : null,
              code: err && err.code != null ? err.code : null
            });
          };
          const ZuzuExhaustedException = class ExhaustedException extends Error {
            constructor(message = "") {
              super(message);
              this.name = "ExhaustedException";
            }
            to_String() {
              const message = String(this.message ?? "");
              if (message === this.name || message.startsWith(`${this.name}:`)) {
                return message;
              }
              return message === "" ? this.name : `${this.name}: ${message}`;
            }
          };
          const defineRuntimeMethod = (proto, name2, fn2) => {
            const desc = /* @__PURE__ */ Object.create(null);
            desc.value = fn2;
            desc.enumerable = false;
            Object.defineProperty(proto, name2, desc);
          };
          if (!Number.prototype.contains) {
            defineRuntimeMethod(Number.prototype, "contains", function _containsNumber(value) {
              return Number(this.valueOf()) === Number(value) ? 1 : 0;
            });
          }
          if (!Set.prototype.push) {
            defineRuntimeMethod(Set.prototype, "length", function _lengthSet() {
              return this.size;
            });
            defineRuntimeMethod(Set.prototype, "count", function _countSet() {
              return this.size;
            });
            defineRuntimeMethod(Set.prototype, "empty", function _emptySet() {
              return this.size === 0 ? 1 : 0;
            });
            defineRuntimeMethod(Set.prototype, "is_empty", function _isEmptySet() {
              return this.empty();
            });
            defineRuntimeMethod(Set.prototype, "push", function _pushSet(...values) {
              for (const v of values) {
                addSetValue(this, v);
              }
              return this;
            });
            defineRuntimeMethod(Set.prototype, "contains", function _containsSet(value) {
              return contains(this, value);
            });
            defineRuntimeMethod(Set.prototype, "remove", function _removeSet(value) {
              const resolved = resolveWeakValue(value);
              if (this.delete(resolved)) {
                releaseCollectionValue(this, resolved);
              }
              return this;
            });
            defineRuntimeMethod(Set.prototype, "to_Array", function _setToArray() {
              return makeArray(this);
            });
            defineRuntimeMethod(Set.prototype, "to_Bag", function _setToBag() {
              return makeBag([...this]);
            });
            defineRuntimeMethod(Set.prototype, "copy", function _setCopy() {
              return makeSet(this);
            });
            defineRuntimeMethod(Set.prototype, "union", function _setUnion(other) {
              return collectionUnion(this, other);
            });
            defineRuntimeMethod(Set.prototype, "intersection", function _setIntersection(other) {
              return collectionIntersection(this, other);
            });
            defineRuntimeMethod(Set.prototype, "difference", function _setDifference(other) {
              return collectionDifference(this, other);
            });
            defineRuntimeMethod(Set.prototype, "symmetric_difference", function _setSymmetricDifference(other) {
              return collectionDifference(this.union(other), this.intersection(other));
            });
            defineRuntimeMethod(Set.prototype, "is_subset", function _setIsSubset(other) {
              return collectionSubsetOf(this, other);
            });
            defineRuntimeMethod(Set.prototype, "is_superset", function _setIsSuperset(other) {
              return collectionSupersetOf(this, other);
            });
            defineRuntimeMethod(Set.prototype, "is_disjoint", function _setIsDisjoint(other) {
              return this.intersection(other).size === 0 ? 1 : 0;
            });
            defineRuntimeMethod(Set.prototype, "equals", function _setEquals(other) {
              return collectionEquivalentOf(this, other);
            });
            defineRuntimeMethod(Set.prototype, "sort", function _setSort(fn2) {
              return [...this].sort(fn2);
            });
            defineRuntimeMethod(Set.prototype, "sortstr", function _setSortstr() {
              return [...this].sort((a, b) => String(a).localeCompare(String(b)));
            });
            defineRuntimeMethod(Set.prototype, "sortnum", function _setSortnum() {
              return [...this].map((item) => Number(item)).sort((a, b) => a - b);
            });
            defineRuntimeMethod(Set.prototype, "map", function _setMap(fn2) {
              return new Set([...this].map(fn2));
            });
            defineRuntimeMethod(Set.prototype, "grep", function _setGrep(fn2) {
              return new Set([...this].filter(fn2));
            });
            defineRuntimeMethod(Set.prototype, "any", function _setAny(fn2) {
              return [...this].some(fn2) ? 1 : 0;
            });
            defineRuntimeMethod(Set.prototype, "all", function _setAll(fn2) {
              return [...this].every(fn2) ? 1 : 0;
            });
            defineRuntimeMethod(Set.prototype, "first", function _setFirst(fn2) {
              for (const v of this) {
                if (fn2(v)) {
                  return v;
                }
              }
              return null;
            });
            defineRuntimeMethod(Set.prototype, "remove_if", function _setRemoveIf(fn2) {
              for (const v of [...this]) {
                if (fn2(v)) {
                  releaseCollectionValue(this, v);
                  this.delete(v);
                }
              }
              return this;
            });
            defineRuntimeMethod(Set.prototype, "for_each_value", function _setForEachValue(fn2) {
              for (const v of this) {
                fn2(v);
              }
              return this;
            });
          }
          const fallbackDoneTesting = function done_testing(n = null) {
            if (typeof globalThis._LEVEL === "number" && globalThis._LEVEL > 0) {
              throw new Error("Unexpected done_testing() in subtest");
            }
            let seen = 0;
            if (Array.isArray(runtime.outputLines)) {
              for (const line of runtime.outputLines) {
                if (/^ok\b/.test(line) || /^not ok\b/.test(line)) {
                  seen++;
                }
              }
            }
            if (n != null && Number(n) !== Number(seen)) {
              throw new Error(`Expected ${n} tests, but ran ${seen}`);
            }
            emit(`1..${seen}`);
            if (typeof globalThis._FAILED === "number" && globalThis._FAILED > 0) {
              throw new Error(`Failed ${globalThis._FAILED} tests`);
            }
            return true;
          };
          const systemGlobalSeed = {
            language_version: 0,
            runtime: "zuzu-js",
            runtime_version: "dev",
            platform: this.host.name,
            inc: Object.freeze(moduleSearchRoots.slice()),
            deny_fs: capabilityFlags.fs ? false : true,
            deny_net: capabilityFlags.net ? false : true,
            deny_perl: true,
            deny_js: capabilityFlags.js ? false : true,
            deny_proc: capabilityFlags.proc ? false : true,
            deny_db: capabilityFlags.db ? false : true,
            deny_clib: capabilityFlags.clib ? false : true,
            deny_gui: capabilityFlags.gui ? false : true,
            deny_worker: capabilityFlags.worker ? false : true
          };
          if (this.host.name === "node" && typeof process !== "undefined" && process.versions) {
            systemGlobalSeed.nodejs_version = String(process.versions.node || "");
          }
          Object.freeze(systemGlobalSeed);
          const currentSystem = () => {
            const current = {
              ...systemGlobalSeed,
              deny_fs: this.isCapabilityDenied("fs") || !this.host.capabilities.has("fs"),
              deny_net: this.isCapabilityDenied("net") || !this.host.capabilities.has("net"),
              deny_perl: true,
              deny_js: this.isCapabilityDenied("js") || !this.host.capabilities.has("js"),
              deny_proc: this.isCapabilityDenied("proc") || !this.host.capabilities.has("proc"),
              deny_db: this.isCapabilityDenied("db") || !this.host.capabilities.has("db"),
              deny_clib: this.isCapabilityDenied("clib") || !this.host.capabilities.has("clib"),
              deny_gui: this.isCapabilityDenied("gui") || !this.host.capabilities.has("gui"),
              deny_worker: this.isCapabilityDenied("worker") || !this.host.capabilities.has("worker")
            };
            return Object.freeze(current);
          };
          context = {
            ...options.globals || {},
            __file__: this.fileValueForFilename(filename),
            __zuzu_system_seed: systemGlobalSeed,
            __zuzu_current_system: currentSystem,
            DEBUG: this.debugLevel,
            __zuzu_host_capabilities: capabilityFlags,
            has_capability(name2) {
              const key = String(name2);
              return capabilityFlags[key] ? 1 : 0;
            },
            outputLines: this.outputLines,
            done_testing: options.globals && typeof options.globals.done_testing === "function" ? options.globals.done_testing : fallbackDoneTesting,
            exports: options.exports,
            module: options.module,
            console: {
              log: (value) => this.host.consoleLog(value),
              warn: (value) => emitStderr(value),
              error: (value) => emitStderr(value)
            },
            Bag: ZuzuBag,
            PairList,
            Exception: ZuzuException,
            TypeException: ZuzuTypeException,
            ExhaustedException: ZuzuExhaustedException,
            __zuzu_normalize_exception: normalizeZuzuException,
            Task: taskRuntime2.Task,
            CancelledException: taskRuntime2.CancelledException,
            TimeoutException: taskRuntime2.TimeoutException,
            ChannelClosedException: taskRuntime2.ChannelClosedException,
            Null: null,
            Any: function Any() {
            },
            Collection: function Collection() {
            },
            Class: function Class() {
            },
            BinaryString: BinaryString2,
            say(value, ...parts) {
              if (Array.isArray(value) && Object.prototype.hasOwnProperty.call(value, "raw")) {
                let out = "";
                for (let i = 0; i < value.length; i++) {
                  out += value[i];
                  if (i < parts.length) {
                    out += String(parts[i]);
                  }
                }
                emit(out);
                return;
              }
              emit(value);
            },
            __zuzu_switch: runSwitch,
            __zuzu_switch_async: runSwitchAsync,
            __zuzu_match: runMatch,
            __zuzu_to_regexp: operatorRegexp,
            __zuzu_regex_replace: regexReplaceValue,
            __zuzu_contains: contains,
            __zuzu_union: collectionUnion,
            __zuzu_intersection: collectionIntersection,
            __zuzu_difference: collectionDifference,
            __zuzu_default: defaultOperator,
            __zuzu_subsetof: collectionSubsetOf,
            __zuzu_supersetof: collectionSupersetOf,
            __zuzu_equivalentof: collectionEquivalentOf,
            __zuzu_array: makeArray,
            __zuzu_set: makeSet,
            __zuzu_bag: makeBag,
            __zuzu_pairlist_literal: makePairList,
            __zuzu_temp_pairlist: makeTemporaryPairList,
            __zuzu_snapshot_spread_arg: snapshotSpreadArg,
            __zuzu_spread_call_args: spreadCallArgs,
            __zuzu_unpack_source: unpackDeclarationSource,
            __zuzu_unpack_value: unpackDeclarationValue,
            __zuzu_release_collection_values: releaseCollectionValues,
            __zuzu_path_op: makePathOperator(runtime, filename),
            __zuzu_path_assign: makePathAssignmentOperator(runtime, filename),
            __zuzu_path_ref: makePathReferenceOperator(runtime, filename),
            __zuzu_path_update: makePathUpdateOperator(runtime, filename),
            __zuzu_call_member: zuzuCallMember,
            __zuzu_is_weakable_value: isWeakableValue,
            __zuzu_is_pairlist: isPairListLike,
            __zuzu_make_weak_value: makeWeakValue,
            __zuzu_resolve_weak_value: resolveWeakValue,
            __zuzu_retain_value: retainValue,
            __zuzu_release_value: releaseValue,
            __zuzu_retain_collection_value: retainCollectionValue,
            __zuzu_release_collection_value: releaseCollectionValue,
            __zuzu_add_set_value: addSetValue,
            __zuzu_assign_strong: assignStrongValue,
            __zuzu_assign_weak: assignWeakValue,
            __zuzu_assign_index: assignIndexedValue,
            __zuzu_bodyless_function(name2) {
              let target = null;
              const fn2 = function __zuzu_bodyless_function_wrapper(...args) {
                if (typeof target === "function") {
                  return target.apply(this, args);
                }
                throw new Error(`Exception: Function '${name2}' has no body`);
              };
              Object.defineProperty(fn2, "__zuzu_complete_body", {
                value(completed) {
                  target = completed;
                  return fn2;
                },
                enumerable: false,
                configurable: true
              });
              return fn2;
            },
            __zuzu_complete_function(current, completed, meta) {
              const value = completed;
              if (value && (typeof value === "function" || typeof value === "object")) {
                Object.defineProperty(value, "__zuzu_marshal_meta", {
                  value: meta || {},
                  enumerable: false,
                  configurable: true,
                  writable: true
                });
              }
              if (current && typeof current.__zuzu_complete_body === "function") {
                return current.__zuzu_complete_body(value);
              }
              throw new Error("Exception: function predeclaration target is not bodyless");
            },
            __zuzu_with_marshal_meta(value, meta) {
              if (value && (typeof value === "function" || typeof value === "object")) {
                Object.defineProperty(value, "__zuzu_marshal_meta", {
                  value: meta || {},
                  enumerable: false,
                  configurable: true,
                  writable: true
                });
              }
              return value;
            },
            __zuzu_await_value(value) {
              return taskRuntime2.awaitValue(value);
            },
            __zuzu_await_block(value) {
              return taskRuntime2.awaitBlock(value);
            },
            __zuzu_callsite(metadata, fn2) {
              return taskRuntime2.withCallsite(
                {
                  file: filename,
                  ...metadata || {}
                },
                fn2
              );
            },
            __zuzu_task(fn2, metadata) {
              return taskRuntime2.task(fn2, {
                file: filename,
                ...metadata || {}
              });
            },
            __zuzu_task_sync(fn2, metadata) {
              return taskRuntime2.taskSync(fn2, {
                file: filename,
                ...metadata || {}
              });
            },
            __zuzu_spawn(fn2, metadata) {
              return taskRuntime2.spawn(fn2, {
                file: filename,
                ...metadata || {}
              });
            },
            async __zuzu_collection_map_async(collection, fn2) {
              const out = [];
              for (const item of collection || []) {
                out.push(await taskRuntime2.awaitValue(fn2(item)));
              }
              return out;
            },
            async __zuzu_collection_grep_async(collection, fn2) {
              const out = [];
              for (const item of collection || []) {
                if (zuzuTruthy(await taskRuntime2.awaitValue(fn2(item)))) {
                  out.push(item);
                }
              }
              return out;
            },
            async __zuzu_collection_reduce_async(collection, fn2) {
              const items = Array.from(collection || []);
              if (items.length === 0) {
                return null;
              }
              let acc = items[0];
              for (let i = 1; i < items.length; i++) {
                acc = await taskRuntime2.awaitValue(fn2(acc, items[i]));
              }
              return acc;
            },
            __zuzu_prepare_eval(source, namedArgs = null) {
              if (typeof source !== "string") {
                throw new ZuzuTypeException(
                  `TypeException: eval expects String, got ${zuzuTypeof(source)}`
                );
              }
              if (namedArgs != null && !isPairListLike(namedArgs)) {
                throw new ZuzuTypeException(
                  `TypeException: eval named arguments must be PairList, got ${zuzuTypeof(namedArgs)}`
                );
              }
              let compiled;
              try {
                compiled = runtime.transpile(source, { syncEval: true });
              } catch (err) {
                const line = err && err.token && err.token.line != null ? err.token.line : 1;
                throw new ZuzuException({
                  message: err && err.message ? String(err.message) : String(err),
                  file: "<std/eval>",
                  line,
                  code: "E_COMPILE_SYNTAX"
                });
              }
              if (namedArgs == null) {
                return compiled;
              }
              const overrides = /* @__PURE__ */ Object.create(null);
              const accepted = /* @__PURE__ */ new Set([
                "deny_fs",
                "deny_net",
                "deny_perl",
                "deny_js",
                "deny_proc",
                "deny_db",
                "deny_clib",
                "deny_gui",
                "deny_worker"
              ]);
              for (const optName of namedArgs.keys()) {
                if (!accepted.has(optName)) {
                  throw new ZuzuException(
                    `Unknown named argument '${optName}' for eval`
                  );
                }
              }
              for (const [optName, flagName] of [
                ["deny_fs", "deny_fs"],
                ["deny_net", "deny_net"],
                ["deny_perl", "deny_perl"],
                ["deny_js", "deny_js"],
                ["deny_proc", "deny_proc"],
                ["deny_db", "deny_db"],
                ["deny_clib", "deny_clib"],
                ["deny_gui", "deny_gui"],
                ["deny_worker", "deny_worker"]
              ]) {
                if (namedArgs.has(optName) && zuzuTruthy(namedArgs.get(optName))) {
                  overrides[flagName] = true;
                }
              }
              if (Object.keys(overrides).length === 0) {
                return compiled;
              }
              return [
                "( () => {",
                `const __zuzu_eval_prev_caps = __zuzu_push_eval_capability_overrides( ${JSON.stringify(overrides)} );`,
                "try {",
                "return ( () => {",
                "const __system__ = __zuzu_current_system();",
                `return ${compiled};`,
                "} )();",
                "} finally {",
                "__zuzu_pop_eval_capability_overrides( __zuzu_eval_prev_caps );",
                "}",
                "} )()"
              ].join("\n");
            },
            __zuzu_prepare_eval_call_args(args) {
              let source = "";
              let namedArgs = null;
              if (args.length > 0) {
                if (isPairListLike(args[args.length - 1])) {
                  namedArgs = args[args.length - 1];
                  if (args.length > 1) {
                    source = args[0];
                  }
                } else {
                  source = args[0];
                }
              }
              return context.__zuzu_prepare_eval(source, namedArgs);
            },
            __zuzu_await_block_sync(value) {
              return taskRuntime2.awaitBlockSync(value);
            },
            __zuzu_iter(value) {
              const asIterable = (input) => {
                const hasMethodHere = (candidate, name2) => {
                  if (candidate == null) {
                    return false;
                  }
                  if (Object.prototype.hasOwnProperty.call(candidate, name2)) {
                    return true;
                  }
                  const proto = Object.getPrototypeOf(candidate);
                  if (!proto) {
                    return false;
                  }
                  return Object.prototype.hasOwnProperty.call(proto, name2);
                };
                if (input == null) {
                  return [];
                }
                if (typeof input[Symbol.iterator] === "function") {
                  return input;
                }
                if (typeof input === "function") {
                  return {
                    *[Symbol.iterator]() {
                      while (true) {
                        try {
                          yield input();
                        } catch (err) {
                          if (isExhaustedIteratorError(err)) {
                            return;
                          }
                          throw err;
                        }
                      }
                    }
                  };
                }
                if (input && typeof input.to_Iterator === "function" && hasMethodHere(input, "to_Iterator")) {
                  const iterator = input.to_Iterator();
                  if (typeof iterator === "function" && input && typeof input === "object") {
                    return asIterable(iterator.bind(input));
                  }
                  return asIterable(iterator);
                }
                if (input && typeof input.to_Array === "function" && hasMethodHere(input, "to_Array")) {
                  return asIterable(input.to_Array());
                }
                if (isPlainObjectLike(input) && typeof input.to_Iterator === "function") {
                  return asIterable(input.to_Iterator());
                }
                if (isPlainObjectLike(input) && typeof input.to_Array === "function") {
                  return asIterable(input.to_Array());
                }
                if (input && typeof input === "object") {
                  return Object.keys(input).sort();
                }
                return [];
              };
              return asIterable(value);
            },
            __zuzu_length: operatorLength,
            __zuzu_num(value) {
              return zuzuToNumber(value);
            },
            __zuzu_truthy(value) {
              return zuzuTruthy(value);
            },
            __zuzu_not(value) {
              return zuzuTruthy(value) ? 0 : 1;
            },
            __zuzu_and(left, right) {
              return zuzuTruthy(left) && zuzuTruthy(right) ? 1 : 0;
            },
            __zuzu_or(left, right) {
              return zuzuTruthy(left) || zuzuTruthy(right) ? 1 : 0;
            },
            __zuzu_typeof(value) {
              return zuzuTypeof(value);
            },
            __zuzu_instanceof(value, klass) {
              return zuzuInstanceof(value, klass);
            },
            __zuzu_trait(name2, methods, source = null, captures = {}) {
              return zuzuTrait(name2, methods, source, captures);
            },
            __zuzu_apply_traits(klass, traits) {
              return zuzuApplyTraits(klass, traits);
            },
            __zuzu_class_with_traits(klass, traits) {
              return zuzuClassWithTraits(klass, traits);
            },
            __zuzu_does(value, trait) {
              return zuzuDoes(value, trait);
            },
            __zuzu_can(value, methodName) {
              return zuzuCan(value, methodName);
            },
            __zuzu_super_call(self, klass, methodName, args) {
              return zuzuSuperCall(self, klass, methodName, args);
            },
            __zuzu_super_static_call(klass, methodName, args) {
              return zuzuSuperStaticCall(klass, methodName, args);
            },
            __zuzu_super_dispatch(isStatic, self, klass, methodName, args) {
              return zuzuSuperDispatch(isStatic, self, klass, methodName, args);
            },
            __zuzu_type_matches(value, typeName2) {
              return zuzuTypeMatches(value, typeName2);
            },
            __zuzu_require_type(argName, typeName2, value) {
              if (!zuzuTypeMatches(value, typeName2)) {
                throw new Error(`TypeException: argument '${argName}' must be ${typeName2}, got ${zuzuTypeof(value)}`);
              }
              return value;
            },
            __zuzu_checked_declaration(name2, typeName2, value) {
              if (typeName2 !== "Any" && !zuzuTypeMatches(value, typeName2)) {
                throw new Error(`TypeException: '${name2}' must be ${typeName2}, got ${zuzuTypeof(value)}`);
              }
              return value;
            },
            __zuzu_checked_return(fnName, typeName2, value) {
              if (typeName2 !== "Any" && !zuzuTypeMatches(value, typeName2)) {
                throw new Error(`TypeException: 'return value of '${fnName}'' must be ${typeName2}, got ${zuzuTypeof(value)}`);
              }
              return value;
            },
            __zuzu_die(value) {
              if (typeof value === "string") {
                throw new ZuzuException(value);
              }
              throw value;
            },
            __zuzu_throw(value, line) {
              const err = value instanceof Error || value && typeof value === "object" ? value : new ZuzuException(value);
              if (err.file == null) {
                err.file = filename;
              }
              if (err.line == null) {
                err.line = Number(line || 0);
              }
              throw err;
            },
            __zuzu_add(left, right) {
              return zuzuToNumber(left) + zuzuToNumber(right);
            },
            __zuzu_concat(left, right) {
              return concatValue(left, right);
            },
            __zuzu_binary_literal(value) {
              return binaryFromLiteral(value);
            },
            to_binary(value) {
              return toBinaryValue(value);
            },
            to_string(value) {
              return toStringValue(value);
            },
            is_ascii(value) {
              if (!(value instanceof ZuzuBinary)) {
                throw new Error(`TypeException: expected BinaryString for is_ascii, got ${zuzuTypeof(value)}`);
              }
              return value.isAscii();
            },
            __zuzu_bit_and(left, right) {
              return bitwiseAnd(left, right);
            },
            __zuzu_bit_or(left, right) {
              return bitwiseOr(left, right);
            },
            __zuzu_bit_xor(left, right) {
              return bitwiseXor(left, right);
            },
            __zuzu_bit_not(value) {
              return bitwiseNot(value);
            },
            __zuzu_sub(left, right) {
              return zuzuToNumber(left) - zuzuToNumber(right);
            },
            __zuzu_mul(left, right) {
              return zuzuToNumber(left) * zuzuToNumber(right);
            },
            __zuzu_div(left, right) {
              return zuzuToNumber(left) / zuzuToNumber(right);
            },
            __zuzu_mod(left, right) {
              return zuzuToNumber(left) % zuzuToNumber(right);
            },
            __zuzu_pow(left, right) {
              return zuzuToNumber(left) ** zuzuToNumber(right);
            },
            __zuzu_cmp(left, right) {
              const l = zuzuToNumber(left);
              const r = zuzuToNumber(right);
              return l < r ? -1 : l > r ? 1 : 0;
            },
            __zuzu_eq(left, right) {
              if (arguments.length < 2) {
                return 0;
              }
              return zuzuEqual(left, right);
            },
            __zuzu_ne(left, right) {
              if (arguments.length < 2) {
                return 0;
              }
              return zuzuEqual(left, right) ? 0 : 1;
            },
            __zuzu_str_eq(left, right) {
              return stringCompare(left, right) === 0 ? 1 : 0;
            },
            __zuzu_str_ne(left, right) {
              return stringCompare(left, right) !== 0 ? 1 : 0;
            },
            __zuzu_str_gt(left, right) {
              return stringCompare(left, right) > 0 ? 1 : 0;
            },
            __zuzu_str_ge(left, right) {
              return stringCompare(left, right) >= 0 ? 1 : 0;
            },
            __zuzu_str_lt(left, right) {
              return stringCompare(left, right) < 0 ? 1 : 0;
            },
            __zuzu_str_le(left, right) {
              return stringCompare(left, right) <= 0 ? 1 : 0;
            },
            __zuzu_str_cmp(left, right) {
              return stringCompare(left, right);
            },
            __zuzu_str_eqi(left, right) {
              return stringCompare(left, right, { insensitive: true }) === 0 ? 1 : 0;
            },
            __zuzu_str_nei(left, right) {
              return stringCompare(left, right, { insensitive: true }) !== 0 ? 1 : 0;
            },
            __zuzu_str_gti(left, right) {
              return stringCompare(left, right, { insensitive: true }) > 0 ? 1 : 0;
            },
            __zuzu_str_gei(left, right) {
              return stringCompare(left, right, { insensitive: true }) >= 0 ? 1 : 0;
            },
            __zuzu_str_lti(left, right) {
              return stringCompare(left, right, { insensitive: true }) < 0 ? 1 : 0;
            },
            __zuzu_str_lei(left, right) {
              return stringCompare(left, right, { insensitive: true }) <= 0 ? 1 : 0;
            },
            __zuzu_str_cmpi(left, right) {
              return stringCompare(left, right, { insensitive: true });
            },
            __zuzu_warn(...parts) {
              emitStderr(parts.map((part) => zuzuStringify(part)).join(""));
            },
            __zuzu_debug(levelThunk, messageThunk) {
              const level = typeof levelThunk === "function" ? levelThunk() : levelThunk;
              if (Number(level || 0) > runtime.debugLevel) {
                return null;
              }
              const message = typeof messageThunk === "function" ? messageThunk() : messageThunk;
              emitStderr(zuzuStringify(message ?? ""));
              return null;
            },
            __zuzu_assert(conditionThunk) {
              if (runtime.debugLevel <= 0) {
                return null;
              }
              const condition = typeof conditionThunk === "function" ? conditionThunk() : conditionThunk;
              if (!condition) {
                throw new Error("Assertion failed");
              }
              return condition;
            },
            __zuzu_make_class(name2, base) {
              const parent = typeof base === "function" ? base : Object;
              return {
                [name2]: class extends parent {
                  constructor(...args) {
                    if (args.length === 1 && args[0] && typeof args[0] === "object" && !Array.isArray(args[0]) && Object.prototype.hasOwnProperty.call(args[0], "message")) {
                      super(args[0].message);
                      if (this instanceof Error) {
                        this.name = name2;
                      }
                      return;
                    }
                    super(...args);
                    if (this instanceof Error) {
                      this.name = name2;
                    }
                  }
                }
              }[name2];
            },
            __zuzu_define_class(name2, base, spec) {
              return defineZuzuClass(name2, base, spec);
            },
            __zuzu_get_member(object, property) {
              return zuzuGetMember(object, property);
            },
            __zuzu_get_index(object, index) {
              return zuzuGetIndex(object, index);
            },
            __zuzu_get_brace_member(object, literalProperty, getDynamicProperty) {
              return zuzuGetBraceMember(object, literalProperty, getDynamicProperty);
            },
            __zuzu_resolve_brace_key(object, literalProperty, getDynamicProperty) {
              return zuzuResolveBraceKey(object, literalProperty, getDynamicProperty);
            },
            __zuzu_maybe_demolish(value) {
              return zuzuMaybeDemolish(value);
            },
            __zuzu_xor(left, right) {
              return zuzuTruthy(left) !== zuzuTruthy(right) ? 1 : 0;
            },
            __zuzu_nand(left, right) {
              return zuzuTruthy(left) && zuzuTruthy(right) ? 0 : 1;
            },
            __zuzu_num_eq(left, right) {
              if (!isNumericComparable(left) || !isNumericComparable(right)) {
                return zuzuEqual(left, right);
              }
              return numericEqual(left, right) ? 1 : 0;
            },
            __zuzu_num_ne(left, right) {
              if (!isNumericComparable(left) || !isNumericComparable(right)) {
                return zuzuEqual(left, right) ? 0 : 1;
              }
              return numericEqual(left, right) ? 0 : 1;
            },
            __zuzu_num_lt(left, right) {
              return zuzuToNumber(left) < zuzuToNumber(right) ? 1 : 0;
            },
            __zuzu_num_lte(left, right) {
              return zuzuToNumber(left) <= zuzuToNumber(right) ? 1 : 0;
            },
            __zuzu_num_gt(left, right) {
              return zuzuToNumber(left) > zuzuToNumber(right) ? 1 : 0;
            },
            __zuzu_num_gte(left, right) {
              return zuzuToNumber(left) >= zuzuToNumber(right) ? 1 : 0;
            },
            __zuzu_abs(value) {
              return Math.abs(zuzuToNumber(value));
            },
            __zuzu_sqrt(value) {
              return Math.sqrt(zuzuToNumber(value));
            },
            __zuzu_floor(value) {
              return Math.floor(zuzuToNumber(value));
            },
            __zuzu_ceil(value) {
              return Math.ceil(zuzuToNumber(value));
            },
            __zuzu_round(value) {
              const n = zuzuToNumber(value);
              return n >= 0 ? Math.floor(n + 0.5) : Math.ceil(n - 0.5);
            },
            __zuzu_int(value) {
              const n = zuzuToNumber(value);
              return n < 0 ? Math.ceil(n) : Math.floor(n);
            },
            __zuzu_uc(value) {
              if (value instanceof ZuzuBinary) {
                throw new Error("TypeException: uc expects String, got BinaryString");
              }
              return zuzuOperatorString(value).toUpperCase();
            },
            __zuzu_lc(value) {
              if (value instanceof ZuzuBinary) {
                throw new Error("TypeException: lc expects String, got BinaryString");
              }
              return zuzuOperatorString(value).toLowerCase();
            },
            __zuzu_range(start, end) {
              const from = zuzuToNumber(start);
              const to = zuzuToNumber(end);
              const out = [];
              const step = from <= to ? 1 : -1;
              for (let n = from; step > 0 ? n <= to : n >= to; n += step) {
                out.push(n);
              }
              return out;
            },
            __zuzu_ref_index(target, index) {
              return refIndex(target, index);
            },
            __zuzu_ref_key(target, key) {
              return refKey(target, key);
            },
            __zuzu_get_slice(target, from, length) {
              return zuzuGetSlice(target, from, length);
            },
            __zuzu_ref_slice(target, from, length) {
              return refSlice(target, from, length);
            },
            __zuzu_assign_slice(target, from, length, value) {
              return zuzuAssignSlice(target, from, length, value);
            },
            Pair
          };
          if (this.host.name === "browser") {
            context.Object = createObjectFacade();
          }
          context.__zuzu_push_eval_capability_overrides = (overrides = {}) => {
            const previous = this.evalCapabilityOverrides;
            const next = { ...previous || {} };
            for (const [key, value] of Object.entries(overrides || {})) {
              if (value) {
                next[key] = true;
              }
            }
            this.evalCapabilityOverrides = Object.keys(next).length > 0 ? next : null;
            return previous;
          };
          context.__zuzu_pop_eval_capability_overrides = (previous) => {
            this.evalCapabilityOverrides = previous || null;
          };
          context.__zuzu_import = (name2) => {
            if (name2 === "std/eval") {
              return { eval: context.__zuzu_native_eval };
            }
            return this.loadModule(name2, filename, context);
          };
          return context;
        }
        installCollectionMethods(context) {
          const bootstrap = `
			(function () {
				globalThis.__zuzu_native_eval = eval;
				globalThis.__zuzu_builtin_Array = Array;
				globalThis.__zuzu_builtin_Function = Function;
				globalThis.__zuzu_builtin_Object = Object;
				globalThis.__zuzu_builtin_RegExp = RegExp;
				globalThis.__zuzu_builtin_Set = Set;
				globalThis.Dict = function Dict( value ) {
					if ( value && typeof value === 'object' && !Array.isArray( value ) ) {
						return Object.assign( {}, value );
					}
					return {};
				};
				if ( !globalThis.__zuzu_define_property_patched ) {
					const __zuzu_native_define_property = Object.defineProperty;
					const __zuzu_native_define_properties = Object.defineProperties;
					const __zuzu_safe_descriptor = function ( descriptor ) {
						if ( !descriptor || typeof descriptor !== 'object' ) {
							return descriptor;
						}
						const safe = Object.create( null );
						for ( const key of [ 'value', 'get', 'set', 'writable', 'enumerable', 'configurable' ] ) {
							if ( Object.prototype.hasOwnProperty.call( descriptor, key ) ) {
								safe[key] = descriptor[key];
							}
						}
						return safe;
					};
					Object.defineProperty = function __zuzu_define_property( obj, prop, descriptor ) {
						return __zuzu_native_define_property(
							obj,
							prop,
							__zuzu_safe_descriptor( descriptor )
						);
					};
					Object.defineProperties = function __zuzu_define_properties( obj, descriptors ) {
						const safeDescriptors = Object.create( null );
						for ( const key of Object.keys( descriptors || {} ) ) {
							safeDescriptors[key] = __zuzu_safe_descriptor( descriptors[key] );
						}
						return __zuzu_native_define_properties( obj, safeDescriptors );
					};
					globalThis.__zuzu_define_property_patched = true;
				}
				const __zuzu_seed = globalThis.__zuzu_system_seed || Object.create( null );
				const __zuzu_system_desc = Object.create( null );
				__zuzu_system_desc.get = function __zuzu_get_system() {
					if ( typeof globalThis.__zuzu_current_system === 'function' ) {
						return globalThis.__zuzu_current_system();
					}
					return Object.freeze( Object.assign( {}, __zuzu_seed ) );
				};
				__zuzu_system_desc.enumerable = true;
				__zuzu_system_desc.configurable = true;
				Object.defineProperty(
					globalThis,
					'__system__',
					__zuzu_system_desc
				);
				delete globalThis.__zuzu_system_seed;
				const define = ( proto, name, fn ) => {
					if ( !Object.prototype.hasOwnProperty.call( proto, name ) ) {
						const desc = Object.create( null );
						desc.value = fn;
						desc.enumerable = false;
						desc.configurable = true;
						desc.writable = true;
						Object.defineProperty( proto, name, desc );
					}
				};
				define( Array.prototype, 'length', function _length() { return this.length; } );
				define( Array.prototype, 'count', function _count() { return this.length; } );
				define( Array.prototype, 'empty', function _empty() { return this.length === 0 ? 1 : 0; } );
				define( Array.prototype, 'is_empty', function _is_empty() { return this.empty(); } );
				define( Array.prototype, 'append', function _append( ...values ) { this.push( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
				define( Array.prototype, 'add', function _add( ...values ) { this.push( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
				define( Array.prototype, 'prepend', function _prepend( ...values ) { this.unshift( ...values.map( ( value ) => __zuzu_retain_collection_value( this, value ) ) ); return this; } );
				define( Array.prototype, 'push_weak', function _push_weak( ...values ) { this.push( ...values.map( __zuzu_make_weak_value ) ); return this; } );
				define( Array.prototype, 'unshift_weak', function _unshift_weak( ...values ) { this.unshift( ...values.map( __zuzu_make_weak_value ) ); return this; } );
				define( Array.prototype, 'get', function _get( idx, fallback = null ) { return idx >= 0 && idx < this.length ? this[idx] : fallback; } );
				define( Array.prototype, 'set', function _set( idx, value ) { __zuzu_release_collection_value( this, this[idx] ); this[idx] = __zuzu_retain_collection_value( this, value ); return this; } );
				define( Array.prototype, 'set_weak', function _set_weak( idx, value ) { __zuzu_release_collection_value( this, this[idx] ); this[idx] = __zuzu_make_weak_value( value ); return this; } );
				define( Array.prototype, 'grep', function _grep( fn ) { return this.filter( fn ); } );
				define( Array.prototype, 'any', function _any( fn ) { return this.some( fn ) ? 1 : 0; } );
				define( Array.prototype, 'all', function _all( fn ) { return this.every( fn ) ? 1 : 0; } );
				define( Array.prototype, 'first', function _first( fn ) { return this.find( fn ) ?? null; } );
				define( Array.prototype, 'remove', function _remove( fn ) { for ( let i = this.length - 1; i >= 0; i-- ) { if ( fn( this[i] ) ) { __zuzu_release_collection_value( this, this[i] ); this.splice( i, 1 ); } } return this; } );
				define( Array.prototype, 'contains', function _contains( value ) { return this.includes( value ) ? 1 : 0; } );
				define( Array.prototype, 'first_index', function _first_index( fn ) { return this.findIndex( fn ); } );
				define( Array.prototype, 'reductions', function _reductions( fn ) { const out = []; for ( const item of this ) { out.push( out.length === 0 ? item : fn( out[out.length - 1], item ) ); } return out; } );
				define( Array.prototype, 'head', function _head( n ) { return this.slice( 0, n ); } );
				define( Array.prototype, 'tail', function _tail( n ) { return this.slice( n - 1 ); } );
				define( Array.prototype, 'sum', function _sum() { return this.reduce( (a, b) => Number( a ) + Number( b ), 0 ); } );
				define( Array.prototype, 'product', function _product() { return this.reduce( (a, b) => Number( a ) * Number( b ), 1 ); } );
				define( Array.prototype, 'shuffle', function _shuffle() { return this.slice(); } );
				define( Array.prototype, 'sample', function _sample( n ) { return this.slice( 0, n ); } );
				define( Array.prototype, 'for_each_value', function _for_each_value( fn ) { this.forEach( fn ); return this; } );
				define( Array.prototype, 'sortstr', function _sortstr() { return this.slice().sort( (a, b) => String( a ).localeCompare( String( b ) ) ); } );
				define( Array.prototype, 'sortnum', function _sortnum() { return this.map( (item) => Number( item ) ).sort( (a, b) => a - b ); } );
				define( Array.prototype, 'to_Array', function _to_array() { return __zuzu_array( this ); } );
				define( Array.prototype, 'to_Set', function _to_set() { return __zuzu_set( this ); } );
				define( Array.prototype, 'to_Bag', function _to_bag() { return new Bag( this ); } );
				define( Array.prototype, 'to_Iterator', function _to_iterator() { return this[Symbol.iterator](); } );
				define( Array.prototype, 'copy', function _copy() { return __zuzu_array( this ); } );
				define( Array.prototype, 'clear', function _clear() { __zuzu_release_collection_values( this ); this.splice( 0, this.length ); return this; } );

				define( Set.prototype, 'length', function _length() { return this.size; } );
				define( Set.prototype, 'count', function _count() { return this.size; } );
				define( Set.prototype, 'empty', function _empty() { return this.size === 0 ? 1 : 0; } );
				define( Set.prototype, 'is_empty', function _is_empty() { return this.empty(); } );
				define( Set.prototype, 'push', function _push( ...values ) { for ( const v of values ) { __zuzu_add_set_value( this, v ); } return this; } );
				define( Set.prototype, 'add_weak', function _add_weak( value ) { this.add( __zuzu_make_weak_value( value ) ); return this; } );
				define( Set.prototype, 'contains', function _contains( value ) { return __zuzu_contains( this, value ); } );
				define( Set.prototype, 'remove', function _remove( value ) { const resolved = __zuzu_resolve_weak_value( value ); if ( this.delete( resolved ) ) { __zuzu_release_collection_value( this, resolved ); } return this; } );
				define( Set.prototype, 'to_Array', function _to_array() { return __zuzu_array( this ); } );
				define( Set.prototype, 'to_Bag', function _to_bag() { return __zuzu_bag( [ ...this ] ); } );
				define( Set.prototype, 'to_Iterator', function _to_iterator() { return this.values(); } );
				define( Set.prototype, 'copy', function _copy() { return __zuzu_set( this ); } );
				define( Set.prototype, 'union', function _union( other ) { return __zuzu_union( this, other ); } );
				define( Set.prototype, 'intersection', function _intersection( other ) { return __zuzu_intersection( this, other ); } );
				define( Set.prototype, 'difference', function _difference( other ) { return __zuzu_difference( this, other ); } );
				define( Set.prototype, 'symmetric_difference', function _symmetric_difference( other ) { return __zuzu_difference( this.union( other ), this.intersection( other ) ); } );
				define( Set.prototype, 'is_subset', function _is_subset( other ) { return __zuzu_subsetof( this, other ); } );
				define( Set.prototype, 'is_superset', function _is_superset( other ) { return __zuzu_supersetof( this, other ); } );
				define( Set.prototype, 'is_disjoint', function _is_disjoint( other ) { return this.intersection( other ).size === 0 ? 1 : 0; } );
				define( Set.prototype, 'equals', function _equals( other ) { return __zuzu_equivalentof( this, other ); } );
				define( Set.prototype, 'sort', function _sort( fn ) { return [ ...this ].sort( fn ); } );
				define( Set.prototype, 'sortstr', function _sortstr() { return [ ...this ].sort( (a, b) => String( a ).localeCompare( String( b ) ) ); } );
				define( Set.prototype, 'sortnum', function _sortnum() { return [ ...this ].map( (item) => Number( item ) ).sort( (a, b) => a - b ); } );
				define( Set.prototype, 'map', function _map( fn ) { return new Set( [ ...this ].map( fn ) ); } );
				define( Set.prototype, 'grep', function _grep( fn ) { return new Set( [ ...this ].filter( fn ) ); } );
				define( Set.prototype, 'any', function _any( fn ) { return [ ...this ].some( fn ) ? 1 : 0; } );
				define( Set.prototype, 'all', function _all( fn ) { return [ ...this ].every( fn ) ? 1 : 0; } );
				define( Set.prototype, 'first', function _first( fn ) { for ( const v of this ) { if ( fn( v ) ) { return v; } } return null; } );
				define( Set.prototype, 'remove_if', function _remove_if( fn ) { for ( const v of [ ...this ] ) { if ( fn( v ) ) { __zuzu_release_collection_value( this, v ); this.delete( v ); } } return this; } );
				define( Set.prototype, 'for_each_value', function _for_each_value( fn ) { for ( const v of this ) { fn( v ); } return this; } );
				const clearSet = Set.prototype.clear;
				define( Set.prototype, 'clear', function _clear() { __zuzu_release_collection_values( this ); clearSet.call( this ); return this; } );
				define( RegExp.prototype, 'to_String', function _to_string() { return this.source; } );
				if ( !Object.prototype.hasOwnProperty.call( RegExp.prototype, Symbol.toPrimitive ) ) {
					const regDesc = Object.create( null );
					regDesc.value = function _regexp_to_primitive( hint ) {
						if ( hint === 'string' || hint === 'default' ) {
							return this.to_String();
						}
						return NaN;
					};
					regDesc.enumerable = false;
					regDesc.configurable = true;
					regDesc.writable = true;
					Object.defineProperty( RegExp.prototype, Symbol.toPrimitive, regDesc );
				}
				if ( !Object.prototype.hasOwnProperty.call( Object.prototype, Symbol.toPrimitive ) ) {
					const objectDesc = Object.create( null );
					objectDesc.value = function _object_to_primitive( hint ) {
						if ( ( hint === 'string' || hint === 'default' ) && typeof this.to_String === 'function' ) {
							return this.to_String();
						}
						const methods = hint === 'number'
							? [ 'valueOf', 'toString' ]
							: [ 'toString', 'valueOf' ];
						for ( const methodName of methods ) {
							const method = this[methodName];
							if ( typeof method !== 'function' ) {
								continue;
							}
							if ( methodName === 'toString' && method === Object.prototype.toString ) {
								continue;
							}
							if ( methodName === 'valueOf' && method === Object.prototype.valueOf ) {
								continue;
							}
							const value = method.call( this );
							if ( value == null || typeof value !== 'object' ) {
								return value;
							}
						}
						return Object.prototype.toString.call( this );
					};
					objectDesc.enumerable = false;
					objectDesc.configurable = true;
					objectDesc.writable = true;
					Object.defineProperty( Object.prototype, Symbol.toPrimitive, objectDesc );
				}

			})();
		`;
          const bootstrapRunOptions = {};
          if (this.executionTimeoutMs != null) {
            bootstrapRunOptions.timeout = this.executionTimeoutMs;
          }
          this.host.runInContext(bootstrap, context, bootstrapRunOptions);
        }
        loadModule(moduleName, fromFile, contextForPolicy = null) {
          if (/(^|\/)\.\.(\/|$)/.test(moduleName)) {
            throw new Error("Import module path cannot contain '..' segments");
          }
          this.enforceModulePolicy(moduleName);
          const resolved = this.resolveModulePath(moduleName, fromFile);
          const cacheable = moduleName !== "test/more" && this.evalCapabilityOverrides == null;
          if (cacheable && this.moduleCache.has(resolved)) {
            return this.moduleCache.get(resolved);
          }
          if (this.moduleLoading.has(resolved)) {
            throw new Error("Circular module loading detected");
          }
          if (resolved.endsWith(".js")) {
            const hiddenObjectPrototypeMethods = [];
            for (const name2 of ["get", "set"]) {
              const desc = Object.prototype.hasOwnProperty.call(Object.prototype, name2) ? Object.getOwnPropertyDescriptor(Object.prototype, name2) : null;
              if (desc && desc.configurable) {
                hiddenObjectPrototypeMethods.push([name2, desc]);
                delete Object.prototype[name2];
              }
            }
            let loaded;
            try {
              loaded = this.host.loadJsModule(resolved, moduleName, fromFile);
            } finally {
              for (const [name2, desc] of hiddenObjectPrototypeMethods) {
                Object.defineProperty(Object.prototype, name2, desc);
              }
            }
            if (loaded && typeof loaded.__zuzu_set_runtime_policy === "function") {
              const policy = {
                gui: this.host.gui || null,
                host_name: this.host.name,
                repo_root: this.repoRoot,
                include_paths: this.includePaths.slice(),
                deny_modules: [...this.denyModules],
                debug_level: this.debugLevel,
                transpiler: this.transpiler,
                load_module: (name2, requestFromFile = fromFile) => this.loadModule(
                  name2,
                  requestFromFile || fromFile,
                  contextForPolicy
                ),
                builtin_class: (name2) => {
                  if (!contextForPolicy) {
                    return null;
                  }
                  const builtins = {
                    Array: contextForPolicy.__zuzu_builtin_Array,
                    Bag: contextForPolicy.Bag,
                    Class: contextForPolicy.Class,
                    Dict: contextForPolicy.Dict || contextForPolicy.__zuzu_builtin_Object,
                    Function: contextForPolicy.__zuzu_builtin_Function,
                    Object: contextForPolicy.__zuzu_builtin_Object,
                    Pair: contextForPolicy.Pair,
                    PairList: contextForPolicy.PairList,
                    Regexp: contextForPolicy.__zuzu_builtin_RegExp,
                    Set: contextForPolicy.__zuzu_builtin_Set
                  };
                  return builtins[name2] || null;
                },
                to_String: (value) => zuzuOperatorString(value),
                to_Number: (value) => zuzuToNumber(value),
                to_Boolean: (value) => zuzuTruthy(value),
                to_Regexp: (value) => operatorRegexp(value),
                to_Regexp_with_flags: (value, flags) => {
                  const pattern = value instanceof RegExp ? value.source : zuzuOperatorString(value);
                  return new RegExp(pattern, zuzuOperatorString(flags));
                },
                stdout_write: (text) => {
                  if (typeof this.stdoutHandler === "function") {
                    this.stdoutHandler(String(text));
                  } else if (typeof process !== "undefined" && process.stdout) {
                    process.stdout.write(String(text));
                  } else {
                    this.host.consoleLog(String(text));
                  }
                },
                stderr_write: (text) => {
                  if (typeof this.stderrHandler === "function") {
                    this.stderrHandler(String(text));
                  } else if (typeof process !== "undefined" && process.stderr) {
                    process.stderr.write(String(text));
                  } else if (typeof console !== "undefined" && typeof console.warn === "function") {
                    console.warn(String(text));
                  }
                },
                browser_worker_source: this.host.workerSource || null,
                browser_worker_url: this.host.workerUrl || null,
                browser_worker_factory: this.host.workerFactory || null
              };
              for (const capability of [
                "fs",
                "net",
                "perl",
                "js",
                "proc",
                "db",
                "clib",
                "gui",
                "worker"
              ]) {
                policy[`deny_${capability}`] = this.isCapabilityDenied(capability) || !this.host.capabilities.has(capability);
              }
              loaded.__zuzu_set_runtime_policy(policy);
            }
            if (cacheable) {
              this.moduleCache.set(resolved, loaded);
            }
            return loaded;
          }
          const source = this.host.readFileText(resolved);
          let js = this.transpile(source);
          setCompiledSource(resolved, js);
          const exportNames = resolved.endsWith(".zzm") ? collectTopLevelDeclarations(source, stripPod) : [];
          if (exportNames.length > 0) {
            const exportBridge = exportNames.map((name2) => {
              if (name2.startsWith("_")) {
                return `if ( typeof ${name2} !== "undefined" ) { const __zuzu_desc = Object.create( null ); __zuzu_desc.get = function() { return ${name2}; }; __zuzu_desc.set = function( value ) { ${name2} = value; }; __zuzu_desc.enumerable = false; __zuzu_desc.configurable = true; Object.defineProperty( module.exports, ${JSON.stringify(name2)}, __zuzu_desc ); }`;
              }
              return `if ( typeof ${name2} !== "undefined" ) { const __zuzu_desc = Object.create( null ); __zuzu_desc.get = function() { return ${name2}; }; __zuzu_desc.set = function( value ) { ${name2} = value; }; __zuzu_desc.enumerable = true; __zuzu_desc.configurable = true; Object.defineProperty( module.exports, ${JSON.stringify(name2)}, __zuzu_desc ); }`;
            }).join("\n");
            js += `
${exportBridge}
`;
          }
          const moduleObj = { exports: {} };
          const context = this.buildContext({
            exports: moduleObj.exports,
            module: moduleObj,
            filename: resolved
          });
          context.__global__ = /* @__PURE__ */ Object.create(null);
          this.installCollectionMethods(context);
          const moduleRunOptions = { filename: resolved };
          if (this.executionTimeoutMs != null) {
            moduleRunOptions.timeout = this.executionTimeoutMs;
          }
          this.moduleLoading.add(resolved);
          try {
            this.host.runInContext(js, context, moduleRunOptions);
            if (cacheable) {
              this.moduleCache.set(resolved, moduleObj.exports);
            }
          } finally {
            this.moduleLoading.delete(resolved);
          }
          return moduleObj.exports;
        }
        runSource(source, options = {}) {
          const filename = options.filename || this.host.join(this.repoRoot, "<inline>.zzs");
          let js;
          try {
            js = this.transpile(source);
          } catch (err) {
            const stderr = formatRuntimeError(err);
            if (typeof options.onStderr === "function") {
              options.onStderr(stderr);
            }
            return {
              status: 3,
              stdout: "",
              stderr
            };
          }
          return this.runCompiled(js, options);
        }
        runCompiled(js, options = {}) {
          const filename = options.filename || this.host.join(this.repoRoot, "<inline>.zzs");
          taskRuntime2.resetForRun(this.debugLevel);
          setCompiledSource(filename, js);
          const preloadGlobals = /* @__PURE__ */ Object.create(null);
          if (Array.isArray(options.preloadModules)) {
            for (const moduleName of options.preloadModules) {
              Object.assign(preloadGlobals, this.loadModule(moduleName, filename));
            }
          }
          this.outputLines = [];
          const previousStdoutHandler = this.stdoutHandler;
          const previousStderrHandler = this.stderrHandler;
          this.stdoutHandler = typeof options.onStdout === "function" ? options.onStdout : null;
          this.stderrHandler = typeof options.onStderr === "function" ? options.onStderr : null;
          const context = this.buildContext({
            filename,
            globals: preloadGlobals
          });
          context.__global__ = /* @__PURE__ */ Object.create(null);
          this.installCollectionMethods(context);
          const finishRun = () => {
            let topLevelTests = 0;
            let hasTopLevelPlan = false;
            for (const line of this.outputLines) {
              if (/^\d+\.\.\d+\s*$/.test(line)) {
                hasTopLevelPlan = true;
              }
              if (/^ok\b/.test(line) || /^not ok\b/.test(line)) {
                topLevelTests++;
              }
            }
            if (topLevelTests > 0 && !hasTopLevelPlan) {
              const stdout2 = this.outputLines.length > 0 ? `${this.outputLines.join("\n")}
` : "";
              const stderr = "Error: TAP plan missing (expected 1..N)\n";
              if (typeof this.stderrHandler === "function") {
                this.stderrHandler(stderr);
              }
              return {
                status: 1,
                stdout: stdout2,
                stderr
              };
            }
            const stdout = this.outputLines.length > 0 ? `${this.outputLines.join("\n")}
` : "";
            return {
              status: 0,
              stdout,
              stderr: ""
            };
          };
          const failRun = (err) => {
            const stdout = this.outputLines.length > 0 ? `${this.outputLines.join("\n")}
` : "";
            const isParse = err && err.name === "SyntaxError";
            const stderr = formatRuntimeError(err);
            if (typeof this.stderrHandler === "function") {
              this.stderrHandler(stderr);
            }
            return {
              status: isParse ? 3 : 1,
              stdout,
              stderr
            };
          };
          const cleanupRun = (result) => {
            taskRuntime2.shutdown("Task cancelled");
            this.outputLines = null;
            this.stdoutHandler = previousStdoutHandler;
            this.stderrHandler = previousStderrHandler;
            return result;
          };
          const invokeMain = () => {
            if (typeof context.__main__ !== "function") {
              return null;
            }
            const argv = Array.isArray(options.scriptArgs) ? options.scriptArgs.map((value) => String(value)) : [];
            const mainResult = context.__main__(argv);
            if (mainResult instanceof taskRuntime2.Task || mainResult && typeof mainResult.then === "function") {
              return taskRuntime2.awaitValue(mainResult);
            }
            return null;
          };
          try {
            const scriptRunOptions = { filename };
            if (this.executionTimeoutMs != null) {
              scriptRunOptions.timeout = this.executionTimeoutMs;
            }
            const topLevelResult = this.host.runInContext(js, context, scriptRunOptions);
            if (topLevelResult && typeof topLevelResult.then === "function") {
              return Promise.resolve(topLevelResult).then(invokeMain).then(finishRun, failRun).then(cleanupRun);
            }
            const mainResult = invokeMain();
            if (mainResult && typeof mainResult.then === "function") {
              return Promise.resolve(mainResult).then(finishRun, failRun).then(cleanupRun);
            }
            return cleanupRun(finishRun());
          } catch (err) {
            return cleanupRun(failRun(err));
          }
        }
        runFile(scriptPath) {
          const source = this.host.readFileText(scriptPath);
          return this.runSource(source, {
            filename: scriptPath,
            scriptArgs: []
          });
        }
      };
      module2.exports = {
        ZuzuScript,
        isWeakableValue,
        makeWeakValue,
        resolveWeakValue
      };
    }
  });

  // lib/browser-runtime.js
  var require_browser_runtime = __commonJS({
    "lib/browser-runtime.js"(exports2, module2) {
      "use strict";
      var { createBrowserHost } = require_browser_host();
      var { transpile } = require_transpiler();
      var { ZuzuScript } = require_runtime();
      function _extractLineColumn(errorText) {
        const match = String(errorText || "").match(/:(\d+):(\d+)\)?(?:\n|$)/u);
        if (!match) {
          return null;
        }
        return {
          line: Number(match[1]),
          column: Number(match[2])
        };
      }
      function _makeSnippet(source, line, column) {
        const lines = String(source || "").split(/\r?\n/u);
        if (!Number.isInteger(line) || line < 1 || line > lines.length) {
          return null;
        }
        const content = lines[line - 1];
        const caretColumn = Number.isInteger(column) && column > 0 ? column : 1;
        return `${content}
${" ".repeat(Math.max(0, caretColumn - 1))}^`;
      }
      function _toJsError(source, filename, result) {
        const stderr = String(result && result.stderr || "").trim();
        const message = stderr || `Zuzu evaluation failed (${filename})`;
        const err = new Error(message);
        err.name = result && result.status === 3 ? "ZuzuParseError" : "ZuzuRuntimeError";
        err.filename = filename;
        err.source = String(source || "");
        err.zuzu = {
          status: result ? result.status : 1,
          stdout: result ? result.stdout : "",
          stderr: result ? result.stderr : ""
        };
        const where = _extractLineColumn(stderr);
        if (where) {
          err.line = where.line;
          err.column = where.column;
          err.snippet = _makeSnippet(source, where.line, where.column);
        }
        return err;
      }
      function _coerceScalarOutput(stdout) {
        const lines = String(stdout || "").trimEnd().split(/\r?\n/u);
        if (lines.length !== 1) {
          return void 0;
        }
        const raw = lines[0];
        if (/^-?\d+(?:\.\d+)?$/u.test(raw)) {
          return Number(raw);
        }
        if (raw === "true" || raw === "1") {
          return true;
        }
        if (raw === "false" || raw === "0") {
          return false;
        }
        if (raw === "null") {
          return null;
        }
        return raw;
      }
      function createBrowserRuntime(options = {}) {
        const host = options.host || createBrowserHost(options);
        const runtime = options.runtime || new ZuzuScript({
          host,
          repoRoot: options.repoRoot || host.repoRoot || "/",
          includePaths: options.includePaths,
          denyCapabilities: options.denyCapabilities,
          allowCapabilities: options.allowCapabilities,
          denyModules: options.denyModules,
          debugLevel: options.debugLevel,
          executionTimeoutMs: options.executionTimeoutMs,
          transpiler: options.transpiler
        });
        function _runSource(source, evalOptions = {}) {
          const filename = evalOptions.filename || "/<browser>.zzs";
          return runtime.runSource(String(source ?? ""), {
            filename,
            preloadModules: evalOptions.preloadModules || []
          });
        }
        function zuzu_run(source, evalOptions = {}) {
          const result = _runSource(source, evalOptions);
          if (result && typeof result.then === "function") {
            return result.then((resolved) => {
              if (evalOptions.throwOnError !== false && resolved.status !== 0) {
                throw _toJsError(source, evalOptions.filename || "/<browser>.zzs", resolved);
              }
              return resolved;
            });
          }
          if (evalOptions.throwOnError !== false && result.status !== 0) {
            throw _toJsError(source, evalOptions.filename || "/<browser>.zzs", result);
          }
          return result;
        }
        function zuzu_eval(source, evalOptions = {}) {
          const sourceText = String(source ?? "");
          const filename = evalOptions.filename || "/<browser>.zzs";
          const run = () => {
            if (evalOptions.result === true) {
              return zuzu_run(sourceText, evalOptions);
            }
            const expressionResult = _runSource(`say( ${sourceText} );`, {
              ...evalOptions,
              filename
            });
            if (expressionResult && typeof expressionResult.then === "function") {
              return expressionResult.then((resolvedExpression) => {
                if (resolvedExpression.status === 0) {
                  return _coerceScalarOutput(resolvedExpression.stdout);
                }
                return Promise.resolve(zuzu_run(sourceText, evalOptions)).then((result2) => {
                  if (result2.stdout && evalOptions.returnStdout === true) {
                    return result2.stdout;
                  }
                  return void 0;
                });
              });
            }
            if (expressionResult.status === 0) {
              return _coerceScalarOutput(expressionResult.stdout);
            }
            const result = zuzu_run(sourceText, evalOptions);
            if (result.stdout && evalOptions.returnStdout === true) {
              return result.stdout;
            }
            return void 0;
          };
          if (evalOptions.async === true) {
            return Promise.resolve().then(run);
          }
          return run();
        }
        function zuzu_compile(source, _compileOptions = {}) {
          return transpile(String(source ?? ""), {
            transpiler: runtime.transpiler
          });
        }
        return {
          host,
          runtime,
          zuzu_eval,
          zuzu_run,
          zuzu_compile
        };
      }
      module2.exports = {
        createBrowserRuntime
      };
    }
  });

  // modules/std/marshal/graph.js
  var require_graph = __commonJS({
    "modules/std/marshal/graph.js"(exports2, module2) {
      "use strict";
      var {
        BinaryString: BinaryString2,
        ZuzuBinary,
        ZuzuBag,
        Pair,
        PairList,
        isPairListLike,
        isWeakCell,
        makeWeakValue,
        retainCollectionValue,
        retainValue,
        resolveWeakValue
      } = require_runtime_helpers();
      var cbor = require_cbor();
      var KIND_PAIR = 1;
      var KIND_ARRAY = 2;
      var KIND_DICT = 3;
      var KIND_PAIRLIST = 4;
      var KIND_SET = 5;
      var KIND_BAG = 6;
      var KIND_OBJECT = 7;
      var KIND_FUNCTION = 8;
      var KIND_CLASS = 9;
      var KIND_TRAIT = 10;
      var KIND_BOUND_METHOD = 11;
      var KIND_TIME = 12;
      var KIND_PATH = 13;
      var CODE_FUNCTION = 1;
      var CODE_CLASS = 2;
      var CODE_TRAIT = 3;
      var MAX_SAFE_INTEGER = 9007199254740991;
      var classRegistry = /* @__PURE__ */ new Map();
      var codeRegistry = /* @__PURE__ */ new Map();
      var runtimePolicy2 = {
        host_name: "node",
        repo_root: null,
        include_paths: [],
        deny_modules: [],
        debug_level: 0,
        transpiler: null
      };
      function setRuntimePolicy2(policy = {}) {
        runtimePolicy2 = {
          ...runtimePolicy2,
          ...policy,
          include_paths: Array.isArray(policy.include_paths) ? policy.include_paths.slice() : runtimePolicy2.include_paths,
          deny_modules: Array.isArray(policy.deny_modules) ? policy.deny_modules.slice() : runtimePolicy2.deny_modules
        };
      }
      function dumpGraph(value) {
        const state = {
          objects: [],
          ids: /* @__PURE__ */ new WeakMap(),
          code: [],
          codeIds: /* @__PURE__ */ new WeakMap(),
          onDump: /* @__PURE__ */ new WeakSet()
        };
        const root = encodeValue(value, state);
        return cbor.encodeOne(
          cbor.tag(cbor.SELF_DESCRIBED_TAG, [
            cbor.textString("ZUZU-MARSHAL"),
            1,
            /* @__PURE__ */ new Map(),
            root,
            state.objects,
            state.code
          ])
        );
      }
      function loadGraph(blob) {
        if (!(blob instanceof BinaryString2)) {
          throw new Error(
            `TypeException: std/marshal.load expects BinaryString, got ${typeName2(blob)}`
          );
        }
        const decoded = cbor.decodeOne(blob);
        const envelope = decodeEnvelope(decoded);
        const codeValues = loadCodeTable(envelope.code);
        const placeholders = allocatePlaceholders(envelope.objects, codeValues);
        fillPlaceholders(envelope.objects, placeholders);
        const value = decodeValue(envelope.root, placeholders, {
          allowWeak: false,
          context: "Envelope root"
        });
        runOnLoadHooks(envelope.objects, placeholders);
        return value;
      }
      function safeToDumpGraph(value) {
        try {
          dumpGraph(value);
          return true;
        } catch (_err) {
          return false;
        }
      }
      function encodeValue(value, state) {
        if (isWeakCell(value)) {
          return [1, encodeValue(resolveWeakValue(value), state)];
        }
        if (value == null) {
          return null;
        }
        if (typeof value === "boolean") {
          return value;
        }
        if (typeof value === "number") {
          return encodeNumber(value);
        }
        if (typeof value === "string") {
          return cbor.textString(value);
        }
        if (value instanceof ZuzuBinary) {
          return cbor.byteString(value.bytes);
        }
        if (isBoundMethodValue(value)) {
          return encodeBoundMethod(value, state);
        }
        if (isUserClassValue(value)) {
          return encodeClassReference(value, state);
        }
        if (isTraitValue(value)) {
          return encodeTraitReference(value, state);
        }
        if (isFunctionValue(value)) {
          return encodeFunctionReference(value, state);
        }
        if (value instanceof Pair) {
          return encodeObjectTableValue(value, KIND_PAIR, state, encodePairPayload);
        }
        if (Array.isArray(value)) {
          return encodeObjectTableValue(value, KIND_ARRAY, state, encodeArrayPayload);
        }
        if (isPairListLike(value)) {
          return encodeObjectTableValue(
            value,
            KIND_PAIRLIST,
            state,
            encodePairListPayload
          );
        }
        if (value instanceof Set) {
          return encodeObjectTableValue(value, KIND_SET, state, encodeSetPayload);
        }
        if (value instanceof ZuzuBag) {
          return encodeObjectTableValue(value, KIND_BAG, state, encodeBagPayload);
        }
        if (isTimeValue(value)) {
          return encodeObjectTableValue(value, KIND_TIME, state, encodeTimePayload);
        }
        if (isPathValue(value)) {
          return encodeObjectTableValue(value, KIND_PATH, state, encodePathPayload);
        }
        if (isPlainDict(value)) {
          return encodeObjectTableValue(value, KIND_DICT, state, encodeDictPayload);
        }
        if (isUserObjectValue(value)) {
          return encodeUserObject(value, state);
        }
        throw new Error(`Value of type ${typeName2(value)} is not marshalable in this phase`);
      }
      function encodeNumber(value) {
        if (!Number.isFinite(value)) {
          throw new Error("Number values must be finite");
        }
        if (!Object.is(value, -0) && Number.isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER) {
          return value;
        }
        return Number(value);
      }
      function encodeObjectTableValue(value, kind, state, payloadEncoder) {
        if (state.ids.has(value)) {
          return [0, state.ids.get(value)];
        }
        const id = state.objects.length;
        state.ids.set(value, id);
        state.objects.push(null);
        state.objects[id] = [kind, payloadEncoder(value, state)];
        return [0, id];
      }
      function encodeArrayPayload(value, state) {
        return value.map((item) => encodeValue(item, state));
      }
      function encodeDictPayload(value, state) {
        return Object.keys(value).sort().map((key) => [
          cbor.textString(key),
          encodeValue(value[key], state)
        ]);
      }
      function encodePairListPayload(value, state) {
        return value.list.map((pair) => [
          cbor.textString(pair[0]),
          encodeValue(pair[1], state)
        ]);
      }
      function encodeSetPayload(value, state) {
        return [...value].map((item) => encodeValue(item, state));
      }
      function encodeBagPayload(value, state) {
        return value.items.map((item) => encodeValue(item, state));
      }
      function encodePairPayload(value, state) {
        return [
          cbor.textString(value.key()),
          encodeValue(value.value(), state)
        ];
      }
      function encodeTimePayload(value, _state) {
        const epoch = typeof value.epoch === "function" ? value.epoch() : value._epoch;
        if (typeof epoch !== "number" || !Number.isFinite(epoch)) {
          throw new Error("Time value has invalid internal epoch");
        }
        const zone = typeof value.timezone === "function" ? value.timezone().to_String() : value._timezone;
        if (zone == null) {
          return [encodeNumber(epoch)];
        }
        return [encodeNumber(epoch), cbor.textString(String(zone))];
      }
      function encodePathPayload(value, _state) {
        const pathText = typeof value.to_String === "function" ? value.to_String() : value.value;
        if (pathText == null) {
          throw new Error("Path value has invalid internal path");
        }
        return [cbor.textString(pathText)];
      }
      function encodeUserObject(value, state) {
        if (state.ids.has(value)) {
          return [0, state.ids.get(value)];
        }
        if (!state.onDump.has(value)) {
          state.onDump.add(value);
          if (typeof value.__on_dump__ === "function") {
            try {
              value.__on_dump__();
            } catch (err) {
              throw new Error(
                `__on_dump__ for ${typeName2(value)} failed: ${err.message || err}`
              );
            }
          }
        }
        const id = state.objects.length;
        state.ids.set(value, id);
        state.objects.push(null);
        const slots = Object.keys(value).filter((key) => isMarshalableObjectSlot(value[key])).sort().map((key) => [
          cbor.textString(key),
          encodeValue(value[key], state)
        ]);
        state.objects[id] = [
          KIND_OBJECT,
          [
            encodeClassReference(value.constructor, state),
            slots
          ]
        ];
        return [0, id];
      }
      function encodeBoundMethod(value, state) {
        if (state.ids.has(value)) {
          return [0, state.ids.get(value)];
        }
        const receiver = value.__zuzu_bound_receiver || value.receiver || null;
        const methodName = value.__zuzu_bound_method_name || value.name;
        if (!receiver || !methodName) {
          throw new Error("Bound method values are not marshalable in this phase");
        }
        const id = state.objects.length;
        state.ids.set(value, id);
        state.objects.push(null);
        state.objects[id] = [
          KIND_BOUND_METHOD,
          [
            encodeValue(receiver, state),
            cbor.textString(methodName)
          ]
        ];
        return [0, id];
      }
      function encodeFunctionReference(fn2, state) {
        return encodeCodeBackedObject(fn2, KIND_FUNCTION, state, encodeFunctionCode);
      }
      function encodeTraitReference(trait, state) {
        return encodeCodeBackedObject(trait, KIND_TRAIT, state, encodeTraitCode);
      }
      function encodeCodeBackedObject(value, kind, state, codeEncoder) {
        if (state.ids.has(value)) {
          return [0, state.ids.get(value)];
        }
        const id = state.objects.length;
        state.ids.set(value, id);
        state.objects.push(null);
        const codeId = codeEncoder(value, state);
        state.objects[id] = [kind, [codeId]];
        return [0, id];
      }
      function encodeClassReference(klass, state) {
        if (!isUserClassValue(klass)) {
          throw new Error("Object class is not marshalable in this phase");
        }
        return encodeCodeBackedObject(klass, KIND_CLASS, state, encodeClassCode);
      }
      function encodeClassCode(klass, state) {
        if (!klass.__zuzu_marshal_meta) {
          Object.defineProperty(klass, "__zuzu_marshal_meta", {
            value: {
              kind: "class",
              name: klass.__zuzu_class_name || klass.name,
              source: marshalClassSource(klass, klass.__zuzu_class_name || klass.name),
              captures: {}
            },
            enumerable: false,
            configurable: true,
            writable: true
          });
        }
        return encodeCodeRecord(klass, state, CODE_CLASS);
      }
      function encodeFunctionCode(fn2, state, preferredName = null) {
        return encodeCodeRecord(fn2, state, CODE_FUNCTION, preferredName);
      }
      function encodeTraitCode(trait, state, preferredName = null) {
        return encodeCodeRecord(trait, state, CODE_TRAIT, preferredName);
      }
      function encodeCodeRecord(value, state, kind, preferredName = null) {
        if (state.codeIds.has(value)) {
          return state.codeIds.get(value);
        }
        const meta = value.__zuzu_marshal_meta || {};
        if (!meta.source) {
          throw new Error(`Value of type ${typeName2(value)} is not marshalable in this phase`);
        }
        const id = state.code.length;
        state.codeIds.set(value, id);
        state.code.push(null);
        const bindingName = marshalBindingName(preferredName || meta.name, id);
        const captures = [];
        const dependencies = [];
        for (const [name2, captured] of Object.entries(meta.captures || {}).sort()) {
          if (isFunctionValue(captured)) {
            dependencies.push([0, encodeFunctionCode(captured, state, name2)]);
          } else if (isUserClassValue(captured)) {
            dependencies.push([0, encodeClassCode(captured, state, name2)]);
          } else if (isTraitValue(captured)) {
            dependencies.push([0, encodeTraitCode(captured, state, name2)]);
          } else if (isScalarForCapture(captured)) {
            captures.push([cbor.textString(name2), encodeValue(captured, state)]);
          }
        }
        registerCodeValue(kind, bindingName, meta.source, value);
        state.code[id] = [
          kind,
          cbor.textString(bindingName),
          cbor.textString(meta.source),
          captures,
          dependencies
        ];
        return id;
      }
      function decodeEnvelope(decoded) {
        if (!cbor.isTagged(decoded) || cbor.tagNumber(decoded) !== cbor.SELF_DESCRIBED_TAG) {
          throw new Error("Top-level item is not tag 55799");
        }
        const envelope = cbor.tagValue(decoded);
        if (!Array.isArray(envelope)) {
          throw new Error("Envelope must be an array");
        }
        if (envelope.length !== 6) {
          throw new Error("Envelope must contain exactly 6 fields");
        }
        const [magic, version, options, root, objects, code] = envelope;
        if (!cbor.isTextString(magic) || cbor.textValue(magic) !== "ZUZU-MARSHAL") {
          throw new Error("Envelope magic is invalid");
        }
        if (typeof version !== "number" || version !== 1) {
          throw new Error("Unsupported Zuzu Marshal version");
        }
        if (!(options instanceof Map)) {
          throw new Error("Envelope options must be a map");
        }
        if (!Array.isArray(objects)) {
          throw new Error("Envelope object table must be an array");
        }
        if (!Array.isArray(code)) {
          throw new Error("Envelope code table must be an array");
        }
        return { root, objects, code };
      }
      function loadCodeTable(code) {
        const records = code.map(validateCodeRecord);
        const values = [];
        const loading = /* @__PURE__ */ new Set();
        function loadById(id) {
          if (values[id]) {
            return values[id];
          }
          if (loading.has(id)) {
            throw new Error(`Cyclic code dependency involving record ${id}`);
          }
          loading.add(id);
          const value = loadCodeRecord(records[id], id, loadById);
          values[id] = value;
          loading.delete(id);
          return value;
        }
        for (let id = 0; id < records.length; id++) {
          loadById(id);
        }
        return values;
      }
      function validateCodeRecord(record, id) {
        assertRecordArray(record, `Code table entry ${id}`, 5);
        const [kind, bindingNameValue, sourceValue, captures, dependencies] = record;
        assertInteger(kind, `Code table entry ${id} kind`);
        if (![CODE_FUNCTION, CODE_CLASS, CODE_TRAIT].includes(kind)) {
          throw new Error(`Unsupported code kind ${kind} in current loader`);
        }
        if (!cbor.isTextString(bindingNameValue)) {
          throw new Error(`Code table entry ${id} binding name must be a text string`);
        }
        if (!cbor.isTextString(sourceValue)) {
          throw new Error(`Code table entry ${id} source must be a text string`);
        }
        if (!Array.isArray(captures)) {
          throw new Error(`Code table entry ${id} captures must be an array`);
        }
        if (!Array.isArray(dependencies)) {
          throw new Error(`Code table entry ${id} dependencies must be an array`);
        }
        return {
          kind,
          bindingName: cbor.textValue(bindingNameValue),
          source: cbor.textValue(sourceValue),
          captures,
          dependencies
        };
      }
      function loadCodeRecord(record, id, loadById) {
        const registered = codeRegistry.get(
          codeRegistryKey(record.kind, record.bindingName, record.source)
        );
        if (registered) {
          return registered;
        }
        const env = /* @__PURE__ */ Object.create(null);
        for (const capture of record.captures) {
          assertRecordArray(capture, `Capture in code record ${id}`, 2);
          const [nameValue, encodedValue] = capture;
          if (!cbor.isTextString(nameValue)) {
            throw new Error(`Capture name in code record ${id} must be a text string`);
          }
          const name2 = cbor.textValue(nameValue);
          if (isWeakStorageRecord(encodedValue)) {
            throw new Error(
              `Capture '${name2}' in code record ${id} weak storage record is not allowed here`
            );
          }
          env[name2] = decodeScalar(encodedValue);
        }
        for (const dependency of record.dependencies) {
          assertRecordArray(dependency, `Code dependency in record ${id}`, 2);
          const [depKind, depId] = dependency;
          assertInteger(depKind, `Code dependency in record ${id} kind`);
          if (depKind !== 0) {
            throw new Error(`Unsupported code dependency kind ${depKind} in record ${id}`);
          }
          assertInteger(depId, `Internal dependency in record ${id}`);
          const value = loadById(depId);
          const name2 = value.__zuzu_class_name || value.__zuzu_trait_name || value.__zuzu_marshal_meta && value.__zuzu_marshal_meta.name;
          if (name2) {
            env[name2] = value;
          }
        }
        if (record.kind === CODE_FUNCTION) {
          return buildFunctionFromSource(record.bindingName, record.source, env);
        }
        if (record.kind === CODE_CLASS) {
          return buildClassFromSource(record.bindingName, record.source, env);
        }
        return buildTraitFromSource(record.bindingName, record.source, env);
      }
      function allocatePlaceholders(objects, codeValues) {
        const placeholders = [];
        for (let id = 0; id < objects.length; id++) {
          const entry = objects[id];
          assertRecordArray(entry, `Object table entry ${id}`, 2);
          const kind = entry[0];
          assertInteger(kind, `Object table entry ${id} kind`);
          switch (kind) {
            case KIND_PAIR:
              placeholders[id] = new Pair({ pair: [] });
              break;
            case KIND_ARRAY:
              placeholders[id] = [];
              break;
            case KIND_DICT:
              placeholders[id] = {};
              break;
            case KIND_PAIRLIST:
              placeholders[id] = new PairList([]);
              break;
            case KIND_SET:
              placeholders[id] = /* @__PURE__ */ new Set();
              break;
            case KIND_BAG:
              placeholders[id] = new ZuzuBag([]);
              break;
            case KIND_OBJECT:
              placeholders[id] = {};
              break;
            case KIND_FUNCTION:
              placeholders[id] = decodeFunctionPayload(id, entry[1], codeValues);
              break;
            case KIND_CLASS:
              placeholders[id] = decodeClassPayload(id, entry[1], codeValues);
              break;
            case KIND_TRAIT:
              placeholders[id] = decodeTraitPayload(id, entry[1], codeValues);
              break;
            case KIND_BOUND_METHOD:
              placeholders[id] = createBoundMethodPlaceholder(id);
              break;
            case KIND_TIME:
              placeholders[id] = new (timeClass())(0);
              break;
            case KIND_PATH:
              placeholders[id] = new (pathClass())(".");
              break;
            default:
              throw new Error(`Unsupported object kind ${kind} in current loader`);
          }
        }
        return placeholders;
      }
      function fillPlaceholders(objects, placeholders) {
        for (let id = 0; id < objects.length; id++) {
          const [kind, payload] = objects[id];
          switch (kind) {
            case KIND_PAIR:
              fillPair(id, payload, placeholders);
              break;
            case KIND_ARRAY:
              fillArray(id, payload, placeholders);
              break;
            case KIND_DICT:
              fillDict(id, payload, placeholders);
              break;
            case KIND_PAIRLIST:
              fillPairList(id, payload, placeholders);
              break;
            case KIND_SET:
              fillSet(id, payload, placeholders);
              break;
            case KIND_BAG:
              fillBag(id, payload, placeholders);
              break;
            case KIND_OBJECT:
              fillObject(id, payload, placeholders);
              break;
            case KIND_FUNCTION:
              break;
            case KIND_CLASS:
              break;
            case KIND_TRAIT:
              break;
            case KIND_BOUND_METHOD:
              break;
            case KIND_TIME:
              fillTime(id, payload, placeholders);
              break;
            case KIND_PATH:
              fillPath(id, payload, placeholders);
              break;
            default:
              throw new Error(`Unsupported object kind ${kind} in current loader`);
          }
        }
        for (let id = 0; id < objects.length; id++) {
          const [kind, payload] = objects[id];
          if (kind === KIND_BOUND_METHOD) {
            fillBoundMethodPayload(id, payload, placeholders);
          }
        }
      }
      function fillPair(id, payload, placeholders) {
        assertRecordArray(payload, `Pair object payload ${id}`, 2);
        const [key, value] = payload;
        if (!cbor.isTextString(key)) {
          throw new Error(`Pair object payload ${id} key must be a text string`);
        }
        placeholders[id].pair = [
          cbor.textValue(key),
          storeStrongLoadedValue(decodeValue(value, placeholders, {
            context: `Pair object payload ${id} value`
          }))
        ];
      }
      function fillArray(id, payload, placeholders) {
        if (!Array.isArray(payload)) {
          throw new Error(`Array object payload ${id} must be an array`);
        }
        placeholders[id].splice(
          0,
          placeholders[id].length,
          ...payload.map((item) => storeCollectionLoadedValue(
            placeholders[id],
            decodeValue(
              item,
              placeholders,
              { context: `Array object payload ${id} item` }
            )
          ))
        );
      }
      function fillDict(id, payload, placeholders) {
        if (!Array.isArray(payload)) {
          throw new Error(`Dict object payload ${id} must be an array`);
        }
        const target = placeholders[id];
        for (const pair of payload) {
          const [key, value] = decodeKeyValueRecord(
            `Dict object payload ${id}`,
            pair,
            placeholders
          );
          if (Object.prototype.hasOwnProperty.call(target, key)) {
            throw new Error(`Dict object payload ${id} contains duplicate key '${key}'`);
          }
          target[key] = storeCollectionLoadedValue(target, value);
        }
      }
      function fillPairList(id, payload, placeholders) {
        if (!Array.isArray(payload)) {
          throw new Error(`PairList object payload ${id} must be an array`);
        }
        placeholders[id].list = payload.map((pair) => {
          const [key, value] = decodeKeyValueRecord(
            `PairList object payload ${id}`,
            pair,
            placeholders
          );
          return [key, storeCollectionLoadedValue(placeholders[id], value)];
        });
      }
      function fillSet(id, payload, placeholders) {
        for (const item of decodeItemPayload(
          `Set object payload ${id}`,
          payload,
          placeholders
        )) {
          placeholders[id].add(storeCollectionLoadedValue(placeholders[id], item));
        }
      }
      function fillBag(id, payload, placeholders) {
        placeholders[id].items = decodeItemPayload(
          `Bag object payload ${id}`,
          payload,
          placeholders
        ).map((item) => storeCollectionLoadedValue(placeholders[id], item));
      }
      function fillTime(id, payload, placeholders) {
        if (!Array.isArray(payload) || payload.length !== 1 && payload.length !== 2) {
          throw new Error(`Time object payload ${id} must contain epoch and optional timezone`);
        }
        const epoch = payload[0];
        if (typeof epoch !== "number") {
          throw new Error(`Time object payload ${id} epoch must be a number`);
        }
        placeholders[id]._epoch = epoch;
        placeholders[id]._timezone = payload.length > 1 && cbor.isTextString(payload[1]) ? cbor.textValue(payload[1]) : "UTC";
      }
      function fillPath(id, payload, placeholders) {
        assertRecordArray(payload, `Path object payload ${id}`, 1);
        const pathValue = payload[0];
        if (!cbor.isTextString(pathValue)) {
          throw new Error(`Path object payload ${id} path must be a text string`);
        }
        placeholders[id].value = cbor.textValue(pathValue);
      }
      function decodeFunctionPayload(id, payload, codeValues) {
        return decodeCodeBackedPayload("Function", id, payload, codeValues);
      }
      function decodeClassPayload(id, payload, codeValues) {
        return decodeCodeBackedPayload("Class", id, payload, codeValues);
      }
      function decodeTraitPayload(id, payload, codeValues) {
        return decodeCodeBackedPayload("Trait", id, payload, codeValues);
      }
      function decodeCodeBackedPayload(label, id, payload, codeValues) {
        assertRecordArray(payload, `${label} object payload ${id}`, 1);
        const codeId = payload[0];
        if (isWeakStorageRecord(codeId)) {
          throw new Error(`${label} object payload ${id} code id weak storage record is not allowed here`);
        }
        assertInteger(codeId, `${label} object payload ${id} code id`);
        if (codeId < 0 || codeId >= codeValues.length) {
          throw new Error(`${label} object payload ${id} code id is outside the code table`);
        }
        return codeValues[codeId];
      }
      function createBoundMethodPlaceholder(id) {
        const fn2 = function __zuzu_loaded_bound_method(...args) {
          const receiver = fn2.__zuzu_bound_receiver;
          const methodName = fn2.__zuzu_bound_method_name;
          if (receiver == null || typeof receiver[methodName] !== "function") {
            throw new Error(`Bound method object payload ${id} method is not loaded`);
          }
          return receiver[methodName](...args);
        };
        Object.defineProperty(fn2, "__zuzu_method", {
          value: true,
          enumerable: false,
          configurable: true
        });
        fn2.invoke = function invoke(_self, args = []) {
          return fn2(...args);
        };
        return fn2;
      }
      function fillBoundMethodPayload(id, payload, placeholders) {
        assertRecordArray(payload, `Bound method object payload ${id}`, 2);
        const receiver = decodeValue(payload[0], placeholders, {
          allowWeak: false,
          context: `Bound method object payload ${id} receiver`
        });
        if (receiver == null || typeof receiver !== "object") {
          throw new Error(`Bound method object payload ${id} receiver must resolve to an Object`);
        }
        if (!cbor.isTextString(payload[1])) {
          throw new Error(`Bound method object payload ${id} method name must be a text string`);
        }
        const methodName = cbor.textValue(payload[1]);
        if (typeof receiver[methodName] !== "function") {
          throw new Error(
            `Bound method object payload ${id} method '${methodName}' was not found`
          );
        }
        const fn2 = placeholders[id];
        Object.defineProperty(fn2, "__zuzu_bound_receiver", {
          value: receiver,
          enumerable: false,
          configurable: true,
          writable: true
        });
        Object.defineProperty(fn2, "__zuzu_bound_method_name", {
          value: methodName,
          enumerable: false,
          configurable: true,
          writable: true
        });
        fn2.invoke = function invoke(_self, args = []) {
          return receiver[methodName](...args);
        };
      }
      function fillObject(id, payload, placeholders) {
        assertRecordArray(payload, `Object payload ${id}`, 2);
        const [classRef, slotPayload] = payload;
        const klass = decodeValue(classRef, placeholders, {
          allowWeak: false,
          context: `Object payload ${id} class`
        });
        if (typeof klass !== "function") {
          throw new Error(`Object payload ${id} class must resolve to a Class`);
        }
        if (!Array.isArray(slotPayload)) {
          throw new Error(`Object payload ${id} slots must be an array`);
        }
        const object = placeholders[id];
        Object.setPrototypeOf(object, klass.prototype);
        const seen = /* @__PURE__ */ new Set();
        for (const record of slotPayload) {
          assertRecordArray(record, `Object payload ${id} slot records`, 2);
          const [nameValue, encodedValue] = record;
          if (!cbor.isTextString(nameValue)) {
            throw new Error(`Object payload ${id} slot names must be text strings`);
          }
          const name2 = cbor.textValue(nameValue);
          if (seen.has(name2)) {
            throw new Error(`Object payload ${id} contains duplicate slot '${name2}'`);
          }
          seen.add(name2);
          object[name2] = storeStrongLoadedValue(decodeValue(encodedValue, placeholders, {
            context: `Object payload ${id} slot '${name2}'`
          }));
        }
      }
      function runOnLoadHooks(objects, placeholders) {
        for (let id = 0; id < objects.length; id++) {
          const [kind] = objects[id];
          if (kind !== KIND_OBJECT) {
            continue;
          }
          const object = placeholders[id];
          if (typeof object.__on_load__ === "function") {
            try {
              object.__on_load__();
            } catch (err) {
              throw new Error(
                `__on_load__ for ${typeName2(object)} failed: ${err.message || err}`
              );
            }
          }
        }
      }
      function decodeItemPayload(context, payload, placeholders) {
        if (!Array.isArray(payload)) {
          throw new Error(`${context} must be an array`);
        }
        return payload.map((item) => decodeValue(item, placeholders, {
          context: `${context} item`
        }));
      }
      function decodeKeyValueRecord(context, pair, placeholders) {
        assertRecordArray(pair, `${context} entries`, 2);
        const [key, value] = pair;
        if (!cbor.isTextString(key)) {
          throw new Error(`${context} keys must be text strings`);
        }
        return [
          cbor.textValue(key),
          decodeValue(value, placeholders, {
            context: `${context} value`
          })
        ];
      }
      function decodeValue(value, placeholders, opts = {}) {
        const allowWeak = Object.prototype.hasOwnProperty.call(opts, "allowWeak") ? opts.allowWeak : true;
        const context = opts.context || "Encoded value";
        if (isEncodedScalar(value)) {
          return decodeScalar(value);
        }
        if (Array.isArray(value)) {
          if (value.length !== 2) {
            throw new Error(`${context} array must be [0, id] or [1, value]`);
          }
          const [marker, id] = value;
          if (!isInteger(marker) || marker !== 0 && marker !== 1) {
            throw new Error(`${context} marker must be 0 or 1`);
          }
          if (marker === 1) {
            validateWeakStorageRecord(value, placeholders, context);
            if (!allowWeak) {
              throw new Error(`${context} weak storage record is not allowed here`);
            }
            return makeWeakValue(decodeValue(id, placeholders, {
              allowWeak: false,
              context: `${context} weak storage value`
            }));
          }
          if (!isInteger(id)) {
            throw new Error("Encoded reference id must be an integer");
          }
          if (id < 0 || id >= placeholders.length) {
            throw new Error(`Reference id ${id} is outside the object table`);
          }
          return placeholders[id];
        }
        throw new Error("Envelope root is not a scalar or supported reference");
      }
      function storeStrongLoadedValue(value) {
        return isWeakCell(value) ? value : retainValue(value);
      }
      function storeCollectionLoadedValue(owner, value) {
        return isWeakCell(value) ? value : retainCollectionValue(owner, value);
      }
      function validateWeakStorageRecord(record, placeholders, context) {
        assertRecordArray(record, `${context} weak storage record`, 2);
        const inner = record[1];
        if (isWeakStorageRecord(inner)) {
          throw new Error(`${context} nested weak storage records are invalid`);
        }
        decodeValue(inner, placeholders, {
          allowWeak: false,
          context: `${context} weak storage value`
        });
      }
      function isWeakStorageRecord(value) {
        return Array.isArray(value) && value.length === 2 && value[0] === 1;
      }
      function isEncodedScalar(value) {
        return value == null || typeof value === "boolean" || typeof value === "number" || cbor.isTextString(value) || cbor.isByteString(value);
      }
      function decodeScalar(value) {
        if (value == null) {
          return null;
        }
        if (typeof value === "boolean" || typeof value === "number") {
          return value;
        }
        if (cbor.isTextString(value)) {
          return cbor.textValue(value);
        }
        if (cbor.isByteString(value)) {
          return new BinaryString2(cbor.bytesValue(value));
        }
        throw new Error("Envelope root is not a scalar value");
      }
      function assertRecordArray(value, context, length) {
        if (!Array.isArray(value) || value.length !== length) {
          const item = length === 1 ? "one-item" : `${length}-item`;
          throw new Error(`${context} must be a ${item} array`);
        }
      }
      function assertInteger(value, context) {
        if (!isInteger(value)) {
          throw new Error(`${context} must be an integer`);
        }
      }
      function isInteger(value) {
        return typeof value === "number" && Number.isInteger(value);
      }
      function isPlainDict(value) {
        if (value == null || typeof value !== "object") {
          return false;
        }
        if (value instanceof ZuzuBinary || value instanceof Pair || isPairListLike(value)) {
          return false;
        }
        if (value instanceof Set || value instanceof ZuzuBag || Array.isArray(value)) {
          return false;
        }
        if (isTimeValue(value) || isPathValue(value)) {
          return false;
        }
        const proto = Object.getPrototypeOf(value);
        if (proto === null || proto === Object.prototype) {
          return true;
        }
        return Object.prototype.toString.call(value) === "[object Object]" && value.constructor && value.constructor.name === "Object";
      }
      function isUserObjectValue(value) {
        return value && typeof value === "object" && !Array.isArray(value) && isUserClassValue(value.constructor) && !isTimeValue(value) && !isPathValue(value);
      }
      function isFunctionValue(value) {
        return typeof value === "function" && !isUserClassValue(value) && value.__zuzu_marshal_meta && value.__zuzu_marshal_meta.kind === "function";
      }
      function isUserClassValue(value) {
        return typeof value === "function" && typeof value.__zuzu_class_name === "string" && value.__zuzu_class_spec && typeof value.__zuzu_class_spec === "object";
      }
      function isTraitValue(value) {
        return value && typeof value === "object" && value.__zuzu_trait_methods && typeof value.__zuzu_trait_name === "string";
      }
      function isBoundMethodValue(value) {
        return value && (value.__zuzu_method || value.constructor && value.constructor.name === "ZuzuMethod");
      }
      function isScalarForCapture(value) {
        return value == null || typeof value === "boolean" || typeof value === "number" || typeof value === "string" || value instanceof ZuzuBinary;
      }
      function isMarshalableObjectSlot(value) {
        return typeof value !== "function";
      }
      function isTimeValue(value) {
        return value && typeof value === "object" && (value.__zuzu_type_name === "Time" || value.constructor && value.constructor.name === "Time") && (typeof value.epoch === "function" || typeof value._epoch === "number");
      }
      function isPathValue(value) {
        return value && typeof value === "object" && value.constructor && value.constructor.name === "Path" && (typeof value.to_String === "function" || typeof value.value === "string");
      }
      function timeClass() {
        return require_time().Time;
      }
      function pathClass() {
        if (runtimePolicy2.host_name === "browser") {
          throw new Error("UnmarshallingException: Path requires std/io");
        }
        const dynamicRequire = __require;
        return dynamicRequire("../io").Path;
      }
      function marshalBindingName(rawName, id) {
        const name2 = String(rawName || "");
        if (/^[A-Za-z_][A-Za-z0-9_]*$/u.test(name2)) {
          return name2;
        }
        return `__zuzu_marshal_class_${id}`;
      }
      function marshalClassSource(klass, bindingName) {
        const fields = classFields(klass).map(sourceField).join("\n");
        return fields ? `class ${bindingName} {
${fields}
}` : `class ${bindingName} {}`;
      }
      function classFields(klass) {
        const spec = klass.__zuzu_class_spec || {};
        return Array.isArray(spec.fields) ? spec.fields : [];
      }
      function sourceField(field) {
        const kind = field.kind === "const" ? "const" : "let";
        const typeName3 = field.typeName ? `${field.typeName} ` : "";
        const accessors = Array.isArray(field.accessors) && field.accessors.length > 0 ? ` with ${field.accessors.join(", ")}` : "";
        return `	${kind} ${typeName3}${field.name}${accessors};`;
      }
      function registerCodeValue(kind, bindingName, source, value) {
        codeRegistry.set(codeRegistryKey(kind, bindingName, source), value);
        if (kind === CODE_CLASS) {
          classRegistry.set(classRegistryKey(bindingName, source), value);
        }
      }
      function classRegistryKey(bindingName, source) {
        return `${bindingName}\0${source}`;
      }
      function codeRegistryKey(kind, bindingName, source) {
        return `${kind}\0${bindingName}\0${source}`;
      }
      function buildFunctionFromSource(bindingName, source, env = {}) {
        const names = Object.keys(env);
        const values = names.map((name2) => env[name2]);
        let fn2;
        if (["node", "browser", "electron"].includes(runtimePolicy2.host_name)) {
          try {
            fn2 = buildFunctionWithRuntime(bindingName, source, env);
          } catch (runtimeErr) {
            try {
              fn2 = Function(...names, `return ( ${source} );`)(...values);
            } catch (rawErr) {
              fn2 = unloadedFunction(bindingName, runtimeErr, rawErr);
            }
          }
        } else {
          try {
            fn2 = Function(...names, `return ( ${source} );`)(...values);
          } catch (rawErr) {
            fn2 = unloadedFunction(bindingName, rawErr);
          }
        }
        Object.defineProperty(fn2, "__zuzu_marshal_meta", {
          value: {
            kind: "function",
            name: bindingName,
            source,
            captures: env
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
        return fn2;
      }
      function unloadedFunction(bindingName, ...errors) {
        return function __zuzu_loaded_function() {
          const err = errors.find((item) => item && item.message);
          const message = err ? err.message : `Loaded function '${bindingName}' is not executable in JS`;
          throw new Error(message);
        };
      }
      function buildFunctionWithRuntime(bindingName, source, env = {}) {
        if (runtimePolicy2.host_name && !["node", "browser", "electron"].includes(runtimePolicy2.host_name)) {
          throw new Error(`Loaded function '${bindingName}' is not executable in JS`);
        }
        const denyCapabilities = [];
        for (const capability of [
          "fs",
          "net",
          "perl",
          "js",
          "proc",
          "db",
          "clib",
          "gui",
          "worker"
        ]) {
          if (runtimePolicy2[`deny_${capability}`]) {
            denyCapabilities.push(capability);
          }
        }
        const runtimeOptions = {
          repoRoot: runtimePolicy2.repo_root || void 0,
          includePaths: runtimePolicy2.include_paths || [],
          denyCapabilities,
          denyModules: runtimePolicy2.deny_modules || [],
          debugLevel: runtimePolicy2.debug_level || 0,
          transpiler: runtimePolicy2.transpiler || void 0
        };
        let runtime;
        if (runtimePolicy2.host_name === "browser") {
          const { createBrowserRuntime } = require_browser_runtime();
          const defaults = typeof globalThis !== "undefined" && globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__ && typeof globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__ === "object" ? globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__ : {};
          runtime = createBrowserRuntime({
            ...defaults,
            ...runtimeOptions
          }).runtime;
        } else {
          const entrypointsModule = "../../../lib/runtime-entrypoints";
          const { createNodeRuntime } = __require(entrypointsModule);
          runtime = createNodeRuntime(runtimeOptions);
        }
        const js = runtime.transpile(
          `let __zuzu_marshal_value := ${source};
__global__{__zuzu_marshal_result} := __zuzu_marshal_value;`
        );
        const context = runtime.buildContext({
          filename: "<std/marshal-code>",
          globals: env
        });
        context.__global__ = /* @__PURE__ */ Object.create(null);
        runtime.installCollectionMethods(context);
        runtime.host.runInContext(
          js,
          context,
          { filename: "<std/marshal-code>" }
        );
        const fn2 = context.__global__.__zuzu_marshal_result;
        if (typeof fn2 !== "function") {
          throw new Error(`Loaded function '${bindingName}' is not executable in JS`);
        }
        return fn2;
      }
      function buildClassFromSource(bindingName, source, env = {}) {
        const spec = parseClassSource(source, env);
        return buildMarshalClass(
          bindingName,
          spec.baseName ? env[spec.baseName] : null,
          spec.fields,
          spec.methods,
          spec.statics,
          spec.traitNames.map((name2) => env[name2]).filter(isTraitValue),
          env,
          source
        );
      }
      function buildTraitFromSource(bindingName, source, env = {}) {
        const trait = {
          __zuzu_trait_name: bindingName,
          __zuzu_trait_methods: parseMethods(source, env).methods
        };
        Object.defineProperty(trait, "__zuzu_marshal_meta", {
          value: {
            kind: "trait",
            name: bindingName,
            source,
            captures: env
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
        return trait;
      }
      function parseClassSource(source, env = {}) {
        return {
          baseName: parseClassBaseName(source),
          fields: parseClassFields(source),
          traitNames: parseClassTraitNames(source),
          ...parseMethods(source, env)
        };
      }
      function parseClassBaseName(source) {
        const match = String(source || "").match(
          /\bclass\s+[A-Za-z_][A-Za-z0-9_]*\s+extends\s+([A-Za-z_][A-Za-z0-9_]*)/u
        );
        return match ? match[1] : null;
      }
      function parseClassFields(source) {
        const body = String(source || "").replace(/\/\*[\s\S]*?\*\//gu, "");
        const fields = [];
        const byName = /* @__PURE__ */ new Map();
        const rx = /\b(let|const)\s+(?:(Null|Any|Boolean|Number|String|BinaryString|Array|Dict|PairList|Set|Bag|Pair|Time|Path|Object)\s+)?([A-Za-z_][A-Za-z0-9_]*)(?:\s+with\s+([^;:=]+?))?\s*(?::=\s*([^;]*))?;/gu;
        let match = rx.exec(body);
        while (match) {
          const field = {
            kind: match[1],
            typeName: match[2] || null,
            name: match[3],
            accessors: match[4] ? match[4].split(",").map((item) => item.trim()).filter(Boolean) : [],
            defaultSource: match[5] ? match[5].trim() : null
          };
          fields.push(field);
          byName.set(field.name, field);
          match = rx.exec(body);
        }
        const methodRx = /\bmethod\s+(get|set|clear|has)_([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)/gu;
        let methodMatch = methodRx.exec(body);
        while (methodMatch) {
          const field = byName.get(methodMatch[2]);
          if (field && !field.accessors.includes(methodMatch[1])) {
            field.accessors.push(methodMatch[1]);
          }
          if (field && methodMatch[1] === "set" && !field.typeName) {
            const typeMatch = methodMatch[3].match(/\b(Null|Any|Boolean|Number|String|BinaryString|Array|Dict|PairList|Set|Bag|Pair|Time|Path|Object)\s+[A-Za-z_][A-Za-z0-9_]*\b/u);
            if (typeMatch) {
              field.typeName = typeMatch[1];
            }
          }
          methodMatch = methodRx.exec(body);
        }
        return fields;
      }
      function parseClassTraitNames(source) {
        const match = String(source || "").match(
          /\bclass\s+[A-Za-z_][A-Za-z0-9_]*(?:\s+extends\s+[A-Za-z_][A-Za-z0-9_]*)?\s+(?:with|but)\s+([^{;]+)/u
        );
        if (!match) {
          return [];
        }
        return match[1].split(",").map((item) => item.trim()).filter((item) => /^[A-Za-z_][A-Za-z0-9_]*$/u.test(item));
      }
      function parseMethods(source, env = {}) {
        const text = String(source || "").replace(/\/\*[\s\S]*?\*\//gu, "");
        const methods = {};
        const statics = {};
        const rx = /\b(static\s+)?method\s+([A-Za-z_][A-Za-z0-9_]*)\s*\(([^)]*)\)\s*(?:->\s*[A-Za-z_][A-Za-z0-9_]*)?\s*\{([\s\S]*?)\}/gu;
        let match = rx.exec(text);
        while (match) {
          const target = match[1] ? statics : methods;
          target[match[2]] = compileSimpleMethod(
            match[2],
            parseParamNames(match[3]),
            match[4],
            env
          );
          match = rx.exec(text);
        }
        return { methods, statics };
      }
      function parseParamNames(source) {
        return String(source || "").split(",").map((item) => item.trim()).filter(Boolean).map((item) => {
          const match = item.match(/([A-Za-z_][A-Za-z0-9_]*)$/u);
          return match ? match[1] : null;
        }).filter(Boolean);
      }
      function compileSimpleMethod(name2, paramNames, body, env) {
        const match = String(body || "").match(/\breturn\s+([\s\S]*?)\s*;/u);
        if (!match) {
          return function _loaded_method() {
            return null;
          };
        }
        const expression = match[1];
        return {
          [name2]: function _loaded_method(...args) {
            const params = /* @__PURE__ */ Object.create(null);
            for (let i = 0; i < paramNames.length; i++) {
              params[paramNames[i]] = args[i];
            }
            return evalSimpleExpression(expression, this, env, params);
          }
        }[name2];
      }
      function evalSimpleExpression(source, self, env = {}, params = {}) {
        const expression = normalizeSimpleExpression(source);
        const envNames = Object.keys(env);
        const paramNames = Object.keys(params);
        const fn2 = Function(
          "self",
          ...envNames,
          ...paramNames,
          `with ( self ) { return ( ${expression} ); }`
        );
        return fn2(
          self || {},
          ...envNames.map((name2) => env[name2]),
          ...paramNames.map((name2) => params[name2])
        );
      }
      function normalizeSimpleExpression(source) {
        return String(source || "null").replace(/\s+_\s+/gu, " + ");
      }
      function buildMarshalClass(name2, base = null, fields, methods = {}, statics = {}, traits = [], env = {}, source = "") {
        const parent = typeof base === "function" ? base : Object;
        const ctor = {
          [name2]: class extends parent {
            constructor(initial = {}) {
              super(initial);
              for (const field of fields) {
                let value = field.defaultSource ? evalSimpleExpression(field.defaultSource, this, env) : null;
                if (isPairListLike(initial)) {
                  value = initial.get(field.name, value);
                } else if (initial && typeof initial === "object" && Object.prototype.hasOwnProperty.call(initial, field.name)) {
                  value = initial[field.name];
                }
                this[field.name] = value;
              }
            }
          }
        }[name2];
        for (const field of fields) {
          if (!Array.isArray(field.accessors)) {
            continue;
          }
          if (field.accessors.includes("get")) {
            ctor.prototype[`get_${field.name}`] = function _get_field() {
              return this[field.name];
            };
          }
          if (field.accessors.includes("set")) {
            ctor.prototype[`set_${field.name}`] = function _set_field(value) {
              if (field.typeName && value != null && !typeMatches(value, field.typeName)) {
                throw new Error(
                  `TypeException: field '${field.name}' must be ${field.typeName}, got ${typeName2(value)}`
                );
              }
              this[field.name] = value;
              return this;
            };
          }
        }
        for (const trait of traits) {
          for (const [methodName, fn2] of Object.entries(trait.__zuzu_trait_methods)) {
            if (typeof fn2 === "function" && typeof ctor.prototype[methodName] !== "function") {
              ctor.prototype[methodName] = fn2;
            }
          }
        }
        const generatedAccessors = /* @__PURE__ */ new Set();
        for (const field of fields) {
          for (const accessor of field.accessors || []) {
            generatedAccessors.add(`${accessor}_${field.name}`);
          }
        }
        for (const [methodName, fn2] of Object.entries(methods)) {
          if (generatedAccessors.has(methodName)) {
            continue;
          }
          ctor.prototype[methodName] = fn2;
        }
        for (const [methodName, fn2] of Object.entries(statics)) {
          ctor[methodName] = fn2;
        }
        Object.defineProperty(ctor, "__zuzu_class_name", {
          value: name2,
          enumerable: false,
          configurable: true,
          writable: true
        });
        Object.defineProperty(ctor, "__zuzu_class_spec", {
          value: { fields, traits, methods, statics, nested: {} },
          enumerable: false,
          configurable: true,
          writable: true
        });
        Object.defineProperty(ctor, "__zuzu_marshal_meta", {
          value: {
            kind: "class",
            name: name2,
            source,
            captures: env
          },
          enumerable: false,
          configurable: true,
          writable: true
        });
        return ctor;
      }
      function typeMatches(value, expected) {
        if (expected === "Any" || expected == null) {
          return true;
        }
        if (expected === "Null") {
          return value == null;
        }
        if (expected === "Boolean") {
          return typeof value === "boolean";
        }
        if (expected === "Number") {
          return typeof value === "number";
        }
        if (expected === "String") {
          return typeof value === "string";
        }
        if (expected === "BinaryString") {
          return value instanceof BinaryString2;
        }
        if (expected === "Array") {
          return Array.isArray(value);
        }
        if (expected === "Dict") {
          return isPlainDict(value);
        }
        if (expected === "PairList") {
          return isPairListLike(value);
        }
        if (expected === "Set") {
          return value instanceof Set;
        }
        if (expected === "Bag") {
          return value instanceof ZuzuBag;
        }
        if (expected === "Pair") {
          return value instanceof Pair;
        }
        if (expected === "Time") {
          return isTimeValue(value);
        }
        if (expected === "Path") {
          return isPathValue(value);
        }
        return true;
      }
      function typeName2(value) {
        if (value == null) {
          return "Null";
        }
        if (value instanceof BinaryString2) {
          return "BinaryString";
        }
        if (typeof value === "boolean") {
          return "Boolean";
        }
        if (typeof value === "number") {
          return "Number";
        }
        if (typeof value === "string") {
          return "String";
        }
        if (Array.isArray(value)) {
          return "Array";
        }
        if (value && value.constructor && value.constructor.name) {
          return value.constructor.name;
        }
        return typeof value;
      }
      module2.exports = {
        dumpGraph,
        loadGraph,
        safeToDumpGraph,
        setRuntimePolicy: setRuntimePolicy2
      };
    }
  });

  // modules/std/marshal.js
  var require_marshal = __commonJS({
    "modules/std/marshal.js"(exports2, module2) {
      "use strict";
      var cbor = require_cbor();
      var {
        dumpGraph,
        loadGraph,
        safeToDumpGraph,
        setRuntimePolicy: setRuntimePolicy2
      } = require_graph();
      var MarshallingException = class extends Error {
        constructor(message = "std/marshal.dump failed") {
          super(String(message));
          this.name = "MarshallingException";
        }
        to_String() {
          return `${this.name}: ${this.message}`;
        }
      };
      var UnmarshallingException = class extends Error {
        constructor(message = "std/marshal.load failed") {
          super(String(message));
          this.name = "UnmarshallingException";
        }
        to_String() {
          return `${this.name}: ${this.message}`;
        }
      };
      function dump(value) {
        assertArity("dump", arguments.length, 1);
        try {
          return dumpGraph(value);
        } catch (err) {
          throw new MarshallingException(
            `std/marshal.dump failed: ${err.message || err}`
          );
        }
      }
      function load(blob) {
        assertArity("load", arguments.length, 1);
        try {
          return loadGraph(blob);
        } catch (err) {
          if (String(err && err.message || err).startsWith("TypeException:")) {
            throw err;
          }
          throw new UnmarshallingException(
            `std/marshal.load failed: ${err.message || err}`
          );
        }
      }
      function safe_to_dump(value) {
        assertArity("safe_to_dump", arguments.length, 1);
        return safeToDumpGraph(value);
      }
      function assertArity(name2, got, expected) {
        if (got !== expected) {
          throw new Error(
            `TypeException: ${name2} expects ${expected} argument, got ${got}`
          );
        }
      }
      module2.exports = {
        dump,
        load,
        safe_to_dump,
        MarshallingException,
        UnmarshallingException,
        __zuzu_set_runtime_policy: setRuntimePolicy2
      };
      Object.defineProperty(module2.exports, "__cbor", {
        value: cbor,
        enumerable: false,
        configurable: false,
        writable: false
      });
    }
  });

  // modules/std/worker.js
  var require_worker = __commonJS({
    "modules/std/worker.js"(exports2, module2) {
      "use strict";
      var { BinaryString: BinaryString2, PairList } = require_runtime_helpers();
      var taskRuntime2 = require_task();
      var { CancelledException, ChannelClosedException, Task } = taskRuntime2;
      var marshal = require_marshal();
      var DENIAL_CAPABILITIES = [
        "fs",
        "net",
        "perl",
        "js",
        "proc",
        "db",
        "clib",
        "gui",
        "worker"
      ];
      var runtimePolicy2 = {
        host_name: "node",
        repo_root: null,
        include_paths: [],
        deny_modules: [],
        debug_level: 0,
        transpiler: null,
        browser_worker_source: null,
        browser_worker_url: null,
        browser_worker_factory: null
      };
      function setRuntimePolicy2(policy = {}) {
        runtimePolicy2 = {
          ...runtimePolicy2,
          ...policy,
          include_paths: Array.isArray(policy.include_paths) ? policy.include_paths.slice() : runtimePolicy2.include_paths,
          deny_modules: Array.isArray(policy.deny_modules) ? policy.deny_modules.slice() : runtimePolicy2.deny_modules
        };
        marshal.__zuzu_set_runtime_policy(runtimePolicy2);
      }
      function loadWorkerThreads() {
        if (runtimePolicy2.host_name === "browser") {
          return null;
        }
        try {
          return __require("node:worker_threads");
        } catch (_err) {
          return null;
        }
      }
      function loadNodePath() {
        try {
          return __require("node:path");
        } catch (_err) {
          return null;
        }
      }
      function browserRoot() {
        return typeof globalThis !== "undefined" ? globalThis : null;
      }
      function browserWorkerSource() {
        const root = browserRoot();
        return runtimePolicy2.browser_worker_source || root && root.__ZUZU_BROWSER_WORKER_SOURCE__ || null;
      }
      function browserWorkerUrl() {
        const root = browserRoot();
        return runtimePolicy2.browser_worker_url || root && root.__ZUZU_BROWSER_WORKER_URL__ || null;
      }
      function loadBrowserWorkerFactory() {
        if (runtimePolicy2.host_name !== "browser") {
          return null;
        }
        if (typeof runtimePolicy2.browser_worker_factory === "function") {
          return runtimePolicy2.browser_worker_factory;
        }
        const root = browserRoot();
        if (root && typeof root.__ZUZU_BROWSER_WORKER_FACTORY__ === "function") {
          return root.__ZUZU_BROWSER_WORKER_FACTORY__;
        }
        return null;
      }
      function assertWorkerCapability(label) {
        if (runtimePolicy2.deny_worker) {
          throw new Error(`${label} is denied by runtime policy`);
        }
      }
      function createBrowserWorker() {
        const factory = loadBrowserWorkerFactory();
        const source = browserWorkerSource();
        const url = browserWorkerUrl();
        if (factory) {
          return factory({
            source,
            url,
            name: "zuzu-browser-worker"
          });
        }
        const root = browserRoot();
        if (!root || typeof root.Worker !== "function") {
          return null;
        }
        if (url) {
          return new root.Worker(url);
        }
        if (source && typeof root.Blob === "function" && root.URL && typeof root.URL.createObjectURL === "function") {
          const blob = new root.Blob([source], { type: "text/javascript" });
          const objectUrl = root.URL.createObjectURL(blob);
          return new root.Worker(objectUrl);
        }
        return null;
      }
      function isPairList(value) {
        return value instanceof PairList || value && typeof value === "object" && Array.isArray(value.list) && typeof value.has === "function" && typeof value.get === "function";
      }
      function typeName2(value) {
        if (value == null) {
          return "Null";
        }
        if (isPairList(value)) {
          return "PairList";
        }
        if (Array.isArray(value)) {
          return "Array";
        }
        if (typeof value === "function") {
          return "Function";
        }
        if (typeof value === "boolean") {
          return "Boolean";
        }
        if (typeof value === "number") {
          return "Number";
        }
        if (typeof value === "string") {
          return "String";
        }
        if (value && value.__zuzu_type_name) {
          return String(value.__zuzu_type_name);
        }
        if (value && value.constructor && value.constructor.name) {
          return value.constructor.name;
        }
        return "Object";
      }
      function namedOptionMap(namedArgs) {
        const out = /* @__PURE__ */ Object.create(null);
        if (!namedArgs) {
          return out;
        }
        for (const pair of namedArgs.list || []) {
          if (Array.isArray(pair) && pair.length >= 2) {
            out[String(pair[0])] = pair[1];
          }
        }
        return out;
      }
      function parseWorkerOptions(namedArgs) {
        const named = namedOptionMap(namedArgs);
        const extraDenials = [];
        const refusedRelaxations = [];
        for (const key of Object.keys(named).sort()) {
          if (!key.startsWith("deny_")) {
            throw new Error(`Unknown named argument '${key}' for Worker.spawn`);
          }
          const capability = key.slice("deny_".length);
          if (!DENIAL_CAPABILITIES.includes(capability)) {
            throw new Error(`Unknown named argument '${key}' for Worker.spawn`);
          }
          if (typeof named[key] !== "boolean") {
            throw new Error(
              `TypeException: Worker.spawn named argument '${key}' expects Boolean, got ${typeName2(named[key])}`
            );
          }
          if (named[key]) {
            extraDenials.push(capability);
          } else if (runtimePolicy2[key]) {
            refusedRelaxations.push(capability);
          }
        }
        return { extraDenials, refusedRelaxations };
      }
      function effectivePolicy(extraDenials) {
        const policy = {
          host_name: runtimePolicy2.host_name,
          repo_root: runtimePolicy2.repo_root,
          include_paths: (runtimePolicy2.include_paths || []).slice(),
          deny_modules: (runtimePolicy2.deny_modules || []).slice(),
          debug_level: runtimePolicy2.debug_level,
          transpiler: runtimePolicy2.transpiler
        };
        for (const capability of DENIAL_CAPABILITIES) {
          policy[`deny_${capability}`] = Boolean(runtimePolicy2[`deny_${capability}`]) || extraDenials.includes(capability);
        }
        return policy;
      }
      function taskException(message) {
        const err = new Error(String(message || "worker failed"));
        err.name = "Exception";
        err.to_String = function toString() {
          return `Exception: ${this.message}`;
        };
        return err;
      }
      var Worker = class {
        static spawn(...rawArgs) {
          assertWorkerCapability("Worker.spawn");
          let namedArgs = null;
          if (rawArgs.length > 0 && isPairList(rawArgs[rawArgs.length - 1])) {
            namedArgs = rawArgs.pop();
          }
          if (rawArgs.length < 1 || rawArgs.length > 2) {
            throw new Error("Worker.spawn expects Callable and optional Array arguments");
          }
          const callable = rawArgs[0];
          if (typeof callable !== "function") {
            throw new Error(
              `TypeException: Worker.spawn expects Function, got ${typeName2(callable)}`
            );
          }
          const workerArgs = rawArgs.length > 1 ? rawArgs[1] : [];
          if (!Array.isArray(workerArgs)) {
            throw new Error(
              `TypeException: Worker.spawn expects Array arguments, got ${typeName2(workerArgs)}`
            );
          }
          const threads = loadWorkerThreads();
          const browserMode = runtimePolicy2.host_name === "browser";
          if (!threads && !browserMode) {
            throw new Error("std/worker transport is unavailable");
          }
          const { extraDenials, refusedRelaxations } = parseWorkerOptions(namedArgs);
          if (refusedRelaxations.length > 0) {
            return Task.failed(taskException(
              `Denied capability '${refusedRelaxations[0]}' cannot be relaxed for worker`
            ));
          }
          let requestBytes;
          try {
            requestBytes = marshal.dump([callable, workerArgs]);
          } catch (err) {
            throw err;
          }
          if (browserMode) {
            return spawnBrowserWorker(requestBytes, extraDenials);
          }
          return spawnNodeWorker(threads, requestBytes, extraDenials);
        }
        static spawn_handle(...rawArgs) {
          assertWorkerCapability("Worker.spawn_handle");
          let namedArgs = null;
          if (rawArgs.length > 0 && isPairList(rawArgs[rawArgs.length - 1])) {
            namedArgs = rawArgs.pop();
          }
          if (rawArgs.length < 1 || rawArgs.length > 2) {
            throw new Error(
              "Worker.spawn_handle expects Callable and optional Array arguments"
            );
          }
          const callable = rawArgs[0];
          if (typeof callable !== "function") {
            throw new Error(
              `TypeException: Worker.spawn_handle expects Function, got ${typeName2(callable)}`
            );
          }
          const workerArgs = rawArgs.length > 1 ? rawArgs[1] : [];
          if (!Array.isArray(workerArgs)) {
            throw new Error(
              `TypeException: Worker.spawn_handle expects Array arguments, got ${typeName2(workerArgs)}`
            );
          }
          const threads = loadWorkerThreads();
          const browserMode = runtimePolicy2.host_name === "browser";
          if (!threads && !browserMode) {
            throw new Error("std/worker transport is unavailable");
          }
          const { extraDenials, refusedRelaxations } = parseWorkerOptions(namedArgs);
          if (refusedRelaxations.length > 0) {
            const task = Task.failed(taskException(
              `Denied capability '${refusedRelaxations[0]}' cannot be relaxed for worker`
            ));
            return new WorkerHandle(null, {
              resultTask: task,
              remoteClosed: true
            });
          }
          const requestBytes = marshal.dump([callable, workerArgs]);
          if (browserMode) {
            return spawnBrowserWorkerHandle(requestBytes, extraDenials);
          }
          return spawnNodeWorkerHandle(threads, requestBytes, extraDenials);
        }
      };
      var WorkerHandle = class {
        constructor(transport, options = {}) {
          this._transport = transport;
          this._queue = [];
          this._receivers = [];
          this._localClosed = false;
          this._remoteClosed = Boolean(options.remoteClosed);
          this._cancelled = false;
          this._remoteError = null;
          this._nextOutgoingSeq = 1;
          this._nextIncomingSeq = 1;
          this._incomingFrames = /* @__PURE__ */ new Map();
          this._resultTask = options.resultTask || new Task(null, {
            status: "running",
            name: "WorkerHandle.result",
            cancel: (reason) => this.cancel(reason)
          });
        }
        send(value = null) {
          if (this._localClosed || this._remoteClosed || this._cancelled) {
            return Task.failed(
              new ChannelClosedException("send on closed worker handle")
            );
          }
          let bytes;
          try {
            bytes = marshal.dump(value);
          } catch (err) {
            return Task.failed(err);
          }
          try {
            this._post({
              type: "message",
              bytes: Array.from(bytes.bytes)
            });
          } catch (err) {
            this._closeRemote(err);
            return Task.failed(err);
          }
          return Task.resolved(value);
        }
        recv() {
          if (this._queue.length > 0) {
            return Task.resolved(this._queue.shift());
          }
          if (this._cancelled) {
            return Task.failed(new CancelledException("worker cancelled"));
          }
          if (this._remoteClosed) {
            return Task.failed(
              new ChannelClosedException("worker handle closed")
            );
          }
          const task = new Task(null, {
            status: "waiting",
            name: "WorkerHandle.recv",
            cancel: () => {
              this._receivers = this._receivers.filter((item) => item !== task);
            }
          });
          this._receivers.push(task);
          return task;
        }
        close() {
          if (this._localClosed) {
            return Task.resolved(null);
          }
          this._localClosed = true;
          try {
            this._post({ type: "close" });
          } catch (_err) {
          }
          return Task.resolved(null);
        }
        cancel(reason = null) {
          if (this._cancelled) {
            return this;
          }
          this._cancelled = true;
          this._localClosed = true;
          this._remoteClosed = true;
          const err = reason instanceof Error ? reason : new CancelledException(reason == null ? "worker cancelled" : reason);
          this._rejectReceivers(err, true);
          try {
            this._post({
              type: "cancel",
              reason: err.message || String(err)
            });
          } catch (_err) {
          }
          if (this._transport && typeof this._transport.terminate === "function") {
            this._transport.terminate();
          }
          if (!this._resultTask.done()) {
            this._resultTask.cancel(err);
          }
          return this;
        }
        result() {
          return this._resultTask;
        }
        status() {
          return this._resultTask.status();
        }
        done() {
          return this._resultTask.done();
        }
        _post(message) {
          if (!this._transport || typeof this._transport.postMessage !== "function") {
            throw taskException("worker transport is closed");
          }
          const payload = { ...message };
          if (["message", "close", "cancel"].includes(payload.type) && !Number.isInteger(payload.seq)) {
            payload.seq = this._nextOutgoingSeq++;
          }
          this._transport.postMessage(payload);
        }
        _deliverBytes(bytes) {
          let value;
          try {
            value = marshal.load(new BinaryString2(bytes || []));
          } catch (err) {
            this._closeRemote(err);
            return;
          }
          const receiver = this._receivers.shift();
          if (receiver) {
            receiver._resolve(value);
          } else {
            this._queue.push(value);
          }
        }
        _resolveResultBytes(bytes) {
          try {
            this._resultTask._resolve(
              marshal.load(new BinaryString2(bytes || []))
            );
          } catch (err) {
            this._resultTask._reject(err);
          }
        }
        _rejectResult(err) {
          if (!this._resultTask.done()) {
            this._resultTask._reject(err);
          }
        }
        _closeRemote(err = null) {
          this._remoteClosed = true;
          if (err) {
            this._remoteError = err;
          }
          this._rejectReceivers(
            err || this._remoteError || new ChannelClosedException("worker handle closed"),
            false
          );
        }
        _rejectReceivers(err, forceCancel = false) {
          while (this._receivers.length > 0) {
            this._receivers.shift()._reject(
              err,
              forceCancel ? "cancelled" : null
            );
          }
        }
        _receiveFrame(message) {
          if (Number.isInteger(message.seq)) {
            this._incomingFrames.set(message.seq, message);
            while (this._incomingFrames.has(this._nextIncomingSeq)) {
              const next = this._incomingFrames.get(this._nextIncomingSeq);
              this._incomingFrames.delete(this._nextIncomingSeq);
              this._nextIncomingSeq++;
              processWorkerHandleMessage(this, next);
            }
            return;
          }
          processWorkerHandleMessage(this, message);
        }
      };
      Object.defineProperty(WorkerHandle.prototype, "__zuzu_type_name", {
        value: "WorkerHandle",
        enumerable: false,
        configurable: true,
        writable: true
      });
      function spawnNodeWorker(threads, requestBytes, extraDenials) {
        const nodePath = loadNodePath();
        if (!threads || !nodePath) {
          throw new Error("std/worker transport is unavailable");
        }
        const task = new Task(null, {
          status: "running",
          name: "Worker.spawn"
        });
        const nodeWorker = new threads.Worker(
          nodePath.join(__dirname, "worker-thread.js"),
          {
            workerData: {
              request_bytes: Array.from(requestBytes.bytes),
              policy: effectivePolicy(extraDenials)
            }
          }
        );
        task._cancelHook = function cancelWorker() {
          nodeWorker.terminate().catch(() => {
          });
        };
        let settled = false;
        nodeWorker.once("message", (message) => {
          settled = true;
          handleWorkerMessage(task, message);
        });
        nodeWorker.once("error", (err) => {
          settled = true;
          if (!task.done()) {
            task._reject(taskException(err && err.message ? err.message : err));
          }
        });
        nodeWorker.once("exit", (code) => {
          if (!settled && !task.done() && code !== 0) {
            task._reject(taskException(`Worker exited with code ${code}`));
          }
        });
        return task;
      }
      function spawnBrowserWorker(requestBytes, extraDenials) {
        const browserWorker = createBrowserWorker();
        if (!browserWorker) {
          throw new Error("std/worker transport is unavailable");
        }
        const task = new Task(null, {
          status: "running",
          name: "Worker.spawn"
        });
        task._cancelHook = function cancelWorker() {
          if (browserWorker && typeof browserWorker.terminate === "function") {
            browserWorker.terminate();
          }
        };
        const onMessage = (event) => handleWorkerMessage(
          task,
          event && Object.prototype.hasOwnProperty.call(event, "data") ? event.data : event
        );
        const onError = (err) => {
          const root = browserRoot();
          const reject = () => {
            if (!task.done()) {
              task._reject(taskException(err && err.message ? err.message : err));
            }
          };
          if (root && typeof root.setTimeout === "function") {
            root.setTimeout(reject, 25);
            return;
          }
          reject();
        };
        if (typeof browserWorker.addEventListener === "function") {
          browserWorker.addEventListener("message", onMessage);
          browserWorker.addEventListener("error", onError);
        } else {
          browserWorker.onmessage = onMessage;
          browserWorker.onerror = onError;
        }
        browserWorker.postMessage({
          request_bytes: Array.from(requestBytes.bytes),
          policy: effectivePolicy(extraDenials)
        });
        return task;
      }
      function spawnNodeWorkerHandle(threads, requestBytes, extraDenials) {
        const nodePath = loadNodePath();
        if (!threads || !nodePath) {
          throw new Error("std/worker transport is unavailable");
        }
        const nodeWorker = new threads.Worker(
          nodePath.join(__dirname, "worker-thread.js"),
          {
            workerData: {
              mode: "handle",
              request_bytes: Array.from(requestBytes.bytes),
              policy: effectivePolicy(extraDenials)
            }
          }
        );
        const handle = new WorkerHandle({
          postMessage: (message) => nodeWorker.postMessage(message),
          terminate: () => nodeWorker.terminate().catch(() => {
          })
        });
        let settled = false;
        nodeWorker.on("message", (message) => handleWorkerHandleMessage(handle, message));
        nodeWorker.once("error", (err) => {
          settled = true;
          const wrapped = taskException(err && err.message ? err.message : err);
          handle._closeRemote(wrapped);
          handle._rejectResult(wrapped);
        });
        nodeWorker.once("exit", (code) => {
          if (settled) {
            return;
          }
          if (code !== 0 && !handle._cancelled) {
            const err = taskException(`Worker exited with code ${code}`);
            handle._closeRemote(err);
            handle._rejectResult(err);
            return;
          }
          handle._closeRemote();
          if (!handle._resultTask.done() && !handle._cancelled) {
            handle._rejectResult(taskException("Worker exited without result"));
          }
        });
        return handle;
      }
      function spawnBrowserWorkerHandle(requestBytes, extraDenials) {
        const browserWorker = createBrowserWorker();
        if (!browserWorker) {
          throw new Error("std/worker transport is unavailable");
        }
        const handle = new WorkerHandle({
          postMessage: (message) => browserWorker.postMessage(message),
          terminate: () => {
            if (typeof browserWorker.terminate === "function") {
              browserWorker.terminate();
            }
          }
        });
        const onMessage = (event) => handleWorkerHandleMessage(
          handle,
          event && Object.prototype.hasOwnProperty.call(event, "data") ? event.data : event
        );
        const onError = (err) => {
          const wrapped = taskException(err && err.message ? err.message : err);
          handle._closeRemote(wrapped);
          handle._rejectResult(wrapped);
        };
        if (typeof browserWorker.addEventListener === "function") {
          browserWorker.addEventListener("message", onMessage);
          browserWorker.addEventListener("error", onError);
        } else {
          browserWorker.onmessage = onMessage;
          browserWorker.onerror = onError;
        }
        browserWorker.postMessage({
          type: "start_handle",
          request_bytes: Array.from(requestBytes.bytes),
          policy: effectivePolicy(extraDenials)
        });
        return handle;
      }
      function handleWorkerMessage(task, message) {
        if (task.done()) {
          return;
        }
        if (!message || typeof message !== "object") {
          task._reject(taskException("Worker returned invalid reply"));
          return;
        }
        if (!message.ok) {
          task._reject(taskException(message.error || "worker failed"));
          return;
        }
        try {
          task._resolve(marshal.load(new BinaryString2(message.bytes || [])));
        } catch (err) {
          task._reject(err);
        }
      }
      function handleWorkerHandleMessage(handle, message) {
        if (!message || typeof message !== "object") {
          const err = taskException("Worker returned invalid reply");
          handle._closeRemote(err);
          handle._rejectResult(err);
          return;
        }
        handle._receiveFrame(message);
      }
      function processWorkerHandleMessage(handle, message) {
        if (message.type === "message") {
          handle._deliverBytes(message.bytes || []);
          return;
        }
        if (message.type === "close") {
          handle._closeRemote();
          return;
        }
        if (message.type === "result") {
          if (message.ok) {
            handle._resolveResultBytes(message.bytes || []);
          } else {
            const err2 = taskException(message.error || "worker failed");
            handle._remoteError = err2;
            handle._rejectResult(err2);
          }
          return;
        }
        const err = taskException("Worker returned invalid reply");
        handle._closeRemote(err);
        handle._rejectResult(err);
      }
      module2.exports = {
        Worker,
        __zuzu_set_runtime_policy: setRuntimePolicy2
      };
    }
  });

  // modules/std/digest/_hash.js
  var require_hash = __commonJS({
    "modules/std/digest/_hash.js"(exports2, module2) {
      "use strict";
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      function valueType(value) {
        if (value == null) {
          return "Null";
        }
        if (typeof value === "string") {
          return "String";
        }
        return value.constructor && value.constructor.name ? value.constructor.name : typeof value;
      }
      function assertBinary(value, fnName, label = "BinaryString") {
        if (!value || !(value.bytes instanceof Uint8Array)) {
          throw new Error(`TypeException: ${fnName} expects ${label}, got ${valueType(value)}`);
        }
      }
      function toBinary(bytes) {
        return new BinaryString2(Uint8Array.from(bytes));
      }
      function bytesToHex(bytes) {
        return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
      }
      function bytesToBase64(bytes) {
        if (typeof Buffer !== "undefined") {
          return Buffer.from(bytes).toString("base64").replace(/=+$/u, "");
        }
        let text = "";
        for (let i = 0; i < bytes.length; i++) {
          text += String.fromCharCode(bytes[i]);
        }
        return btoa(text).replace(/=+$/u, "");
      }
      function concatBytes2(...items) {
        const total = items.reduce((sum, item) => sum + item.length, 0);
        const out = new Uint8Array(total);
        let offset = 0;
        for (const item of items) {
          out.set(item, offset);
          offset += item.length;
        }
        return out;
      }
      function padded64(bytes, littleEndianLength = false) {
        const bitLength = bytes.length * 8;
        const total = Math.ceil((bytes.length + 9) / 64) * 64;
        const out = new Uint8Array(total);
        out.set(bytes);
        out[bytes.length] = 128;
        if (littleEndianLength) {
          let n = bitLength;
          for (let i = 0; i < 8; i++) {
            out[total - 8 + i] = n & 255;
            n = Math.floor(n / 256);
          }
        } else {
          let n = bitLength;
          for (let i = 7; i >= 0; i--) {
            out[total - 8 + i] = n & 255;
            n = Math.floor(n / 256);
          }
        }
        return out;
      }
      function padded128(bytes) {
        const bitLength = BigInt(bytes.length) * 8n;
        const total = Math.ceil((bytes.length + 17) / 128) * 128;
        const out = new Uint8Array(total);
        out.set(bytes);
        out[bytes.length] = 128;
        let n = bitLength;
        for (let i = 15; i >= 0; i--) {
          out[total - 16 + i] = Number(n & 0xffn);
          n >>= 8n;
        }
        return out;
      }
      function rotl32(value, bits) {
        return (value << bits | value >>> 32 - bits) >>> 0;
      }
      function rotr32(value, bits) {
        return (value >>> bits | value << 32 - bits) >>> 0;
      }
      function add32(...values) {
        return values.reduce((sum, value) => sum + value >>> 0, 0);
      }
      function md5Bytes(bytes) {
        const s = [
          7,
          12,
          17,
          22,
          7,
          12,
          17,
          22,
          7,
          12,
          17,
          22,
          7,
          12,
          17,
          22,
          5,
          9,
          14,
          20,
          5,
          9,
          14,
          20,
          5,
          9,
          14,
          20,
          5,
          9,
          14,
          20,
          4,
          11,
          16,
          23,
          4,
          11,
          16,
          23,
          4,
          11,
          16,
          23,
          4,
          11,
          16,
          23,
          6,
          10,
          15,
          21,
          6,
          10,
          15,
          21,
          6,
          10,
          15,
          21,
          6,
          10,
          15,
          21
        ];
        const k = Array.from(
          { length: 64 },
          (_value, i) => Math.floor(Math.abs(Math.sin(i + 1)) * 4294967296) >>> 0
        );
        const data = padded64(bytes, true);
        let a0 = 1732584193;
        let b0 = 4023233417;
        let c0 = 2562383102;
        let d0 = 271733878;
        for (let offset = 0; offset < data.length; offset += 64) {
          const m = new Uint32Array(16);
          for (let i = 0; i < 16; i++) {
            const j = offset + i * 4;
            m[i] = data[j] | data[j + 1] << 8 | data[j + 2] << 16 | data[j + 3] << 24;
          }
          let a = a0;
          let b = b0;
          let c = c0;
          let d = d0;
          for (let i = 0; i < 64; i++) {
            let f;
            let g;
            if (i < 16) {
              f = b & c | ~b & d;
              g = i;
            } else if (i < 32) {
              f = d & b | ~d & c;
              g = (5 * i + 1) % 16;
            } else if (i < 48) {
              f = b ^ c ^ d;
              g = (3 * i + 5) % 16;
            } else {
              f = c ^ (b | ~d);
              g = 7 * i % 16;
            }
            const tmp = d;
            d = c;
            c = b;
            b = add32(b, rotl32(add32(a, f, k[i], m[g]), s[i]));
            a = tmp;
          }
          a0 = add32(a0, a);
          b0 = add32(b0, b);
          c0 = add32(c0, c);
          d0 = add32(d0, d);
        }
        const out = new Uint8Array(16);
        for (const [index, value] of [a0, b0, c0, d0].entries()) {
          out[index * 4] = value & 255;
          out[index * 4 + 1] = value >>> 8 & 255;
          out[index * 4 + 2] = value >>> 16 & 255;
          out[index * 4 + 3] = value >>> 24 & 255;
        }
        return out;
      }
      function sha1Bytes(bytes) {
        const data = padded64(bytes);
        let h0 = 1732584193;
        let h1 = 4023233417;
        let h2 = 2562383102;
        let h3 = 271733878;
        let h4 = 3285377520;
        for (let offset = 0; offset < data.length; offset += 64) {
          const w = new Uint32Array(80);
          for (let i = 0; i < 16; i++) {
            const j = offset + i * 4;
            w[i] = data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3];
          }
          for (let i = 16; i < 80; i++) {
            w[i] = rotl32(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
          }
          let a = h0;
          let b = h1;
          let c = h2;
          let d = h3;
          let e = h4;
          for (let i = 0; i < 80; i++) {
            let f;
            let k;
            if (i < 20) {
              f = b & c | ~b & d;
              k = 1518500249;
            } else if (i < 40) {
              f = b ^ c ^ d;
              k = 1859775393;
            } else if (i < 60) {
              f = b & c | b & d | c & d;
              k = 2400959708;
            } else {
              f = b ^ c ^ d;
              k = 3395469782;
            }
            const temp = add32(rotl32(a, 5), f, e, k, w[i]);
            e = d;
            d = c;
            c = rotl32(b, 30);
            b = a;
            a = temp;
          }
          h0 = add32(h0, a);
          h1 = add32(h1, b);
          h2 = add32(h2, c);
          h3 = add32(h3, d);
          h4 = add32(h4, e);
        }
        return words32ToBytes([h0, h1, h2, h3, h4]);
      }
      var SHA256_K = [
        1116352408,
        1899447441,
        3049323471,
        3921009573,
        961987163,
        1508970993,
        2453635748,
        2870763221,
        3624381080,
        310598401,
        607225278,
        1426881987,
        1925078388,
        2162078206,
        2614888103,
        3248222580,
        3835390401,
        4022224774,
        264347078,
        604807628,
        770255983,
        1249150122,
        1555081692,
        1996064986,
        2554220882,
        2821834349,
        2952996808,
        3210313671,
        3336571891,
        3584528711,
        113926993,
        338241895,
        666307205,
        773529912,
        1294757372,
        1396182291,
        1695183700,
        1986661051,
        2177026350,
        2456956037,
        2730485921,
        2820302411,
        3259730800,
        3345764771,
        3516065817,
        3600352804,
        4094571909,
        275423344,
        430227734,
        506948616,
        659060556,
        883997877,
        958139571,
        1322822218,
        1537002063,
        1747873779,
        1955562222,
        2024104815,
        2227730452,
        2361852424,
        2428436474,
        2756734187,
        3204031479,
        3329325298
      ];
      function words32ToBytes(words) {
        const out = new Uint8Array(words.length * 4);
        for (let i = 0; i < words.length; i++) {
          out[i * 4] = words[i] >>> 24 & 255;
          out[i * 4 + 1] = words[i] >>> 16 & 255;
          out[i * 4 + 2] = words[i] >>> 8 & 255;
          out[i * 4 + 3] = words[i] & 255;
        }
        return out;
      }
      function sha256Core(bytes, initial) {
        const data = padded64(bytes);
        const h = initial.slice();
        for (let offset = 0; offset < data.length; offset += 64) {
          const w = new Uint32Array(64);
          for (let i = 0; i < 16; i++) {
            const j = offset + i * 4;
            w[i] = data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3];
          }
          for (let i = 16; i < 64; i++) {
            const s0 = rotr32(w[i - 15], 7) ^ rotr32(w[i - 15], 18) ^ w[i - 15] >>> 3;
            const s1 = rotr32(w[i - 2], 17) ^ rotr32(w[i - 2], 19) ^ w[i - 2] >>> 10;
            w[i] = add32(w[i - 16], s0, w[i - 7], s1);
          }
          let [a, b, c, d, e, f, g, hh] = h;
          for (let i = 0; i < 64; i++) {
            const s1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);
            const ch = e & f ^ ~e & g;
            const temp1 = add32(hh, s1, ch, SHA256_K[i], w[i]);
            const s0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);
            const maj = a & b ^ a & c ^ b & c;
            const temp2 = add32(s0, maj);
            hh = g;
            g = f;
            f = e;
            e = add32(d, temp1);
            d = c;
            c = b;
            b = a;
            a = add32(temp1, temp2);
          }
          for (const [i, value] of [a, b, c, d, e, f, g, hh].entries()) {
            h[i] = add32(h[i], value);
          }
        }
        return words32ToBytes(h);
      }
      function sha224Bytes(bytes) {
        return sha256Core(
          bytes,
          [3238371032, 914150663, 812702999, 4144912697, 4290775857, 1750603025, 1694076839, 3204075428]
        ).slice(0, 28);
      }
      function sha256Bytes(bytes) {
        return sha256Core(
          bytes,
          [1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]
        );
      }
      var MASK64 = (1n << 64n) - 1n;
      var SHA512_K = [
        0x428a2f98d728ae22n,
        0x7137449123ef65cdn,
        0xb5c0fbcfec4d3b2fn,
        0xe9b5dba58189dbbcn,
        0x3956c25bf348b538n,
        0x59f111f1b605d019n,
        0x923f82a4af194f9bn,
        0xab1c5ed5da6d8118n,
        0xd807aa98a3030242n,
        0x12835b0145706fben,
        0x243185be4ee4b28cn,
        0x550c7dc3d5ffb4e2n,
        0x72be5d74f27b896fn,
        0x80deb1fe3b1696b1n,
        0x9bdc06a725c71235n,
        0xc19bf174cf692694n,
        0xe49b69c19ef14ad2n,
        0xefbe4786384f25e3n,
        0x0fc19dc68b8cd5b5n,
        0x240ca1cc77ac9c65n,
        0x2de92c6f592b0275n,
        0x4a7484aa6ea6e483n,
        0x5cb0a9dcbd41fbd4n,
        0x76f988da831153b5n,
        0x983e5152ee66dfabn,
        0xa831c66d2db43210n,
        0xb00327c898fb213fn,
        0xbf597fc7beef0ee4n,
        0xc6e00bf33da88fc2n,
        0xd5a79147930aa725n,
        0x06ca6351e003826fn,
        0x142929670a0e6e70n,
        0x27b70a8546d22ffcn,
        0x2e1b21385c26c926n,
        0x4d2c6dfc5ac42aedn,
        0x53380d139d95b3dfn,
        0x650a73548baf63den,
        0x766a0abb3c77b2a8n,
        0x81c2c92e47edaee6n,
        0x92722c851482353bn,
        0xa2bfe8a14cf10364n,
        0xa81a664bbc423001n,
        0xc24b8b70d0f89791n,
        0xc76c51a30654be30n,
        0xd192e819d6ef5218n,
        0xd69906245565a910n,
        0xf40e35855771202an,
        0x106aa07032bbd1b8n,
        0x19a4c116b8d2d0c8n,
        0x1e376c085141ab53n,
        0x2748774cdf8eeb99n,
        0x34b0bcb5e19b48a8n,
        0x391c0cb3c5c95a63n,
        0x4ed8aa4ae3418acbn,
        0x5b9cca4f7763e373n,
        0x682e6ff3d6b2b8a3n,
        0x748f82ee5defb2fcn,
        0x78a5636f43172f60n,
        0x84c87814a1f0ab72n,
        0x8cc702081a6439ecn,
        0x90befffa23631e28n,
        0xa4506cebde82bde9n,
        0xbef9a3f7b2c67915n,
        0xc67178f2e372532bn,
        0xca273eceea26619cn,
        0xd186b8c721c0c207n,
        0xeada7dd6cde0eb1en,
        0xf57d4f7fee6ed178n,
        0x06f067aa72176fban,
        0x0a637dc5a2c898a6n,
        0x113f9804bef90daen,
        0x1b710b35131c471bn,
        0x28db77f523047d84n,
        0x32caab7b40c72493n,
        0x3c9ebe0a15c9bebcn,
        0x431d67c49c100d4cn,
        0x4cc5d4becb3e42b6n,
        0x597f299cfc657e2an,
        0x5fcb6fab3ad6faecn,
        0x6c44198c4a475817n
      ];
      function rotr64(value, bits) {
        const n = BigInt(bits);
        return (value >> n | value << 64n - n) & MASK64;
      }
      function add64(...values) {
        return values.reduce((sum, value) => sum + value & MASK64, 0n);
      }
      function words64ToBytes(words) {
        const out = new Uint8Array(words.length * 8);
        for (let i = 0; i < words.length; i++) {
          let value = words[i];
          for (let j = 7; j >= 0; j--) {
            out[i * 8 + j] = Number(value & 0xffn);
            value >>= 8n;
          }
        }
        return out;
      }
      function sha512Core(bytes, initial) {
        const data = padded128(bytes);
        const h = initial.slice();
        for (let offset = 0; offset < data.length; offset += 128) {
          const w = new Array(80).fill(0n);
          for (let i = 0; i < 16; i++) {
            let value = 0n;
            for (let j = 0; j < 8; j++) {
              value = value << 8n | BigInt(data[offset + i * 8 + j]);
            }
            w[i] = value;
          }
          for (let i = 16; i < 80; i++) {
            const s0 = rotr64(w[i - 15], 1) ^ rotr64(w[i - 15], 8) ^ w[i - 15] >> 7n;
            const s1 = rotr64(w[i - 2], 19) ^ rotr64(w[i - 2], 61) ^ w[i - 2] >> 6n;
            w[i] = add64(w[i - 16], s0, w[i - 7], s1);
          }
          let [a, b, c, d, e, f, g, hh] = h;
          for (let i = 0; i < 80; i++) {
            const s1 = rotr64(e, 14) ^ rotr64(e, 18) ^ rotr64(e, 41);
            const ch = e & f ^ ~e & g;
            const temp1 = add64(hh, s1, ch, SHA512_K[i], w[i]);
            const s0 = rotr64(a, 28) ^ rotr64(a, 34) ^ rotr64(a, 39);
            const maj = a & b ^ a & c ^ b & c;
            const temp2 = add64(s0, maj);
            hh = g;
            g = f;
            f = e;
            e = add64(d, temp1);
            d = c;
            c = b;
            b = a;
            a = add64(temp1, temp2);
          }
          for (const [i, value] of [a, b, c, d, e, f, g, hh].entries()) {
            h[i] = add64(h[i], value);
          }
        }
        return words64ToBytes(h);
      }
      function sha384Bytes(bytes) {
        return sha512Core(
          bytes,
          [
            0xcbbb9d5dc1059ed8n,
            0x629a292a367cd507n,
            0x9159015a3070dd17n,
            0x152fecd8f70e5939n,
            0x67332667ffc00b31n,
            0x8eb44a8768581511n,
            0xdb0c2e0d64f98fa7n,
            0x47b5481dbefa4fa4n
          ]
        ).slice(0, 48);
      }
      function sha512Bytes(bytes) {
        return sha512Core(
          bytes,
          [
            0x6a09e667f3bcc908n,
            0xbb67ae8584caa73bn,
            0x3c6ef372fe94f82bn,
            0xa54ff53a5f1d36f1n,
            0x510e527fade682d1n,
            0x9b05688c2b3e6c1fn,
            0x1f83d9abfb41bd6bn,
            0x5be0cd19137e2179n
          ]
        );
      }
      var ALGORITHMS = {
        md5: { blockSize: 64, digest: md5Bytes },
        sha1: { blockSize: 64, digest: sha1Bytes },
        sha224: { blockSize: 64, digest: sha224Bytes },
        sha256: { blockSize: 64, digest: sha256Bytes },
        sha384: { blockSize: 128, digest: sha384Bytes },
        sha512: { blockSize: 128, digest: sha512Bytes }
      };
      function digestBytes2(algorithm, value, fnName) {
        assertBinary(value, fnName);
        return ALGORITHMS[algorithm].digest(value.bytes);
      }
      function hmacBytes2(algorithm, value, key, fnName) {
        assertBinary(value, fnName);
        assertBinary(key, fnName, "BinaryString key");
        const spec = ALGORITHMS[algorithm];
        let keyBytes = key.bytes;
        if (keyBytes.length > spec.blockSize) {
          keyBytes = spec.digest(keyBytes);
        }
        const paddedKey = new Uint8Array(spec.blockSize);
        paddedKey.set(keyBytes);
        const innerKey = new Uint8Array(spec.blockSize);
        const outerKey = new Uint8Array(spec.blockSize);
        for (let i = 0; i < spec.blockSize; i++) {
          innerKey[i] = paddedKey[i] ^ 54;
          outerKey[i] = paddedKey[i] ^ 92;
        }
        return spec.digest(concatBytes2(outerKey, spec.digest(concatBytes2(innerKey, value.bytes))));
      }
      module2.exports = {
        digestBytes: digestBytes2,
        hmacBytes: hmacBytes2,
        toBinary,
        bytesToHex,
        bytesToBase64
      };
    }
  });

  // modules/std/secure.js
  var require_secure = __commonJS({
    "modules/std/secure.js"(exports, module) {
      "use strict";
      var { BinaryString } = require_runtime_helpers();
      var taskRuntime = require_task();
      var { digestBytes, hmacBytes } = require_hash();
      var { Time } = require_time();
      var BASE64URL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
      var MAX_SAFE_INT = 9007199254740992;
      var RANDOM_CAPABILITIES = /* @__PURE__ */ new Set(["bytes", "token", "int"]);
      var KDF_CAPABILITIES = /* @__PURE__ */ new Set(["hkdf-sha256"]);
      var CIPHER_CAPABILITIES = /* @__PURE__ */ new Set([
        "aes-256-gcm",
        "chacha20-poly1305"
      ]);
      var BROWSER_CIPHER_CAPABILITIES = /* @__PURE__ */ new Set(["aes-256-gcm"]);
      var KEY_AGREEMENT_CAPABILITIES = /* @__PURE__ */ new Set(["x25519"]);
      var CERTIFICATE_CAPABILITIES = /* @__PURE__ */ new Set([
        "parse-x509",
        "parse-x509-der",
        "fingerprint-sha256",
        "public-key",
        "verify-chain"
      ]);
      var BROWSER_CERTIFICATE_CAPABILITIES = /* @__PURE__ */ new Set([
        "parse-x509-der",
        "fingerprint-sha256"
      ]);
      var TLS_IDENTITY_CAPABILITIES = /* @__PURE__ */ new Set(["pem", "pkcs12"]);
      var BROWSER_TLS_IDENTITY_CAPABILITIES = /* @__PURE__ */ new Set(["pem"]);
      var SIGNING_CAPABILITIES = /* @__PURE__ */ new Set([
        "ed25519",
        "ecdsa-p256-sha256",
        "ecdsa-p384-sha384"
      ]);
      var SIGNING_ALGORITHMS = {
        ed25519: {
          type: "ed25519",
          privateLength: 32,
          publicLength: 32
        },
        "ecdsa-p256-sha256": {
          type: "ecdsa",
          privateLength: 32,
          publicLength: 65,
          signatureLength: 64,
          nodeCurve: "prime256v1",
          webCurve: "P-256",
          jwkCurve: "P-256",
          nodeHash: "sha256",
          webHash: "SHA-256"
        },
        "ecdsa-p384-sha384": {
          type: "ecdsa",
          privateLength: 48,
          publicLength: 97,
          signatureLength: 96,
          nodeCurve: "secp384r1",
          webCurve: "P-384",
          jwkCurve: "P-384",
          nodeHash: "sha384",
          webHash: "SHA-384"
        }
      };
      var KEY_AGREEMENT_ALGORITHMS = {
        x25519: {
          privateLength: 32,
          publicLength: 32
        }
      };
      var DEFAULT_PASSWORD_HASH_ALGORITHM = "pbkdf2-sha256";
      var HKDF_SHA256_HASH_LENGTH = 32;
      var HKDF_SHA256_MAX_LENGTH = 255 * HKDF_SHA256_HASH_LENGTH;
      var CIPHER_ALGORITHMS = {
        "aes-256-gcm": {
          keyLength: 32,
          nonceLength: 12,
          tagLength: 16,
          nodeName: "aes-256-gcm",
          webName: "AES-GCM"
        },
        "chacha20-poly1305": {
          keyLength: 32,
          nonceLength: 12,
          tagLength: 16,
          nodeName: "chacha20-poly1305",
          webName: null
        }
      };
      var PASSWORD_HASH_SALT_LENGTH = 16;
      var PASSWORD_HASH_LENGTH = 32;
      var PBKDF2_SHA256_ITERATIONS = 6e5;
      var SCRYPT_LOG_N = 17;
      var SCRYPT_R = 8;
      var SCRYPT_P = 1;
      var runtimePolicy = {
        host_name: "node"
      };
      function setRuntimePolicy(policy = {}) {
        runtimePolicy = {
          ...runtimePolicy,
          ...policy
        };
      }
      function capabilities() {
        return {
          host: hostName(),
          random: hasRandomSource(),
          password_hash: passwordHashCapabilities(),
          kdf: [...KDF_CAPABILITIES],
          cipher: cipherCapabilities(),
          key_agreement: keyAgreementCapabilities(),
          signing: signingCapabilities(),
          certificate: certificateCapabilities(),
          tls_identity: tlsIdentityCapabilities(),
          async_required: {
            cipher: hostName() === "browser",
            kdf: false,
            password_hash: hostName() === "browser",
            signing: hostName() === "browser",
            key_agreement: hostName() === "browser" && keyAgreementCapabilities().length > 0
          }
        };
      }
      function hostName() {
        return runtimePolicy.host_name || "node";
      }
      function capabilityPart(value) {
        return value == null ? "" : String(value);
      }
      function passwordHashCapabilities() {
        return hostName() === "browser" ? ["pbkdf2-sha256"] : ["pbkdf2-sha256", "scrypt"];
      }
      function signingCapabilities() {
        if (hostName() === "browser") {
          return ["ecdsa-p256-sha256", "ecdsa-p384-sha384"];
        }
        return [...SIGNING_CAPABILITIES];
      }
      function keyAgreementCapabilities() {
        if (hostName() === "browser") {
          return subtleKeyAgreementCrypto() ? ["x25519"] : [];
        }
        const crypto = nodeCrypto();
        return crypto && typeof crypto.generateKeyPairSync === "function" && typeof crypto.diffieHellman === "function" ? [...KEY_AGREEMENT_CAPABILITIES] : [];
      }
      function cipherCapabilities() {
        if (hostName() === "browser") {
          return [...BROWSER_CIPHER_CAPABILITIES];
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.getCiphers !== "function") {
          return [];
        }
        const supported = new Set(crypto.getCiphers());
        return [...CIPHER_CAPABILITIES].filter((algorithm) => {
          const meta = CIPHER_ALGORITHMS[algorithm];
          return meta && supported.has(meta.nodeName);
        });
      }
      function certificateCapabilities() {
        return hostName() === "browser" ? [...BROWSER_CERTIFICATE_CAPABILITIES] : [...CERTIFICATE_CAPABILITIES];
      }
      function tlsIdentityCapabilities() {
        return hostName() === "browser" ? [...BROWSER_TLS_IDENTITY_CAPABILITIES] : [...TLS_IDENTITY_CAPABILITIES];
      }
      function hasCapability(area, name2) {
        area = capabilityPart(area);
        name2 = capabilityPart(name2);
        if (area === "random") {
          return hasRandomSource() && RANDOM_CAPABILITIES.has(name2);
        }
        if (area === "password_hash") {
          return passwordHashCapabilities().includes(name2);
        }
        if (area === "kdf") {
          return KDF_CAPABILITIES.has(name2);
        }
        if (area === "cipher") {
          return cipherCapabilities().includes(name2);
        }
        if (area === "key_agreement") {
          return keyAgreementCapabilities().includes(name2);
        }
        if (area === "signing") {
          return signingCapabilities().includes(name2);
        }
        if (area === "certificate") {
          return certificateCapabilities().includes(name2);
        }
        if (area === "tls_identity") {
          return tlsIdentityCapabilities().includes(name2);
        }
        return false;
      }
      function requireCapability(area, name2) {
        area = capabilityPart(area);
        name2 = capabilityPart(name2);
        if (hasCapability(area, name2)) {
          return true;
        }
        throw new Error(
          `Secure capability '${area}/${name2}' is not available on host '${hostName()}'`
        );
      }
      function hasRandomSource() {
        if (globalThis.crypto && typeof globalThis.crypto.getRandomValues === "function") {
          return true;
        }
        const crypto = nodeCrypto();
        return !!(crypto && typeof crypto.randomBytes === "function");
      }
      function nodeCrypto() {
        if (typeof __require !== "function") {
          return null;
        }
        try {
          return __require("node:crypto");
        } catch (_err) {
          return null;
        }
      }
      function nodeForge() {
        if (hostName() === "browser" || typeof __require !== "function") {
          return null;
        }
        try {
          const nodeRequire = eval("require");
          return nodeRequire("node-forge");
        } catch (_err) {
          return null;
        }
      }
      function nodeTls() {
        if (hostName() === "browser" || typeof __require !== "function") {
          return null;
        }
        try {
          const nodeRequire = eval("require");
          return nodeRequire("node:tls");
        } catch (_err) {
          return null;
        }
      }
      function fillRandom(bytes) {
        if (globalThis.crypto && typeof globalThis.crypto.getRandomValues === "function") {
          for (let offset = 0; offset < bytes.length; offset += 65536) {
            globalThis.crypto.getRandomValues(
              bytes.subarray(offset, Math.min(offset + 65536, bytes.length))
            );
          }
          return bytes;
        }
        const crypto = nodeCrypto();
        if (crypto && typeof crypto.randomBytes === "function") {
          bytes.set(crypto.randomBytes(bytes.length));
          return bytes;
        }
        throw new Error("Secure random source is unavailable");
      }
      function nonNegativeInteger(value, label) {
        const number = Number(value ?? 0);
        if (!Number.isInteger(number) || number < 0) {
          throw new Error(`${label} expects a non-negative integer`);
        }
        return number;
      }
      function positiveInteger(value, label) {
        const number = Number(value ?? 0);
        if (!Number.isInteger(number) || number <= 0) {
          throw new Error(`${label} expects a positive integer`);
        }
        if (number > MAX_SAFE_INT) {
          throw new Error(`${label} maximum is too large`);
        }
        return number;
      }
      function randomBytes(length) {
        return fillRandom(new Uint8Array(length));
      }
      function base64url(bytes) {
        let out = "";
        for (let i = 0; i < bytes.length; i += 3) {
          const b0 = bytes[i];
          const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
          const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
          const triple = b0 << 16 | b1 << 8 | b2;
          out += BASE64URL[triple >> 18 & 63];
          out += BASE64URL[triple >> 12 & 63];
          if (i + 1 < bytes.length) {
            out += BASE64URL[triple >> 6 & 63];
          }
          if (i + 2 < bytes.length) {
            out += BASE64URL[triple & 63];
          }
        }
        return out;
      }
      function base64urlDecode(text) {
        if (typeof text !== "string" || /[^A-Za-z0-9_-]/u.test(text)) {
          return null;
        }
        const alphabet = new Map(BASE64URL.split("").map(
          (value, index) => [value, index]
        ));
        const out = [];
        let bits = 0;
        let bitLength = 0;
        for (const char of text) {
          bits = bits << 6 | alphabet.get(char);
          bitLength += 6;
          while (bitLength >= 8) {
            bitLength -= 8;
            out.push(bits >> bitLength & 255);
          }
        }
        if (bitLength > 0 && (bits & (1 << bitLength) - 1) !== 0) {
          return null;
        }
        return Uint8Array.from(out);
      }
      function base64(bytes) {
        const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        let out = "";
        for (let i = 0; i < bytes.length; i += 3) {
          const b0 = bytes[i];
          const b1 = i + 1 < bytes.length ? bytes[i + 1] : 0;
          const b2 = i + 2 < bytes.length ? bytes[i + 2] : 0;
          const triple = b0 << 16 | b1 << 8 | b2;
          out += alphabet[triple >> 18 & 63];
          out += alphabet[triple >> 12 & 63];
          out += i + 1 < bytes.length ? alphabet[triple >> 6 & 63] : "=";
          out += i + 2 < bytes.length ? alphabet[triple & 63] : "=";
        }
        return out;
      }
      function base64Decode(text) {
        if (typeof text !== "string" || /[^A-Za-z0-9+/=]/u.test(text)) {
          return null;
        }
        const clean = text.replace(/=+$/u, "");
        const alphabet = new Map(
          "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("").map((value, index) => [value, index])
        );
        const out = [];
        let bits = 0;
        let bitLength = 0;
        for (const char of clean) {
          if (!alphabet.has(char)) {
            return null;
          }
          bits = bits << 6 | alphabet.get(char);
          bitLength += 6;
          while (bitLength >= 8) {
            bitLength -= 8;
            out.push(bits >> bitLength & 255);
          }
        }
        return Uint8Array.from(out);
      }
      function pemToDer(pem, label) {
        const text = assertString(pem, label, "String key");
        const body = text.replace(/-----BEGIN [^-]+-----/gu, "").replace(/-----END [^-]+-----/gu, "").replace(/\s+/gu, "");
        const bytes = base64Decode(body);
        if (!bytes) {
          throw new Error(`${label} expects PEM key text`);
        }
        return bytes;
      }
      function derToPem(label, der) {
        const encoded = base64(der);
        const lines = [];
        for (let i = 0; i < encoded.length; i += 64) {
          lines.push(encoded.slice(i, i + 64));
        }
        return `-----BEGIN ${label}-----
${lines.join("\n")}
-----END ${label}-----
`;
      }
      function certificateDerToPem(der) {
        return derToPem("CERTIFICATE", der);
      }
      function certificatePemBlocks(pem, label) {
        const text = assertString(pem, label, "String pem");
        const blocks = [];
        const re = /-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/gu;
        let match;
        while (match = re.exec(text)) {
          const bytes = base64Decode(match[1].replace(/\s+/gu, ""));
          if (!bytes) {
            throw new Error(`${label} expects PEM certificate text`);
          }
          blocks.push(bytes);
        }
        if (blocks.length === 0) {
          throw new Error(`${label} expects PEM certificate text`);
        }
        return blocks;
      }
      function randomInt(max) {
        if (max === 1) {
          return 0;
        }
        const space = 2 ** 56;
        const limit = space - space % max;
        while (true) {
          const bytes = randomBytes(7);
          let value = 0;
          for (const byte of bytes) {
            value = value * 256 + byte;
          }
          if (value < limit) {
            return value % max;
          }
        }
      }
      function typeName(value) {
        if (value == null) {
          return "Null";
        }
        if (value && value.bytes instanceof Uint8Array) {
          return "BinaryString";
        }
        if (typeof value === "string") {
          return "String";
        }
        return value.constructor && value.constructor.name ? value.constructor.name : typeof value;
      }
      function isPlainObject(value) {
        return value != null && typeof value === "object" && !Array.isArray(value) && !(value.bytes instanceof Uint8Array);
      }
      function assertBinaryString(value, label, argName = "BinaryString") {
        if (value && value.bytes instanceof Uint8Array) {
          return value.bytes;
        }
        throw new Error(
          `TypeException: ${label} expects ${argName}, got ${typeName(value)}`
        );
      }
      function optionalBinaryString(value, label, argName) {
        if (value == null) {
          return new Uint8Array(0);
        }
        return assertBinaryString(value, label, argName);
      }
      function optionalDict(value, label, argName = "Dict") {
        if (value == null) {
          return {};
        }
        if (isPlainObject(value)) {
          return value;
        }
        throw new Error(
          `TypeException: ${label} expects ${argName}, got ${typeName(value)}`
        );
      }
      function assertString(value, label, argName = "String") {
        if (typeof value === "string") {
          return value;
        }
        throw new Error(
          `TypeException: ${label} expects ${argName}, got ${typeName(value)}`
        );
      }
      function cipherAlgorithm(value, label) {
        const algorithm = value == null ? "aes-256-gcm" : String(value);
        if (!CIPHER_ALGORITHMS[algorithm] || !cipherCapabilities().includes(algorithm)) {
          throw new Error(`${label} cipher algorithm '${algorithm}' is not available`);
        }
        return algorithm;
      }
      function cipherOptions(value, label) {
        const options = optionalDict(value, label, "Dict options");
        const algorithmValue = options.algorithm;
        return {
          algorithm: cipherAlgorithm(algorithmValue, label),
          algorithmSupplied: algorithmValue != null,
          aad: optionalBinaryString(options.aad, label, "BinaryString aad")
        };
      }
      function cipherMeta(algorithm) {
        return CIPHER_ALGORITHMS[algorithm];
      }
      function cipherKey(value, label, meta) {
        const key = assertBinaryString(value, label, "BinaryString key");
        if (key.length !== meta.keyLength) {
          throw new Error(`${label} expects a ${meta.keyLength}-byte key`);
        }
        return key;
      }
      function envelopeBytes(envelope, field, label, length = null) {
        const bytes = assertBinaryString(
          envelope[field],
          label,
          `BinaryString envelope.${field}`
        );
        if (length != null && bytes.length !== length) {
          throw new Error(`${label} expects envelope.${field} to be ${length} bytes`);
        }
        return bytes;
      }
      function cipherEnvelope(value, label) {
        const envelope = optionalDict(value, label, "Dict envelope");
        if (envelope.version !== 1) {
          throw new Error(`${label} expects envelope.version 1`);
        }
        const algorithm = cipherAlgorithm(envelope.algorithm, label);
        const meta = cipherMeta(algorithm);
        return {
          algorithm,
          nonce: envelopeBytes(envelope, "nonce", label, meta.nonceLength),
          ciphertext: envelopeBytes(envelope, "ciphertext", label),
          tag: envelopeBytes(envelope, "tag", label, meta.tagLength)
        };
      }
      function cipherEnvelopeValue(algorithm, nonce, ciphertext, tag) {
        return {
          version: 1,
          algorithm,
          nonce: new BinaryString(nonce),
          ciphertext: new BinaryString(ciphertext),
          tag: new BinaryString(tag)
        };
      }
      function hkdfLength(value, label) {
        const number = Number(value);
        if (!Number.isInteger(number) || number < 0 || number > HKDF_SHA256_MAX_LENGTH) {
          throw new Error(
            `${label} expects length between 0 and ${HKDF_SHA256_MAX_LENGTH}`
          );
        }
        return number;
      }
      function concatBytes(...items) {
        const total = items.reduce((sum, item) => sum + item.length, 0);
        const out = new Uint8Array(total);
        let offset = 0;
        for (const item of items) {
          out.set(item, offset);
          offset += item.length;
        }
        return out;
      }
      function hmacSha256(key, value) {
        return hmacBytes(
          "sha256",
          new BinaryString(value),
          new BinaryString(key),
          "KeyDerivation.hkdf_sha256"
        );
      }
      function hkdfSha256Bytes(inputKeyMaterial, length, salt, info) {
        if (length === 0) {
          return new Uint8Array(0);
        }
        const prk = hmacSha256(salt, inputKeyMaterial);
        let previous = new Uint8Array(0);
        let out = new Uint8Array(0);
        let counter = 1;
        while (out.length < length) {
          previous = hmacSha256(
            prk,
            concatBytes(previous, info, Uint8Array.of(counter))
          );
          out = concatBytes(out, previous);
          counter++;
        }
        return out.slice(0, length);
      }
      function hkdfSha256Inputs(inputKeyMaterial, length, salt, info) {
        const label = "KeyDerivation.hkdf_sha256";
        return {
          inputKeyMaterial: assertBinaryString(inputKeyMaterial, label),
          length: hkdfLength(length, label),
          salt: optionalBinaryString(salt, label, "BinaryString salt"),
          info: optionalBinaryString(info, label, "BinaryString info")
        };
      }
      function hkdfSha256(inputKeyMaterial, length, salt = null, info = null) {
        const args = hkdfSha256Inputs(inputKeyMaterial, length, salt, info);
        return new BinaryString(
          hkdfSha256Bytes(
            args.inputKeyMaterial,
            args.length,
            args.salt,
            args.info
          )
        );
      }
      function passwordBytes(value, label) {
        return new TextEncoder().encode(
          assertString(value, label, "String password")
        );
      }
      function optionString(options, key, fallback) {
        return options[key] == null ? fallback : String(options[key]);
      }
      function optionPositiveInteger(options, key, fallback, label) {
        if (options[key] == null) {
          return fallback;
        }
        return positiveInteger(options[key], `${label} option '${key}'`);
      }
      function passwordHashAlgorithm(options, label) {
        const algorithm = optionString(
          options,
          "algorithm",
          DEFAULT_PASSWORD_HASH_ALGORITHM
        );
        if (!passwordHashCapabilities().includes(algorithm)) {
          throw new Error(
            `${label} password hash algorithm '${algorithm}' is not available`
          );
        }
        return algorithm;
      }
      function pbkdf2Options(options, label) {
        return {
          iterations: optionPositiveInteger(
            options,
            "iterations",
            PBKDF2_SHA256_ITERATIONS,
            label
          ),
          length: optionPositiveInteger(
            options,
            "length",
            PASSWORD_HASH_LENGTH,
            label
          )
        };
      }
      function scryptOptions(options, label) {
        let logN = optionPositiveInteger(options, "log_n", SCRYPT_LOG_N, label);
        const defaultCost = 2 ** logN;
        const cost = optionPositiveInteger(options, "cost", defaultCost, label);
        if (cost < 2 || (cost & cost - 1) !== 0) {
          throw new Error(`${label} option 'cost' must be a power of two`);
        }
        logN = Math.log2(cost);
        return {
          logN,
          cost,
          r: optionPositiveInteger(options, "r", SCRYPT_R, label),
          p: optionPositiveInteger(options, "p", SCRYPT_P, label),
          length: optionPositiveInteger(
            options,
            "length",
            PASSWORD_HASH_LENGTH,
            label
          )
        };
      }
      function constantTimeEqual(left, right) {
        if (!left || !right || left.length !== right.length) {
          return false;
        }
        let diff = 0;
        for (let i = 0; i < left.length; i++) {
          diff |= left[i] ^ right[i];
        }
        return diff === 0;
      }
      function parseParamList(text) {
        const out = {};
        for (const part of text.split(",")) {
          const index = part.indexOf("=");
          if (index <= 0) {
            return null;
          }
          out[part.slice(0, index)] = part.slice(index + 1);
        }
        return out;
      }
      function parsePasswordHash(encoded) {
        if (typeof encoded !== "string") {
          return null;
        }
        let match = encoded.match(
          /^\$zuzu-pbkdf2-sha256\$v=1\$([^$]+)\$([^$]+)\$([^$]+)$/u
        );
        if (match) {
          const params = parseParamList(match[1]);
          if (!params || !/^\d+$/u.test(params.i || "") || !/^\d+$/u.test(params.l || "")) {
            return null;
          }
          const salt = base64urlDecode(match[2]);
          const hash = base64urlDecode(match[3]);
          if (!salt || !hash) {
            return null;
          }
          return {
            algorithm: "pbkdf2-sha256",
            iterations: Number(params.i),
            length: Number(params.l),
            salt,
            hash
          };
        }
        match = encoded.match(
          /^\$scrypt\$([^$]+)\$([^$]+)\$([^$]+)$/u
        );
        if (match) {
          const params = parseParamList(match[1]);
          if (!params || !/^\d+$/u.test(params.ln || "") || !/^\d+$/u.test(params.r || "") || !/^\d+$/u.test(params.p || "") || !/^\d+$/u.test(params.l || "")) {
            return null;
          }
          const salt = base64urlDecode(match[2]);
          const hash = base64urlDecode(match[3]);
          if (!salt || !hash) {
            return null;
          }
          return {
            algorithm: "scrypt",
            log_n: Number(params.ln),
            r: Number(params.r),
            p: Number(params.p),
            length: Number(params.l),
            salt,
            hash
          };
        }
        return null;
      }
      function nodePbkdf2(password, salt, iterations, length) {
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.pbkdf2Sync !== "function") {
          throw new Error("PBKDF2-SHA256 is unavailable on this host");
        }
        return new Uint8Array(
          crypto.pbkdf2Sync(password, salt, iterations, length, "sha256")
        );
      }
      function nodeScrypt(password, salt, options) {
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.scryptSync !== "function") {
          throw new Error("scrypt is unavailable on this host");
        }
        return new Uint8Array(
          crypto.scryptSync(
            password,
            salt,
            options.length,
            {
              N: options.cost,
              r: options.r,
              p: options.p,
              maxmem: Math.max(
                32 * 1024 * 1024,
                128 * options.cost * options.r + 64 * 1024 * 1024
              )
            }
          )
        );
      }
      function passwordHashDeriveBytes(password, algorithm, salt, options, label) {
        if (algorithm === "pbkdf2-sha256") {
          const pbkdf2Opts = pbkdf2Options(options, label);
          return nodePbkdf2(
            password,
            salt,
            pbkdf2Opts.iterations,
            pbkdf2Opts.length
          );
        }
        if (algorithm === "scrypt") {
          return nodeScrypt(password, salt, scryptOptions(options, label));
        }
        throw new Error(`${label} does not support algorithm '${algorithm}'`);
      }
      async function webCryptoPbkdf2(password, salt, iterations, length) {
        const subtle = subtleCrypto();
        if (!subtle) {
          throw new Error("Web Crypto PBKDF2-SHA256 is unavailable");
        }
        const key = await subtle.importKey(
          "raw",
          password,
          "PBKDF2",
          false,
          ["deriveBits"]
        );
        const bits = await subtle.deriveBits(
          {
            name: "PBKDF2",
            hash: "SHA-256",
            salt,
            iterations
          },
          key,
          length * 8
        );
        return new Uint8Array(bits);
      }
      async function passwordHashDeriveBytesAsync(password, algorithm, salt, options, label) {
        if (algorithm === "pbkdf2-sha256" && hostName() === "browser") {
          const pbkdf2Opts = pbkdf2Options(options, label);
          return webCryptoPbkdf2(
            password,
            salt,
            pbkdf2Opts.iterations,
            pbkdf2Opts.length
          );
        }
        return passwordHashDeriveBytes(password, algorithm, salt, options, label);
      }
      function passwordHash(passwordValue, optionsValue = null) {
        const label = "PasswordHash.hash";
        if (hostName() === "browser") {
          throw new Error(
            "PasswordHash.hash is not available synchronously on host browser; use PasswordHash.hash_async"
          );
        }
        const password = passwordBytes(passwordValue, label);
        const options = optionalDict(optionsValue, label, "Dict options");
        const algorithm = passwordHashAlgorithm(options, label);
        const salt = options.salt == null ? randomBytes(PASSWORD_HASH_SALT_LENGTH) : assertBinaryString(options.salt, label, "BinaryString salt");
        const hash = passwordHashDeriveBytes(
          password,
          algorithm,
          salt,
          options,
          label
        );
        if (algorithm === "pbkdf2-sha256") {
          const pbkdf2Opts = pbkdf2Options(options, label);
          return [
            "",
            "zuzu-pbkdf2-sha256",
            "v=1",
            `i=${pbkdf2Opts.iterations},l=${pbkdf2Opts.length}`,
            base64url(salt),
            base64url(hash)
          ].join("$");
        }
        const scryptOpts = scryptOptions(options, label);
        return [
          "",
          "scrypt",
          `ln=${scryptOpts.logN},r=${scryptOpts.r},p=${scryptOpts.p},l=${scryptOpts.length}`,
          base64url(salt),
          base64url(hash)
        ].join("$");
      }
      async function passwordHashAsyncValue(passwordValue, optionsValue = null) {
        const label = "PasswordHash.hash";
        const password = passwordBytes(passwordValue, label);
        const options = optionalDict(optionsValue, label, "Dict options");
        const algorithm = passwordHashAlgorithm(options, label);
        const salt = options.salt == null ? randomBytes(PASSWORD_HASH_SALT_LENGTH) : assertBinaryString(options.salt, label, "BinaryString salt");
        const hash = await passwordHashDeriveBytesAsync(
          password,
          algorithm,
          salt,
          options,
          label
        );
        if (algorithm === "pbkdf2-sha256") {
          const pbkdf2Opts = pbkdf2Options(options, label);
          return [
            "",
            "zuzu-pbkdf2-sha256",
            "v=1",
            `i=${pbkdf2Opts.iterations},l=${pbkdf2Opts.length}`,
            base64url(salt),
            base64url(hash)
          ].join("$");
        }
        const scryptOpts = scryptOptions(options, label);
        return [
          "",
          "scrypt",
          `ln=${scryptOpts.logN},r=${scryptOpts.r},p=${scryptOpts.p},l=${scryptOpts.length}`,
          base64url(salt),
          base64url(hash)
        ].join("$");
      }
      function passwordHashVerify(passwordValue, encodedValue) {
        const label = "PasswordHash.verify";
        if (hostName() === "browser") {
          throw new Error(
            "PasswordHash.verify is not available synchronously on host browser; use PasswordHash.verify_async"
          );
        }
        const password = passwordBytes(passwordValue, label);
        const encoded = assertString(encodedValue, label, "String encoded_hash");
        const parsed = parsePasswordHash(encoded);
        if (!parsed || !passwordHashCapabilities().includes(parsed.algorithm)) {
          return false;
        }
        try {
          const hash = passwordHashDeriveBytes(
            password,
            parsed.algorithm,
            parsed.salt,
            parsed,
            label
          );
          return constantTimeEqual(hash, parsed.hash);
        } catch (_err) {
          return false;
        }
      }
      async function passwordHashVerifyAsyncValue(passwordValue, encodedValue) {
        const label = "PasswordHash.verify";
        const password = passwordBytes(passwordValue, label);
        const encoded = assertString(encodedValue, label, "String encoded_hash");
        const parsed = parsePasswordHash(encoded);
        if (!parsed || !passwordHashCapabilities().includes(parsed.algorithm)) {
          return false;
        }
        try {
          const hash = await passwordHashDeriveBytesAsync(
            password,
            parsed.algorithm,
            parsed.salt,
            parsed,
            label
          );
          return constantTimeEqual(hash, parsed.hash);
        } catch (_err) {
          return false;
        }
      }
      function passwordHashNeedsRehash(encodedValue, optionsValue = null) {
        const label = "PasswordHash.needs_rehash";
        const encoded = assertString(encodedValue, label, "String encoded_hash");
        const options = optionalDict(optionsValue, label, "Dict options");
        const target = passwordHashAlgorithm(options, label);
        const parsed = parsePasswordHash(encoded);
        if (!parsed || parsed.algorithm !== target) {
          return true;
        }
        if (target === "pbkdf2-sha256") {
          const pbkdf2Opts = pbkdf2Options(options, label);
          return parsed.iterations < pbkdf2Opts.iterations || parsed.length !== pbkdf2Opts.length;
        }
        if (target === "scrypt") {
          const scryptOpts = scryptOptions(options, label);
          return parsed.log_n < scryptOpts.logN || parsed.r !== scryptOpts.r || parsed.p !== scryptOpts.p || parsed.length !== scryptOpts.length;
        }
        return true;
      }
      function passwordHashDeriveKey(passwordValue, optionsValue = null) {
        const label = "PasswordHash.derive_key";
        if (hostName() === "browser") {
          throw new Error(
            "PasswordHash.derive_key is not available synchronously on host browser; use PasswordHash.derive_key_async"
          );
        }
        const password = passwordBytes(passwordValue, label);
        const options = optionalDict(optionsValue, label, "Dict options");
        const algorithm = passwordHashAlgorithm(options, label);
        if (options.salt == null) {
          throw new Error(`${label} expects BinaryString salt`);
        }
        const salt = assertBinaryString(options.salt, label, "BinaryString salt");
        return new BinaryString(
          passwordHashDeriveBytes(password, algorithm, salt, options, label)
        );
      }
      async function passwordHashDeriveKeyAsyncValue(passwordValue, optionsValue = null) {
        const label = "PasswordHash.derive_key";
        const password = passwordBytes(passwordValue, label);
        const options = optionalDict(optionsValue, label, "Dict options");
        const algorithm = passwordHashAlgorithm(options, label);
        if (options.salt == null) {
          throw new Error(`${label} expects BinaryString salt`);
        }
        const salt = assertBinaryString(options.salt, label, "BinaryString salt");
        return new BinaryString(
          await passwordHashDeriveBytesAsync(
            password,
            algorithm,
            salt,
            options,
            label
          )
        );
      }
      function subtleCrypto() {
        return globalThis.crypto && globalThis.crypto.subtle && typeof globalThis.crypto.subtle.importKey === "function" && typeof globalThis.crypto.subtle.deriveBits === "function" ? globalThis.crypto.subtle : null;
      }
      function subtleAesCrypto() {
        return globalThis.crypto && globalThis.crypto.subtle && typeof globalThis.crypto.subtle.importKey === "function" && typeof globalThis.crypto.subtle.encrypt === "function" && typeof globalThis.crypto.subtle.decrypt === "function" ? globalThis.crypto.subtle : null;
      }
      function cipherGenerateKey(algorithm = "aes-256-gcm") {
        const actual = cipherAlgorithm(algorithm, "Cipher.generate_key");
        return new BinaryString(randomBytes(cipherMeta(actual).keyLength));
      }
      function nodeCipherEncrypt(plaintext, key, options) {
        const crypto = nodeCrypto();
        const meta = cipherMeta(options.algorithm);
        if (!crypto || typeof crypto.createCipheriv !== "function" || !crypto.getCiphers().includes(meta.nodeName)) {
          throw new Error(`${options.algorithm} is unavailable on this host`);
        }
        const nonce = randomBytes(meta.nonceLength);
        const cipher = crypto.createCipheriv(
          meta.nodeName,
          key,
          nonce,
          { authTagLength: meta.tagLength }
        );
        cipher.setAAD(options.aad);
        const ciphertext = concatBytes(
          cipher.update(plaintext),
          cipher.final()
        );
        const tag = new Uint8Array(cipher.getAuthTag());
        return cipherEnvelopeValue(options.algorithm, nonce, ciphertext, tag);
      }
      function nodeCipherDecrypt(envelope, key, options) {
        const crypto = nodeCrypto();
        const meta = cipherMeta(envelope.algorithm);
        if (!crypto || typeof crypto.createDecipheriv !== "function" || !crypto.getCiphers().includes(meta.nodeName)) {
          throw new Error(`${envelope.algorithm} is unavailable on this host`);
        }
        try {
          const decipher = crypto.createDecipheriv(
            meta.nodeName,
            key,
            envelope.nonce,
            { authTagLength: meta.tagLength }
          );
          decipher.setAAD(options.aad);
          decipher.setAuthTag(envelope.tag);
          return new BinaryString(
            concatBytes(
              decipher.update(envelope.ciphertext),
              decipher.final()
            )
          );
        } catch (_err) {
          throw new Error("Cipher.decrypt authentication failed");
        }
      }
      function cipherEncrypt(plaintext, key, options = null) {
        const label = "Cipher.encrypt";
        const bytes = assertBinaryString(plaintext, label, "BinaryString plaintext");
        const cipherOpts = cipherOptions(options, label);
        const keyBytes = cipherKey(key, label, cipherMeta(cipherOpts.algorithm));
        if (hostName() === "browser") {
          throw new Error(
            "Cipher.encrypt is not available synchronously on host browser; use Cipher.encrypt_async"
          );
        }
        return nodeCipherEncrypt(bytes, keyBytes, cipherOpts);
      }
      function cipherDecrypt(envelope, key, options = null) {
        const label = "Cipher.decrypt";
        const cipherOpts = cipherOptions(options, label);
        const cipherEnv = cipherEnvelope(envelope, label);
        if (cipherOpts.algorithmSupplied && cipherOpts.algorithm !== cipherEnv.algorithm) {
          throw new Error(
            `${label} options.algorithm does not match envelope.algorithm`
          );
        }
        const keyBytes = cipherKey(key, label, cipherMeta(cipherEnv.algorithm));
        if (hostName() === "browser") {
          throw new Error(
            "Cipher.decrypt is not available synchronously on host browser; use Cipher.decrypt_async"
          );
        }
        return nodeCipherDecrypt(cipherEnv, keyBytes, cipherOpts);
      }
      async function webCryptoCipherEncrypt(plaintext, key, options) {
        if (options.algorithm !== "aes-256-gcm") {
          throw new Error(`${options.algorithm} is unavailable on host browser`);
        }
        const subtle = subtleAesCrypto();
        if (!subtle) {
          throw new Error("Web Crypto AES-GCM is unavailable");
        }
        const meta = cipherMeta(options.algorithm);
        const nonce = randomBytes(meta.nonceLength);
        const cryptoKey = await subtle.importKey(
          "raw",
          key,
          "AES-GCM",
          false,
          ["encrypt"]
        );
        const sealed = new Uint8Array(await subtle.encrypt(
          {
            name: "AES-GCM",
            iv: nonce,
            additionalData: options.aad,
            tagLength: 128
          },
          cryptoKey,
          plaintext
        ));
        return cipherEnvelopeValue(
          options.algorithm,
          nonce,
          sealed.slice(0, sealed.length - meta.tagLength),
          sealed.slice(sealed.length - meta.tagLength)
        );
      }
      async function webCryptoCipherDecrypt(envelope, key, options) {
        if (envelope.algorithm !== "aes-256-gcm") {
          throw new Error(`${envelope.algorithm} is unavailable on host browser`);
        }
        const subtle = subtleAesCrypto();
        if (!subtle) {
          throw new Error("Web Crypto AES-GCM is unavailable");
        }
        const cryptoKey = await subtle.importKey(
          "raw",
          key,
          "AES-GCM",
          false,
          ["decrypt"]
        );
        try {
          const plaintext = await subtle.decrypt(
            {
              name: "AES-GCM",
              iv: envelope.nonce,
              additionalData: options.aad,
              tagLength: 128
            },
            cryptoKey,
            concatBytes(envelope.ciphertext, envelope.tag)
          );
          return new BinaryString(new Uint8Array(plaintext));
        } catch (_err) {
          throw new Error("Cipher.decrypt authentication failed");
        }
      }
      function cipherEncryptAsync(plaintext, key, options = null) {
        const label = "Cipher.encrypt";
        const bytes = assertBinaryString(plaintext, label, "BinaryString plaintext");
        const cipherOpts = cipherOptions(options, label);
        const keyBytes = cipherKey(key, label, cipherMeta(cipherOpts.algorithm));
        if (hostName() === "browser") {
          return taskRuntime.Task.from(
            webCryptoCipherEncrypt(bytes, keyBytes, cipherOpts)
          );
        }
        return taskRuntime.Task.resolved(
          nodeCipherEncrypt(bytes, keyBytes, cipherOpts)
        );
      }
      function cipherDecryptAsync(envelope, key, options = null) {
        const label = "Cipher.decrypt";
        const cipherOpts = cipherOptions(options, label);
        const cipherEnv = cipherEnvelope(envelope, label);
        if (cipherOpts.algorithmSupplied && cipherOpts.algorithm !== cipherEnv.algorithm) {
          throw new Error(
            `${label} options.algorithm does not match envelope.algorithm`
          );
        }
        const keyBytes = cipherKey(key, label, cipherMeta(cipherEnv.algorithm));
        if (hostName() === "browser") {
          return taskRuntime.Task.from(
            webCryptoCipherDecrypt(cipherEnv, keyBytes, cipherOpts)
          );
        }
        return taskRuntime.Task.resolved(
          nodeCipherDecrypt(cipherEnv, keyBytes, cipherOpts)
        );
      }
      async function webCryptoHkdfSha256(args) {
        if (args.length === 0) {
          return new BinaryString();
        }
        const subtle = subtleCrypto();
        if (!subtle) {
          return hkdfSha256(
            new BinaryString(args.inputKeyMaterial),
            args.length,
            new BinaryString(args.salt),
            new BinaryString(args.info)
          );
        }
        const key = await subtle.importKey(
          "raw",
          args.inputKeyMaterial,
          "HKDF",
          false,
          ["deriveBits"]
        );
        const bits = await subtle.deriveBits(
          {
            name: "HKDF",
            hash: "SHA-256",
            salt: args.salt,
            info: args.info
          },
          key,
          args.length * 8
        );
        return new BinaryString(new Uint8Array(bits));
      }
      function signingAlgorithm(algorithm, label) {
        const value = algorithm == null ? "ed25519" : String(algorithm);
        if (!SIGNING_ALGORITHMS[value]) {
          throw new Error(
            `${label} only supports ed25519, ecdsa-p256-sha256, and ecdsa-p384-sha384`
          );
        }
        return value;
      }
      function signingAlgorithmOption(options, label) {
        return options.algorithm == null ? null : signingAlgorithm(options.algorithm, label);
      }
      function browserSigningAlgorithm(algorithm, label) {
        if (!signingCapabilities().includes(algorithm)) {
          throw new Error(
            `${label} signing algorithm '${algorithm}' is not available on host browser`
          );
        }
        return algorithm;
      }
      function signingMeta(algorithm) {
        return SIGNING_ALGORITHMS[algorithm];
      }
      function keyAgreementAlgorithm(value = "x25519", label) {
        if (value == null) {
          value = "x25519";
        }
        value = String(value);
        if (!KEY_AGREEMENT_ALGORITHMS[value]) {
          throw new Error(`${label} only supports x25519`);
        }
        return value;
      }
      function keyAgreementAlgorithmOption(options, label) {
        return options.algorithm == null ? null : keyAgreementAlgorithm(options.algorithm, label);
      }
      function keyAgreementMeta(algorithm) {
        return KEY_AGREEMENT_ALGORITHMS[algorithm];
      }
      function keyFormat(key, optionsValue, label) {
        const options = optionalDict(optionsValue, label, "Dict options");
        if (options.format != null) {
          return String(options.format);
        }
        return key && key.bytes instanceof Uint8Array ? "raw" : "pem";
      }
      function nodeUnsupported(label) {
        throw new Error(`${label} signing is unavailable on this host`);
      }
      function keyAgreementUnsupported(label) {
        throw new Error(`${label} key agreement is unavailable on this host`);
      }
      function derLength(length) {
        if (length < 128) {
          return Uint8Array.of(length);
        }
        const bytes = [];
        while (length > 0) {
          bytes.unshift(length & 255);
          length >>= 8;
        }
        return Uint8Array.of(128 | bytes.length, ...bytes);
      }
      function derElement(tag, body) {
        return concatBytes(Uint8Array.of(tag), derLength(body.length), body);
      }
      function derSequence(...items) {
        return derElement(48, concatBytes(...items));
      }
      function derIntegerSmall(value) {
        return derElement(2, Uint8Array.of(value));
      }
      function derOctetString(bytes) {
        return derElement(4, bytes);
      }
      function derOid(bytes) {
        return derElement(6, Uint8Array.from(bytes));
      }
      function derBitString(bytes) {
        return derElement(3, concatBytes(Uint8Array.of(0), bytes));
      }
      function ecCurveOid(algorithm) {
        return algorithm === "ecdsa-p256-sha256" ? [42, 134, 72, 206, 61, 3, 1, 7] : [43, 129, 4, 0, 34];
      }
      function pkcs8DerFromRawSeed(seed) {
        return concatBytes(
          Uint8Array.from([
            48,
            46,
            2,
            1,
            0,
            48,
            5,
            6,
            3,
            43,
            101,
            112,
            4,
            34,
            4,
            32
          ]),
          seed
        );
      }
      function x25519Pkcs8DerFromRawPrivate(bytes) {
        return concatBytes(
          Uint8Array.from([
            48,
            46,
            2,
            1,
            0,
            48,
            5,
            6,
            3,
            43,
            101,
            110,
            4,
            34,
            4,
            32
          ]),
          bytes
        );
      }
      function x25519SpkiDerFromRawPublic(bytes) {
        return concatBytes(
          Uint8Array.from([
            48,
            42,
            48,
            5,
            6,
            3,
            43,
            101,
            110,
            3,
            33,
            0
          ]),
          bytes
        );
      }
      function ecdsaPkcs8DerFromRawScalar(scalar, algorithm) {
        return derSequence(
          derIntegerSmall(0),
          derSequence(
            derOid([42, 134, 72, 206, 61, 2, 1]),
            derOid(ecCurveOid(algorithm))
          ),
          derOctetString(derSequence(
            derIntegerSmall(1),
            derOctetString(scalar)
          ))
        );
      }
      function ecdsaSpkiDerFromRawPublic(publicKey, algorithm) {
        return derSequence(
          derSequence(
            derOid([42, 134, 72, 206, 61, 2, 1]),
            derOid(ecCurveOid(algorithm))
          ),
          derBitString(publicKey)
        );
      }
      function derReader(bytes) {
        return {
          bytes,
          offset: 0,
          readElement(expectedTag = null) {
            if (this.offset + 2 > this.bytes.length) {
              throw new Error("truncated DER");
            }
            const tag = this.bytes[this.offset++];
            if (expectedTag != null && tag !== expectedTag) {
              throw new Error("unexpected DER tag");
            }
            let length = this.bytes[this.offset++];
            if (length & 128) {
              const count = length & 127;
              if (count === 0 || count > 4 || this.offset + count > this.bytes.length) {
                throw new Error("invalid DER length");
              }
              length = 0;
              for (let i = 0; i < count; ++i) {
                length = length << 8 | this.bytes[this.offset++];
              }
            }
            if (this.offset + length > this.bytes.length) {
              throw new Error("truncated DER value");
            }
            const body = this.bytes.slice(this.offset, this.offset + length);
            this.offset += length;
            return body;
          }
        };
      }
      function derIntegerToFixed(integer, length) {
        let value = integer;
        while (value.length > 0 && value[0] === 0) {
          value = value.slice(1);
        }
        if (value.length > length) {
          throw new Error("ECDSA integer too long");
        }
        const out = new Uint8Array(length);
        out.set(value, length - value.length);
        return out;
      }
      function derToEcdsaRawSignature(signature, algorithm) {
        const meta = signingMeta(algorithm);
        const reader = derReader(signature);
        const seqReader = derReader(reader.readElement(48));
        const r = derIntegerToFixed(
          seqReader.readElement(2),
          meta.signatureLength / 2
        );
        const s = derIntegerToFixed(
          seqReader.readElement(2),
          meta.signatureLength / 2
        );
        if (reader.offset !== signature.length || seqReader.offset !== seqReader.bytes.length) {
          throw new Error("trailing DER data");
        }
        return concatBytes(r, s);
      }
      function ecdsaIntegerFromRaw(bytes) {
        let value = bytes;
        while (value.length > 0 && value[0] === 0) {
          value = value.slice(1);
        }
        if (value.length === 0) {
          value = Uint8Array.of(0);
        }
        if (value[0] & 128) {
          value = concatBytes(Uint8Array.of(0), value);
        }
        return derElement(2, value);
      }
      function ecdsaRawSignatureToDer(signature) {
        const half = signature.length / 2;
        return derSequence(
          ecdsaIntegerFromRaw(signature.slice(0, half)),
          ecdsaIntegerFromRaw(signature.slice(half))
        );
      }
      function algorithmFromJwk(jwk, label) {
        if (jwk.kty === "OKP" && jwk.crv === "Ed25519") {
          return "ed25519";
        }
        if (jwk.kty === "OKP" && jwk.crv === "X25519") {
          return "x25519";
        }
        if (jwk.kty === "EC" && jwk.crv === "P-256") {
          return "ecdsa-p256-sha256";
        }
        if (jwk.kty === "EC" && jwk.crv === "P-384") {
          return "ecdsa-p384-sha384";
        }
        throw new Error(`${label} expects an Ed25519, P-256, P-384, or X25519 key`);
      }
      function algorithmFromNodeKey(key, label) {
        if (key.asymmetricKeyType === "ed25519") {
          return "ed25519";
        }
        if (key.asymmetricKeyType === "ec") {
          const curve = key.asymmetricKeyDetails?.namedCurve;
          if (curve === "prime256v1") {
            return "ecdsa-p256-sha256";
          }
          if (curve === "secp384r1") {
            return "ecdsa-p384-sha384";
          }
        }
        if (key.asymmetricKeyType === "x25519") {
          return "x25519";
        }
        return algorithmFromJwk(key.export({ format: "jwk" }), label);
      }
      function rawPublicFromJwk(jwk, label) {
        const algorithm = algorithmFromJwk(jwk, label);
        if (algorithm === "ed25519") {
          return base64urlDecode(jwk.x);
        }
        if (algorithm === "x25519") {
          const x2 = base64urlDecode(jwk.x);
          if (!x2 || x2.length !== 32) {
            throw new Error(`${label} has invalid X25519 public key`);
          }
          return x2;
        }
        const x = base64urlDecode(jwk.x);
        const y = base64urlDecode(jwk.y);
        const meta = signingMeta(algorithm);
        const width = (meta.publicLength - 1) / 2;
        if (!x || !y || x.length !== width || y.length !== width) {
          throw new Error(`${label} has invalid EC public key coordinates`);
        }
        return concatBytes(Uint8Array.of(4), x, y);
      }
      function rawPrivateFromJwk(jwk, label) {
        const algorithm = algorithmFromJwk(jwk, label);
        const d = base64urlDecode(jwk.d);
        if (algorithm === "x25519") {
          if (!d || d.length !== 32) {
            throw new Error(`${label} has invalid X25519 private key`);
          }
          return d;
        }
        if (!d || d.length !== signingMeta(algorithm).privateLength) {
          throw new Error(`${label} has invalid private key scalar`);
        }
        return d;
      }
      function jwkFromRawPrivate(bytes, algorithm, label) {
        const meta = signingMeta(algorithm);
        if (bytes.length !== meta.privateLength) {
          throw new Error(`${label} expects a ${meta.privateLength}-byte raw private key`);
        }
        if (meta.type === "ed25519") {
          return {
            kty: "OKP",
            crv: "Ed25519",
            d: base64url(bytes)
          };
        }
        return null;
      }
      function jwkFromRawPublic(bytes, algorithm, label) {
        const meta = signingMeta(algorithm);
        if (bytes.length !== meta.publicLength) {
          throw new Error(`${label} expects a ${meta.publicLength}-byte raw public key`);
        }
        if (meta.type === "ed25519") {
          return { kty: "OKP", crv: "Ed25519", x: base64url(bytes) };
        }
        if (bytes[0] !== 4) {
          throw new Error(`${label} expects an uncompressed EC public key`);
        }
        const width = (meta.publicLength - 1) / 2;
        return {
          kty: "EC",
          crv: meta.jwkCurve,
          x: base64url(bytes.slice(1, 1 + width)),
          y: base64url(bytes.slice(1 + width))
        };
      }
      function algorithmFromRawPublic(bytes, label) {
        if (bytes.length === 32) {
          return "ed25519";
        }
        if (bytes.length === 65 && bytes[0] === 4) {
          return "ecdsa-p256-sha256";
        }
        if (bytes.length === 97 && bytes[0] === 4) {
          return "ecdsa-p384-sha384";
        }
        throw new Error(
          `${label} expects a 32-byte Ed25519 key, 65-byte P-256 public key, or 97-byte P-384 public key`
        );
      }
      function nodePrivateKeyFromRaw(key, algorithm, label) {
        const bytes = assertBinaryString(key, label, "BinaryString key");
        const meta = signingMeta(algorithm);
        if (bytes.length !== meta.privateLength) {
          throw new Error(`${label} expects a ${meta.privateLength}-byte raw private key`);
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPrivateKey !== "function") {
          nodeUnsupported(label);
        }
        if (meta.type === "ed25519") {
          return crypto.createPrivateKey({
            key: Buffer.from(pkcs8DerFromRawSeed(bytes)),
            format: "der",
            type: "pkcs8"
          });
        }
        return crypto.createPrivateKey({
          key: Buffer.from(ecdsaPkcs8DerFromRawScalar(bytes, algorithm)),
          format: "der",
          type: "pkcs8"
        });
      }
      function nodePublicKeyFromRaw(key, algorithm, label) {
        const bytes = assertBinaryString(key, label, "BinaryString key");
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPublicKey !== "function") {
          nodeUnsupported(label);
        }
        return crypto.createPublicKey({
          key: jwkFromRawPublic(bytes, algorithm, label),
          format: "jwk"
        });
      }
      function x25519PrivateBytes(key, label) {
        const bytes = assertBinaryString(key, label, "BinaryString key");
        if (bytes.length !== 32) {
          throw new Error(`${label} expects a 32-byte raw private key`);
        }
        return bytes;
      }
      function x25519PublicBytes(key, label) {
        const bytes = assertBinaryString(key, label, "BinaryString key");
        if (bytes.length !== 32) {
          throw new Error(`${label} expects a 32-byte raw public key`);
        }
        return bytes;
      }
      function nodeX25519PrivateKeyFromRaw(key, label) {
        const bytes = x25519PrivateBytes(key, label);
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPrivateKey !== "function") {
          keyAgreementUnsupported(label);
        }
        return crypto.createPrivateKey({
          key: Buffer.from(x25519Pkcs8DerFromRawPrivate(bytes)),
          format: "der",
          type: "pkcs8"
        });
      }
      function nodeX25519PublicKeyFromRaw(key, label) {
        const bytes = x25519PublicBytes(key, label);
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPublicKey !== "function") {
          keyAgreementUnsupported(label);
        }
        return crypto.createPublicKey({
          key: Buffer.from(x25519SpkiDerFromRawPublic(bytes)),
          format: "der",
          type: "spki"
        });
      }
      function syncBrowserSigningError(label, asyncName) {
        throw new Error(
          `${label} is not available synchronously on host browser; use ${asyncName}`
        );
      }
      function syncBrowserKeyAgreementError(label, asyncName) {
        throw new Error(
          `${label} is not available synchronously on host browser; use ${asyncName}`
        );
      }
      function browserSigningUnsupported(label) {
        throw new Error(`${label} signing is unavailable on this host`);
      }
      function subtleSigningCrypto() {
        return globalThis.crypto && globalThis.crypto.subtle && typeof globalThis.crypto.subtle.generateKey === "function" && typeof globalThis.crypto.subtle.importKey === "function" && typeof globalThis.crypto.subtle.exportKey === "function" && typeof globalThis.crypto.subtle.sign === "function" && typeof globalThis.crypto.subtle.verify === "function" ? globalThis.crypto.subtle : null;
      }
      function subtleKeyAgreementCrypto() {
        return globalThis.crypto && globalThis.crypto.subtle && typeof globalThis.crypto.subtle.generateKey === "function" && typeof globalThis.crypto.subtle.importKey === "function" && typeof globalThis.crypto.subtle.exportKey === "function" && typeof globalThis.crypto.subtle.deriveBits === "function" ? globalThis.crypto.subtle : null;
      }
      var X509_OIDS = {
        "2.5.4.3": "CN",
        "2.5.4.6": "C",
        "2.5.4.7": "L",
        "2.5.4.8": "ST",
        "2.5.4.10": "O",
        "2.5.4.11": "OU",
        "1.2.840.10045.2.1": "ecPublicKey",
        "1.2.840.10045.3.1.7": "prime256v1",
        "1.3.132.0.34": "secp384r1",
        "1.3.101.112": "ed25519"
      };
      function derError(label) {
        throw new Error(`${label} expects DER X.509 certificate data`);
      }
      function x509DerReader(bytes, label) {
        return {
          bytes,
          offset: 0,
          readElement(expectedTag = null) {
            if (this.offset + 2 > this.bytes.length) {
              derError(label);
            }
            const start = this.offset;
            const tag = this.bytes[this.offset++];
            if (expectedTag != null && tag !== expectedTag) {
              derError(label);
            }
            let length = this.bytes[this.offset++];
            if (length & 128) {
              const count = length & 127;
              if (count === 0 || count > 4 || this.offset + count > this.bytes.length) {
                derError(label);
              }
              length = 0;
              for (let i = 0; i < count; ++i) {
                length = length << 8 | this.bytes[this.offset++];
              }
            }
            if (this.offset + length > this.bytes.length) {
              derError(label);
            }
            const headerLength = this.offset - start;
            const body = this.bytes.slice(this.offset, this.offset + length);
            const raw = this.bytes.slice(start, this.offset + length);
            this.offset += length;
            return { tag, body, raw, headerLength };
          },
          readBody(expectedTag = null) {
            return this.readElement(expectedTag).body;
          },
          empty() {
            return this.offset >= this.bytes.length;
          }
        };
      }
      function oidFromDer(bytes) {
        if (bytes.length === 0) {
          return "";
        }
        const parts = [Math.floor(bytes[0] / 40), bytes[0] % 40];
        let value = 0;
        for (let i = 1; i < bytes.length; ++i) {
          value = value << 7 | bytes[i] & 127;
          if ((bytes[i] & 128) === 0) {
            parts.push(value);
            value = 0;
          }
        }
        return parts.join(".");
      }
      function x509TextValue(tag, body) {
        if (tag === 12 || tag === 19 || tag === 22 || tag === 20) {
          return new TextDecoder().decode(body);
        }
        if (tag === 30) {
          let out = "";
          for (let i = 0; i + 1 < body.length; i += 2) {
            out += String.fromCharCode(body[i] << 8 | body[i + 1]);
          }
          return out;
        }
        return Array.from(body, (byte) => byte.toString(16).padStart(2, "0")).join("").toUpperCase();
      }
      function x509NameString(bytes, label) {
        const seq = x509DerReader(bytes, label);
        const parts = [];
        while (!seq.empty()) {
          const set = x509DerReader(seq.readBody(49), label);
          while (!set.empty()) {
            const attr = x509DerReader(set.readBody(48), label);
            const oid = oidFromDer(attr.readBody(6));
            const value = attr.readElement();
            const name2 = X509_OIDS[oid] || oid;
            parts.push(`${name2}=${x509TextValue(value.tag, value.body)}`);
          }
        }
        return parts.join(", ");
      }
      function x509SerialHex(bytes) {
        let value = bytes;
        while (value.length > 1 && value[0] === 0) {
          value = value.slice(1);
        }
        return Array.from(value, (byte) => byte.toString(16).padStart(2, "0")).join("").toUpperCase();
      }
      function x509TimeEpoch(element, label) {
        const text = new TextDecoder().decode(element.body);
        let year;
        let month;
        let day;
        let hour;
        let minute;
        let second;
        if (element.tag === 23) {
          const match = text.match(/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/u);
          if (!match) {
            derError(label);
          }
          year = Number(match[1]);
          year += year >= 50 ? 1900 : 2e3;
          month = Number(match[2]);
          day = Number(match[3]);
          hour = Number(match[4]);
          minute = Number(match[5]);
          second = Number(match[6]);
        } else if (element.tag === 24) {
          const match = text.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})Z$/u);
          if (!match) {
            derError(label);
          }
          year = Number(match[1]);
          month = Number(match[2]);
          day = Number(match[3]);
          hour = Number(match[4]);
          minute = Number(match[5]);
          second = Number(match[6]);
        } else {
          derError(label);
        }
        return Math.floor(Date.UTC(year, month - 1, day, hour, minute, second) / 1e3);
      }
      function x509BitStringPayload(bytes, label) {
        if (bytes.length === 0 || bytes[0] !== 0) {
          derError(label);
        }
        return bytes.slice(1);
      }
      function x509Spki(bytes, label) {
        const seq = x509DerReader(bytes, label);
        const alg = x509DerReader(seq.readBody(48), label);
        const algOid = oidFromDer(alg.readBody(6));
        let curveOid = null;
        if (!alg.empty()) {
          const param = alg.readElement();
          if (param.tag === 6) {
            curveOid = oidFromDer(param.body);
          }
        }
        const publicBytes = x509BitStringPayload(seq.readBody(3), label);
        return { algOid, curveOid, publicBytes };
      }
      function parseX509Der(der, label = "Certificate.parse") {
        const bytes = Uint8Array.from(der);
        const cert = x509DerReader(bytes, label);
        const certSeq = x509DerReader(cert.readBody(48), label);
        const tbs = x509DerReader(certSeq.readBody(48), label);
        if (!cert.empty()) {
          derError(label);
        }
        if (!tbs.empty()) {
          const next = tbs.readElement();
          if (next.tag !== 160) {
            tbs.offset = 0;
          }
        }
        const serial = x509SerialHex(tbs.readBody(2));
        tbs.readElement(48);
        const issuer = x509NameString(tbs.readBody(48), label);
        const validity = x509DerReader(tbs.readBody(48), label);
        const notBefore = x509TimeEpoch(validity.readElement(), label);
        const notAfter = x509TimeEpoch(validity.readElement(), label);
        const subject = x509NameString(tbs.readBody(48), label);
        const spki = x509Spki(tbs.readBody(48), label);
        return new Certificate(new SecureCertificate(
          bytes,
          subject,
          issuer,
          serial,
          notBefore,
          notAfter,
          spki
        ));
      }
      var SecureCertificate = class {
        constructor(der, subject, issuer, serial, notBefore, notAfter, spki) {
          this.der = der;
          this.subject = subject;
          this.issuer = issuer;
          this.serial = serial;
          this.notBefore = notBefore;
          this.notAfter = notAfter;
          this.spki = spki;
        }
      };
      var SecureTlsIdentity = class {
        constructor(certPem, keyPem, password = "", source = "pem", chainPem = certPem) {
          this.certPem = certPem;
          this.keyPem = keyPem;
          this.password = password;
          this.source = source;
          this.chainPem = chainPem;
        }
      };
      var SecureKeyAgreement = class {
        constructor(algorithm, key, publicKey = null, rawPrivate = null, rawPublic = null) {
          this.algorithm = algorithm;
          this.key = key;
          this.publicKey = publicKey;
          this.rawPrivate = rawPrivate;
          this.rawPublic = rawPublic;
        }
      };
      var SecureSigningKey = class {
        constructor(algorithm, key, publicKey = null, rawPrivate = null, rawPublic = null) {
          this.algorithm = algorithm;
          this.key = key;
          this.publicKey = publicKey;
          this.rawPrivate = rawPrivate;
          this.rawPublic = rawPublic;
        }
      };
      var SecurePublicKey = class {
        constructor(algorithm, key, rawPublic = null) {
          this.algorithm = algorithm;
          this.key = key;
          this.rawPublic = rawPublic;
        }
      };
      function signingGenerate(algorithm = "ed25519") {
        algorithm = signingAlgorithm(algorithm, "SigningKey.generate");
        if (hostName() === "browser") {
          syncBrowserSigningError(
            "SigningKey.generate",
            "SigningKey.generate_async"
          );
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.generateKeyPairSync !== "function") {
          nodeUnsupported("SigningKey.generate");
        }
        const meta = signingMeta(algorithm);
        const pair = meta.type === "ed25519" ? crypto.generateKeyPairSync("ed25519") : crypto.generateKeyPairSync("ec", { namedCurve: meta.nodeCurve });
        return new SigningKey(new SecureSigningKey(algorithm, pair.privateKey));
      }
      async function browserSigningKeyFromPair(algorithm, pair) {
        const privateJwk = await globalThis.crypto.subtle.exportKey(
          "jwk",
          pair.privateKey
        );
        const publicJwk = await globalThis.crypto.subtle.exportKey(
          "jwk",
          pair.publicKey
        );
        return new SigningKey(new SecureSigningKey(
          algorithm,
          pair.privateKey,
          pair.publicKey,
          rawPrivateFromJwk(privateJwk, "SigningKey.generate_async"),
          rawPublicFromJwk(publicJwk, "SigningKey.generate_async")
        ));
      }
      async function signingGenerateAsyncValue(algorithm = "ed25519") {
        algorithm = signingAlgorithm(algorithm, "SigningKey.generate");
        if (hostName() !== "browser") {
          return signingGenerate(algorithm);
        }
        browserSigningAlgorithm(algorithm, "SigningKey.generate_async");
        const subtle = subtleSigningCrypto();
        if (!subtle) {
          browserSigningUnsupported("SigningKey.generate_async");
        }
        const meta = signingMeta(algorithm);
        try {
          const pair = await subtle.generateKey(
            meta.type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", namedCurve: meta.webCurve },
            true,
            ["sign", "verify"]
          );
          return await browserSigningKeyFromPair(algorithm, pair);
        } catch (_err) {
          browserSigningUnsupported("SigningKey.generate_async");
        }
      }
      function signingImportPrivate(key, options = null) {
        const label = "SigningKey.import_private";
        if (hostName() === "browser") {
          syncBrowserSigningError(label, "SigningKey.import_private_async");
        }
        const opts = optionalDict(options, label, "Dict options");
        const format = keyFormat(key, options, label);
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPrivateKey !== "function") {
          nodeUnsupported(label);
        }
        let algorithm = signingAlgorithmOption(opts, label);
        let keyObject;
        if (format === "raw") {
          algorithm ??= "ed25519";
          keyObject = nodePrivateKeyFromRaw(key, algorithm, label);
        } else if (format === "pem") {
          const pem = assertString(key, label, "String key");
          const password = opts.password == null ? null : String(opts.password);
          keyObject = crypto.createPrivateKey(
            password == null ? pem : { key: pem, passphrase: password }
          );
          const actual = algorithmFromNodeKey(keyObject, label);
          if (algorithm && actual !== algorithm) {
            throw new Error(`${label} PEM key algorithm does not match ${algorithm}`);
          }
          algorithm = actual;
        } else {
          throw new Error(`${label} only supports raw and pem formats`);
        }
        return new SigningKey(new SecureSigningKey(algorithm, keyObject));
      }
      async function signingImportPrivateAsyncValue(key, options = null) {
        const label = "SigningKey.import_private";
        if (hostName() !== "browser") {
          return signingImportPrivate(key, options);
        }
        const subtle = subtleSigningCrypto();
        if (!subtle) {
          browserSigningUnsupported(`${label}_async`);
        }
        const opts = optionalDict(options, label, "Dict options");
        const format = keyFormat(key, options, label);
        let algorithm = signingAlgorithmOption(opts, label);
        let der;
        if (format === "raw") {
          const bytes = assertBinaryString(key, label, "BinaryString key");
          algorithm ??= "ed25519";
          browserSigningAlgorithm(algorithm, `${label}_async`);
          const meta = signingMeta(algorithm);
          if (bytes.length !== meta.privateLength) {
            throw new Error(`${label} expects a ${meta.privateLength}-byte raw private key`);
          }
          der = meta.type === "ed25519" ? pkcs8DerFromRawSeed(bytes) : ecdsaPkcs8DerFromRawScalar(bytes, algorithm);
        } else if (format === "pem") {
          der = pemToDer(key, label);
          if (algorithm) {
            browserSigningAlgorithm(algorithm, `${label}_async`);
          }
        } else {
          throw new Error(`${label} only supports raw and pem formats`);
        }
        try {
          let cryptoKey = null;
          let jwk = null;
          const candidates = algorithm ? [algorithm] : signingCapabilities();
          for (const candidate of candidates) {
            const meta = signingMeta(candidate);
            try {
              cryptoKey = await subtle.importKey(
                "pkcs8",
                der,
                meta.type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", namedCurve: meta.webCurve },
                true,
                ["sign"]
              );
              jwk = await subtle.exportKey("jwk", cryptoKey);
              algorithm = algorithmFromJwk(jwk, label);
              break;
            } catch (_err) {
              cryptoKey = null;
            }
          }
          if (!cryptoKey) {
            browserSigningUnsupported(`${label}_async`);
          }
          const rawPublic = rawPublicFromJwk(jwk, label);
          const publicKey = await subtle.importKey(
            signingMeta(algorithm).type === "ed25519" ? "raw" : "jwk",
            signingMeta(algorithm).type === "ed25519" ? rawPublic : jwkFromRawPublic(rawPublic, algorithm, label),
            signingMeta(algorithm).type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", namedCurve: signingMeta(algorithm).webCurve },
            true,
            ["verify"]
          );
          return new SigningKey(new SecureSigningKey(
            algorithm,
            cryptoKey,
            publicKey,
            rawPrivateFromJwk(jwk, label),
            rawPublic
          ));
        } catch (_err) {
          browserSigningUnsupported(`${label}_async`);
        }
      }
      function signingImportPublic(key, options = null) {
        const label = "SigningKey.import_public";
        if (hostName() === "browser") {
          syncBrowserSigningError(label, "SigningKey.import_public_async");
        }
        const opts = optionalDict(options, label, "Dict options");
        const format = keyFormat(key, options, label);
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.createPublicKey !== "function") {
          nodeUnsupported(label);
        }
        let algorithm = signingAlgorithmOption(opts, label);
        let keyObject;
        if (format === "raw") {
          const bytes = assertBinaryString(key, label, "BinaryString key");
          algorithm ??= algorithmFromRawPublic(bytes, label);
          keyObject = nodePublicKeyFromRaw(key, algorithm, label);
        } else if (format === "pem") {
          keyObject = crypto.createPublicKey(assertString(key, label, "String key"));
          const actual = algorithmFromNodeKey(keyObject, label);
          if (algorithm && actual !== algorithm) {
            throw new Error(`${label} PEM key algorithm does not match ${algorithm}`);
          }
          algorithm = actual;
        } else {
          throw new Error(`${label} only supports raw and pem formats`);
        }
        return new PublicKey(new SecurePublicKey(algorithm, keyObject));
      }
      async function signingImportPublicAsyncValue(key, options = null) {
        const label = "SigningKey.import_public";
        if (hostName() !== "browser") {
          return signingImportPublic(key, options);
        }
        const subtle = subtleSigningCrypto();
        if (!subtle) {
          browserSigningUnsupported(`${label}_async`);
        }
        const opts = optionalDict(options, label, "Dict options");
        const format = keyFormat(key, options, label);
        let algorithm = signingAlgorithmOption(opts, label);
        let importData;
        let importFormat;
        if (format === "raw") {
          importData = assertBinaryString(key, label, "BinaryString key");
          algorithm ??= algorithmFromRawPublic(importData, label);
          browserSigningAlgorithm(algorithm, `${label}_async`);
          importFormat = signingMeta(algorithm).type === "ed25519" ? "raw" : "jwk";
          if (importFormat === "jwk") {
            importData = jwkFromRawPublic(importData, algorithm, label);
          }
        } else if (format === "pem") {
          importData = pemToDer(key, label);
          importFormat = "spki";
          if (algorithm) {
            browserSigningAlgorithm(algorithm, `${label}_async`);
          }
        } else {
          throw new Error(`${label} only supports raw and pem formats`);
        }
        try {
          let cryptoKey = null;
          let jwk = null;
          const candidates = algorithm ? [algorithm] : signingCapabilities();
          for (const candidate of candidates) {
            const meta = signingMeta(candidate);
            try {
              cryptoKey = await subtle.importKey(
                importFormat,
                importData,
                meta.type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", namedCurve: meta.webCurve },
                true,
                ["verify"]
              );
              jwk = await subtle.exportKey("jwk", cryptoKey);
              algorithm = algorithmFromJwk(jwk, label);
              break;
            } catch (_err) {
              cryptoKey = null;
            }
          }
          if (!cryptoKey) {
            browserSigningUnsupported(`${label}_async`);
          }
          return new PublicKey(new SecurePublicKey(
            algorithm,
            cryptoKey,
            rawPublicFromJwk(jwk, label)
          ));
        } catch (_err) {
          browserSigningUnsupported(`${label}_async`);
        }
      }
      function signingPublicKey(signingKey) {
        const secure = signingKey.__secureSigningKey;
        if (hostName() === "browser") {
          if (secure.publicKey && secure.rawPublic) {
            return new PublicKey(new SecurePublicKey(
              secure.algorithm,
              secure.publicKey,
              secure.rawPublic
            ));
          }
          throw new Error(
            "SigningKey.public_key is unavailable for this browser key"
          );
        }
        const crypto = nodeCrypto();
        return new PublicKey(new SecurePublicKey(
          secure.algorithm,
          crypto.createPublicKey(secure.key)
        ));
      }
      function signingSign(signingKey, message) {
        const label = "SigningKey.sign";
        if (hostName() === "browser") {
          syncBrowserSigningError(label, "SigningKey.sign_async");
        }
        const bytes = assertBinaryString(message, label, "BinaryString message");
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.sign !== "function") {
          nodeUnsupported(label);
        }
        const meta = signingMeta(signingKey.__secureSigningKey.algorithm);
        return new BinaryString(
          new Uint8Array(crypto.sign(meta.nodeHash ?? null, bytes, signingKey.__secureSigningKey.key))
        );
      }
      async function signingSignAsyncValue(signingKey, message) {
        const label = "SigningKey.sign";
        const bytes = assertBinaryString(message, label, "BinaryString message");
        if (hostName() !== "browser") {
          return signingSign(signingKey, message);
        }
        const subtle = subtleSigningCrypto();
        if (!subtle) {
          browserSigningUnsupported(`${label}_async`);
        }
        const meta = signingMeta(signingKey.__secureSigningKey.algorithm);
        try {
          const rawSignature = new Uint8Array(await subtle.sign(
            meta.type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", hash: meta.webHash },
            signingKey.__secureSigningKey.key,
            bytes
          ));
          return new BinaryString(
            meta.type === "ed25519" ? rawSignature : ecdsaRawSignatureToDer(rawSignature)
          );
        } catch (_err) {
          browserSigningUnsupported(`${label}_async`);
        }
      }
      function signingExportPrivate(signingKey, optionsValue = null) {
        const label = "SigningKey.export_private";
        const options = optionalDict(optionsValue, label, "Dict options");
        const format = options.format == null ? "raw" : String(options.format);
        const secure = signingKey.__secureSigningKey;
        if (format === "raw") {
          if (secure.rawPrivate) {
            return new BinaryString(secure.rawPrivate);
          }
          return new BinaryString(
            rawPrivateFromJwk(secure.key.export({ format: "jwk" }), label)
          );
        }
        if (format === "pem") {
          if (hostName() !== "browser") {
            return String(secure.key.export({
              format: "pem",
              type: "pkcs8"
            }));
          }
          const meta = signingMeta(secure.algorithm);
          const der = meta.type === "ed25519" ? pkcs8DerFromRawSeed(secure.rawPrivate) : ecdsaPkcs8DerFromRawScalar(secure.rawPrivate, secure.algorithm);
          return derToPem("PRIVATE KEY", der);
        }
        throw new Error(`${label} only supports raw and pem formats`);
      }
      function certificateParse(input) {
        const label = "Certificate.parse";
        if (input && input.bytes instanceof Uint8Array) {
          return parseX509Der(input.bytes, label);
        }
        if (hostName() === "browser") {
          throw new Error(`${label} only supports DER BinaryString on host browser`);
        }
        return parseX509Der(certificatePemBlocks(input, label)[0], label);
      }
      function certificateParseChain(input) {
        const label = "Certificate.parse_chain";
        if (input && input.bytes instanceof Uint8Array) {
          return [parseX509Der(input.bytes, label)];
        }
        if (hostName() === "browser") {
          throw new Error(`${label} only supports DER BinaryString on host browser`);
        }
        return certificatePemBlocks(input, label).map((der) => parseX509Der(der, label));
      }
      function certificateState(certificate, label) {
        if (!(certificate instanceof Certificate)) {
          throw new Error(`TypeException: ${label} expects Certificate`);
        }
        return certificate.__secureCertificate;
      }
      function certificateFingerprint(certificate, algorithm) {
        const label = "Certificate.fingerprint";
        const state = certificateState(certificate, label);
        const value = algorithm == null ? "sha256" : String(algorithm).toLowerCase();
        if (value !== "sha256") {
          throw new Error(`${label} only supports sha256`);
        }
        return new BinaryString(
          digestBytes("sha256", new BinaryString(state.der), label)
        );
      }
      function certificatePublicKey(certificate) {
        const label = "Certificate.public_key";
        if (hostName() === "browser") {
          throw new Error(`${label} is not supported on host browser`);
        }
        const state = certificateState(certificate, label);
        const { algOid, curveOid, publicBytes } = state.spki;
        if (algOid === "1.3.101.112") {
          const raw = Uint8Array.from(publicBytes);
          return new PublicKey(new SecurePublicKey(
            "ed25519",
            nodePublicKeyFromRaw(new BinaryString(raw), "ed25519", label),
            raw
          ));
        }
        if (algOid === "1.2.840.10045.2.1" && curveOid === "1.2.840.10045.3.1.7") {
          const raw = Uint8Array.from(publicBytes);
          return new PublicKey(new SecurePublicKey(
            "ecdsa-p256-sha256",
            nodePublicKeyFromRaw(
              new BinaryString(raw),
              "ecdsa-p256-sha256",
              label
            ),
            raw
          ));
        }
        if (algOid === "1.2.840.10045.2.1" && curveOid === "1.3.132.0.34") {
          const raw = Uint8Array.from(publicBytes);
          return new PublicKey(new SecurePublicKey(
            "ecdsa-p384-sha384",
            nodePublicKeyFromRaw(
              new BinaryString(raw),
              "ecdsa-p384-sha384",
              label
            ),
            raw
          ));
        }
        throw new Error(`${label} certificate public-key algorithm is unsupported`);
      }
      function certificateVerifyChain(chain, options = null) {
        const label = "Certificate.verify_chain";
        if (hostName() === "browser") {
          throw new Error(`${label} is not supported on host browser`);
        }
        if (!Array.isArray(chain) || chain.length === 0) {
          throw new Error(`TypeException: ${label} expects non-empty Array chain`);
        }
        const states = chain.map((certificate) => certificateState(certificate, label));
        const opts = certificateVerifyOptions(options, label);
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.X509Certificate !== "function") {
          throw new Error(`${label} requires X509Certificate support on host node`);
        }
        const rootCerts = certificateRootNodeCerts(opts.roots, crypto, label);
        if (opts.use_system_roots) {
          const tls = nodeTls();
          if (tls && Array.isArray(tls.rootCertificates)) {
            for (const pem of tls.rootCertificates) {
              rootCerts.push(new crypto.X509Certificate(pem));
            }
          }
        }
        const nodeChain = states.map(
          (state) => new crypto.X509Certificate(Buffer.from(state.der))
        );
        const verifiedAt = opts.time;
        let valid = true;
        let error = null;
        error = certificateVerifyNodeChain(nodeChain, rootCerts, verifiedAt);
        valid = error == null;
        let reason = valid ? "ok" : certificateVerifyReason(error);
        if (valid && opts.hostname != null) {
          if (!certificateHostnameMatches(states[0], opts.hostname)) {
            valid = false;
            reason = "hostname-mismatch";
            error = "hostname mismatch";
          }
        }
        return {
          valid,
          reason,
          error: valid ? null : error,
          hostname: opts.hostname,
          verified_at: verifiedAt,
          chain_length: chain.length
        };
      }
      function certificateVerifyOptions(options, label) {
        if (options == null) {
          options = {};
        }
        if (typeof options !== "object" || Array.isArray(options)) {
          throw new Error(`TypeException: ${label} expects Dict options`);
        }
        const useSystemRoots = options.use_system_roots == null ? false : options.use_system_roots;
        if (typeof useSystemRoots !== "boolean") {
          throw new Error(
            `TypeException: ${label} option 'use_system_roots' expects Boolean`
          );
        }
        let hostname = options.hostname == null ? null : options.hostname;
        if (hostname != null && typeof hostname !== "string") {
          throw new Error(`TypeException: ${label} option 'hostname' expects String`);
        }
        let time = options.time;
        if (time == null) {
          time = Math.floor(Date.now() / 1e3);
        } else if (time instanceof Time) {
          time = time.epoch();
        } else if (typeof time === "number") {
          time = Math.floor(time);
        } else {
          throw new Error(
            `TypeException: ${label} option 'time' expects Time, Number, or null`
          );
        }
        return {
          roots: options.roots,
          use_system_roots: useSystemRoots,
          hostname,
          time
        };
      }
      function certificateRootNodeCerts(value, crypto, label) {
        if (value == null) {
          return [];
        }
        if (value instanceof Certificate) {
          const state = certificateState(value, label);
          return [new crypto.X509Certificate(Buffer.from(state.der))];
        }
        if (typeof value === "string") {
          return certificatePemBlocks(value, label).map((der) => new crypto.X509Certificate(Buffer.from(der)));
        }
        if (Array.isArray(value)) {
          return value.flatMap(
            (item) => certificateRootNodeCerts(item, crypto, label)
          );
        }
        throw new Error(
          `TypeException: ${label} expects roots to be Certificate, String PEM, Array, or null`
        );
      }
      function certificateVerifyNodeChain(chain, roots, verifiedAt) {
        const verifiedDate = new Date(verifiedAt * 1e3);
        for (const cert of chain) {
          const notBefore = new Date(cert.validFrom);
          const notAfter = new Date(cert.validTo);
          if (verifiedDate < notBefore) {
            return "certificate is not yet valid";
          }
          if (verifiedDate > notAfter) {
            return "certificate has expired";
          }
        }
        for (let i = 0; i < chain.length; i++) {
          const child = chain[i];
          const issuer = chain[i + 1] || roots.find(
            (root) => child.checkIssued(root) && child.verify(root.publicKey)
          );
          if (!issuer) {
            return "certificate is not trusted";
          }
          if (!child.checkIssued(issuer) || !child.verify(issuer.publicKey)) {
            return "certificate signature is invalid";
          }
          if (i > 0 && issuer !== child && !child.ca) {
            return "certificate is not a CA";
          }
        }
        return null;
      }
      function certificateVerifyReason(error) {
        const text = String(error || "").toLowerCase();
        if (text === "" || text === "ok") {
          return "ok";
        }
        if (text.includes("hostname")) {
          return "hostname-mismatch";
        }
        if (text.includes("not valid yet") || text.includes("not yet valid")) {
          return "not-yet-valid";
        }
        if (text.includes("expired") || text.includes("not valid")) {
          return "expired";
        }
        if (text.includes("unknown_ca") || text.includes("not trusted") || text.includes("unknown ca")) {
          return "untrusted-root";
        }
        return "invalid-chain";
      }
      function certificateHostnameMatches(state, hostname) {
        const crypto = nodeCrypto();
        if (crypto && typeof crypto.X509Certificate === "function") {
          const cert = new crypto.X509Certificate(Buffer.from(state.der));
          if (isIpAddress(hostname) && typeof cert.checkIP === "function") {
            return !!cert.checkIP(hostname);
          }
          if (typeof cert.checkHost === "function") {
            return !!cert.checkHost(hostname);
          }
        }
        return certificateHostnameMatchesFallback(state, hostname);
      }
      function isIpAddress(text) {
        return /^(\d{1,3}\.){3}\d{1,3}$/u.test(text) || text.includes(":");
      }
      function certificateHostnameMatchesFallback(state, hostname) {
        const extensions = state.extensions || [];
        const subjectAltName = extensions.find(
          (ext) => ext.oid === "2.5.29.17"
        );
        if (subjectAltName) {
          for (const name2 of subjectAltName.names || []) {
            if (name2.type === "dns" && dnsNameMatches(name2.value, hostname)) {
              return true;
            }
            if (name2.type === "ip" && name2.value === hostname) {
              return true;
            }
          }
          return false;
        }
        const match = state.subject.match(/(?:^|,\s*)CN=([^,]+)/u);
        return !!(match && dnsNameMatches(match[1], hostname));
      }
      function dnsNameMatches(pattern, hostname) {
        pattern = String(pattern).toLowerCase();
        hostname = String(hostname).toLowerCase();
        if (pattern === hostname) {
          return true;
        }
        if (!pattern.startsWith("*.")) {
          return false;
        }
        const suffix = pattern.slice(1);
        return hostname.endsWith(suffix) && hostname.slice(0, -suffix.length).indexOf(".") === -1;
      }
      function binaryStringFromBytes(bytes) {
        let out = "";
        for (let i = 0; i < bytes.length; i += 8192) {
          out += String.fromCharCode(...bytes.slice(i, i + 8192));
        }
        return out;
      }
      function bytesFromBinaryString(text) {
        const bytes = new Uint8Array(text.length);
        for (let i = 0; i < text.length; i++) {
          bytes[i] = text.charCodeAt(i) & 255;
        }
        return bytes;
      }
      function forgeAsn1Bytes(forge, asn1) {
        return bytesFromBinaryString(forge.asn1.toDer(asn1).getBytes());
      }
      function tlsIdentityFromPem(certificatePem, privateKeyPem, password = null) {
        const label = "TlsIdentity.from_pem";
        const certPem = assertString(
          certificatePem,
          label,
          "String certificate_pem"
        );
        const keyPem = assertString(
          privateKeyPem,
          label,
          "String private_key_pem"
        );
        const pass = password == null ? "" : assertString(
          password,
          label,
          "String password"
        );
        const blocks = certificatePemBlocks(certPem, label);
        parseX509Der(blocks[0], label);
        if (!/-----BEGIN [A-Z ]*PRIVATE KEY-----/u.test(keyPem)) {
          throw new Error(`${label} expects PEM private key text`);
        }
        return new TlsIdentity(new SecureTlsIdentity(
          certificateDerToPem(blocks[0]),
          keyPem,
          pass,
          "pem",
          blocks.map(certificateDerToPem).join("")
        ));
      }
      function tlsIdentityFromPkcs12(bytesValue, password = null) {
        const label = "TlsIdentity.from_pkcs12";
        if (hostName() === "browser") {
          throw new Error(`${label} is not supported on host browser`);
        }
        const bytes = assertBinaryString(bytesValue, label, "BinaryString bytes");
        const pass = password == null ? "" : assertString(
          password,
          label,
          "String password"
        );
        const forge = nodeForge();
        if (!forge) {
          nodeUnsupported(label);
        }
        try {
          const asn1 = forge.asn1.fromDer(
            forge.util.createBuffer(binaryStringFromBytes(bytes))
          );
          const p12 = forge.pkcs12.pkcs12FromAsn1(asn1, false, pass);
          const keyBags = [
            ...p12.getBags({
              bagType: forge.pki.oids.pkcs8ShroudedKeyBag
            })[forge.pki.oids.pkcs8ShroudedKeyBag] || [],
            ...p12.getBags({
              bagType: forge.pki.oids.keyBag
            })[forge.pki.oids.keyBag] || []
          ];
          const certBags = p12.getBags({
            bagType: forge.pki.oids.certBag
          })[forge.pki.oids.certBag] || [];
          if (keyBags.length === 0 || certBags.length === 0) {
            throw new Error("missing identity material");
          }
          const keyBag = keyBags[0];
          const certBag = certBags[0];
          const keyPem = keyBag.key ? forge.pki.privateKeyToPem(keyBag.key) : derToPem("PRIVATE KEY", forgeAsn1Bytes(forge, keyBag.asn1));
          const certPem = certBag.cert ? forge.pki.certificateToPem(certBag.cert) : derToPem("CERTIFICATE", forgeAsn1Bytes(forge, certBag.asn1));
          const chainPem = certBags.map(
            (bag) => bag.cert ? forge.pki.certificateToPem(bag.cert) : derToPem("CERTIFICATE", forgeAsn1Bytes(forge, bag.asn1))
          ).join("");
          return new TlsIdentity(new SecureTlsIdentity(
            certPem,
            keyPem,
            "",
            "pkcs12",
            chainPem
          ));
        } catch (err) {
          if (/password|decrypt|mac|integrity/iu.test(String(err.message))) {
            throw new Error(`${label} failed to decrypt PKCS#12 data`);
          }
          throw new Error(
            `${label} expects PKCS#12 data with certificate and private key`
          );
        }
      }
      function tlsIdentityState(identity, label) {
        if (!(identity instanceof TlsIdentity)) {
          throw new Error(`TypeException: ${label} expects TlsIdentity`);
        }
        return identity.__secureTlsIdentity;
      }
      function tlsIdentityCertificate(identity) {
        const label = "TlsIdentity.certificate";
        const state = tlsIdentityState(identity, label);
        return parseX509Der(certificatePemBlocks(state.certPem, label)[0], label);
      }
      function tlsIdentityPrivateKey(identity) {
        const label = "TlsIdentity.private_key";
        if (hostName() === "browser") {
          throw new Error(`${label} is not supported on host browser`);
        }
        const state = tlsIdentityState(identity, label);
        try {
          return signingImportPrivate(
            state.keyPem,
            { format: "pem", password: state.password }
          );
        } catch (_err) {
          throw new Error(
            `${label} only supports Ed25519, ECDSA P-256, and ECDSA P-384 private keys`
          );
        }
      }
      function publicKeyVerify(publicKey, message, signature) {
        const label = "PublicKey.verify";
        if (hostName() === "browser") {
          syncBrowserSigningError(label, "PublicKey.verify_async");
        }
        const messageBytes = assertBinaryString(
          message,
          label,
          "BinaryString message"
        );
        const signatureBytes = assertBinaryString(
          signature,
          label,
          "BinaryString signature"
        );
        const meta = signingMeta(publicKey.__securePublicKey.algorithm);
        if (!meta) {
          throw new Error(`${label} expects a signing public key`);
        }
        if (meta.type === "ed25519" && signatureBytes.length !== 64) {
          return false;
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.verify !== "function") {
          nodeUnsupported(label);
        }
        return crypto.verify(
          meta.nodeHash ?? null,
          messageBytes,
          publicKey.__securePublicKey.key,
          signatureBytes
        );
      }
      async function publicKeyVerifyAsyncValue(publicKey, message, signature) {
        const label = "PublicKey.verify";
        const messageBytes = assertBinaryString(
          message,
          label,
          "BinaryString message"
        );
        const signatureBytes = assertBinaryString(
          signature,
          label,
          "BinaryString signature"
        );
        if (hostName() !== "browser") {
          return publicKeyVerify(publicKey, message, signature);
        }
        const subtle = subtleSigningCrypto();
        if (!subtle) {
          browserSigningUnsupported(`${label}_async`);
        }
        const meta = signingMeta(publicKey.__securePublicKey.algorithm);
        if (!meta) {
          throw new Error(`${label} expects a signing public key`);
        }
        let verifySignature = signatureBytes;
        if (meta.type === "ed25519") {
          if (signatureBytes.length !== 64) {
            return false;
          }
        } else {
          try {
            verifySignature = derToEcdsaRawSignature(
              signatureBytes,
              publicKey.__securePublicKey.algorithm
            );
          } catch (_err) {
            return false;
          }
        }
        try {
          return await subtle.verify(
            meta.type === "ed25519" ? { name: "Ed25519" } : { name: "ECDSA", hash: meta.webHash },
            publicKey.__securePublicKey.key,
            verifySignature,
            messageBytes
          );
        } catch (_err) {
          return false;
        }
      }
      function publicKeyExport(publicKey, optionsValue = null) {
        const label = "PublicKey.export";
        const options = optionalDict(optionsValue, label, "Dict options");
        const format = options.format == null ? "raw" : String(options.format);
        const secure = publicKey.__securePublicKey;
        if (format === "raw") {
          if (secure.rawPublic) {
            return new BinaryString(secure.rawPublic);
          }
          return new BinaryString(
            rawPublicFromJwk(secure.key.export({ format: "jwk" }), label)
          );
        }
        if (format === "pem") {
          if (secure.algorithm === "x25519") {
            throw new Error(
              `${label} only supports raw format for x25519 public keys`
            );
          }
          if (hostName() !== "browser") {
            return String(secure.key.export({
              format: "pem",
              type: "spki"
            }));
          }
          const meta = signingMeta(secure.algorithm);
          const der = meta.type === "ed25519" ? null : ecdsaSpkiDerFromRawPublic(secure.rawPublic, secure.algorithm);
          if (der == null) {
            throw new Error(`${label} PEM export is unavailable for this browser key`);
          }
          return derToPem("PUBLIC KEY", der);
        }
        throw new Error(`${label} only supports raw and pem formats`);
      }
      function keyAgreementGenerate(algorithm = "x25519") {
        const label = "KeyAgreement.generate";
        algorithm = keyAgreementAlgorithm(algorithm, label);
        if (hostName() === "browser") {
          syncBrowserKeyAgreementError(label, "KeyAgreement.generate_async");
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.generateKeyPairSync !== "function") {
          keyAgreementUnsupported(label);
        }
        const pair = crypto.generateKeyPairSync(algorithm);
        return new KeyAgreement(new SecureKeyAgreement(
          algorithm,
          pair.privateKey
        ));
      }
      async function browserKeyAgreementFromPair(algorithm, pair, label) {
        const privateJwk = await globalThis.crypto.subtle.exportKey(
          "jwk",
          pair.privateKey
        );
        const publicJwk = await globalThis.crypto.subtle.exportKey(
          "jwk",
          pair.publicKey
        );
        return new KeyAgreement(new SecureKeyAgreement(
          algorithm,
          pair.privateKey,
          pair.publicKey,
          rawPrivateFromJwk(privateJwk, label),
          rawPublicFromJwk(publicJwk, label)
        ));
      }
      async function keyAgreementGenerateAsyncValue(algorithm = "x25519") {
        const label = "KeyAgreement.generate";
        algorithm = keyAgreementAlgorithm(algorithm, label);
        if (hostName() !== "browser") {
          return keyAgreementGenerate(algorithm);
        }
        const subtle = subtleKeyAgreementCrypto();
        if (!subtle) {
          keyAgreementUnsupported(`${label}_async`);
        }
        try {
          const pair = await subtle.generateKey(
            { name: "X25519" },
            true,
            ["deriveBits"]
          );
          return await browserKeyAgreementFromPair(algorithm, pair, label);
        } catch (_err) {
          keyAgreementUnsupported(`${label}_async`);
        }
      }
      function keyAgreementImportPrivate(key, options = null) {
        const label = "KeyAgreement.import_private";
        if (hostName() === "browser") {
          syncBrowserKeyAgreementError(
            label,
            "KeyAgreement.import_private_async"
          );
        }
        const opts = optionalDict(options, label, "Dict options");
        keyAgreementAlgorithmOption(opts, label);
        const format = keyFormat(key, options, label);
        if (format !== "raw") {
          throw new Error(`${label} only supports raw format`);
        }
        return new KeyAgreement(new SecureKeyAgreement(
          "x25519",
          nodeX25519PrivateKeyFromRaw(key, label)
        ));
      }
      async function keyAgreementImportPrivateAsyncValue(key, options = null) {
        const label = "KeyAgreement.import_private";
        if (hostName() !== "browser") {
          return keyAgreementImportPrivate(key, options);
        }
        const subtle = subtleKeyAgreementCrypto();
        if (!subtle) {
          keyAgreementUnsupported(`${label}_async`);
        }
        const opts = optionalDict(options, label, "Dict options");
        keyAgreementAlgorithmOption(opts, label);
        const format = keyFormat(key, options, label);
        if (format !== "raw") {
          throw new Error(`${label} only supports raw format`);
        }
        const rawPrivate = x25519PrivateBytes(key, label);
        try {
          const privateKey = await subtle.importKey(
            "pkcs8",
            x25519Pkcs8DerFromRawPrivate(rawPrivate),
            { name: "X25519" },
            true,
            ["deriveBits"]
          );
          const privateJwk = await subtle.exportKey("jwk", privateKey);
          const rawPublic = rawPublicFromJwk(privateJwk, label);
          const publicKey = await subtle.importKey(
            "raw",
            rawPublic,
            { name: "X25519" },
            true,
            []
          );
          return new KeyAgreement(new SecureKeyAgreement(
            "x25519",
            privateKey,
            publicKey,
            rawPrivateFromJwk(privateJwk, label),
            rawPublic
          ));
        } catch (_err) {
          keyAgreementUnsupported(`${label}_async`);
        }
      }
      function keyAgreementImportPublic(key, options = null) {
        const label = "KeyAgreement.import_public";
        if (hostName() === "browser") {
          syncBrowserKeyAgreementError(label, "KeyAgreement.import_public_async");
        }
        const opts = optionalDict(options, label, "Dict options");
        keyAgreementAlgorithmOption(opts, label);
        const format = keyFormat(key, options, label);
        if (format !== "raw") {
          throw new Error(`${label} only supports raw format`);
        }
        return new PublicKey(new SecurePublicKey(
          "x25519",
          nodeX25519PublicKeyFromRaw(key, label)
        ));
      }
      async function keyAgreementImportPublicAsyncValue(key, options = null) {
        const label = "KeyAgreement.import_public";
        if (hostName() !== "browser") {
          return keyAgreementImportPublic(key, options);
        }
        const subtle = subtleKeyAgreementCrypto();
        if (!subtle) {
          keyAgreementUnsupported(`${label}_async`);
        }
        const opts = optionalDict(options, label, "Dict options");
        keyAgreementAlgorithmOption(opts, label);
        const format = keyFormat(key, options, label);
        if (format !== "raw") {
          throw new Error(`${label} only supports raw format`);
        }
        const rawPublic = x25519PublicBytes(key, label);
        try {
          const publicKey = await subtle.importKey(
            "raw",
            rawPublic,
            { name: "X25519" },
            true,
            []
          );
          return new PublicKey(new SecurePublicKey(
            "x25519",
            publicKey,
            rawPublic
          ));
        } catch (_err) {
          keyAgreementUnsupported(`${label}_async`);
        }
      }
      function keyAgreementPublicKey(keyAgreement) {
        const secure = keyAgreement.__secureKeyAgreement;
        if (hostName() === "browser") {
          if (secure.publicKey && secure.rawPublic) {
            return new PublicKey(new SecurePublicKey(
              secure.algorithm,
              secure.publicKey,
              secure.rawPublic
            ));
          }
          throw new Error(
            "KeyAgreement.public_key is unavailable for this browser key"
          );
        }
        const crypto = nodeCrypto();
        return new PublicKey(new SecurePublicKey(
          secure.algorithm,
          crypto.createPublicKey(secure.key)
        ));
      }
      function keyAgreementExportPrivate(keyAgreement, optionsValue = null) {
        const label = "KeyAgreement.export_private";
        const options = optionalDict(optionsValue, label, "Dict options");
        const format = options.format == null ? "raw" : String(options.format);
        if (format !== "raw") {
          throw new Error(`${label} only supports raw format`);
        }
        const secure = keyAgreement.__secureKeyAgreement;
        if (secure.rawPrivate) {
          return new BinaryString(secure.rawPrivate);
        }
        return new BinaryString(
          rawPrivateFromJwk(secure.key.export({ format: "jwk" }), label)
        );
      }
      function keyAgreementDerive(keyAgreement, publicKey) {
        const label = "KeyAgreement.derive";
        if (hostName() === "browser") {
          syncBrowserKeyAgreementError(label, "KeyAgreement.derive_async");
        }
        if (!(publicKey instanceof PublicKey) || publicKey.__securePublicKey.algorithm !== "x25519") {
          throw new Error(`${label} expects an x25519 public key`);
        }
        const crypto = nodeCrypto();
        if (!crypto || typeof crypto.diffieHellman !== "function") {
          keyAgreementUnsupported(label);
        }
        return new BinaryString(
          new Uint8Array(crypto.diffieHellman({
            privateKey: keyAgreement.__secureKeyAgreement.key,
            publicKey: publicKey.__securePublicKey.key
          }))
        );
      }
      async function keyAgreementDeriveAsyncValue(keyAgreement, publicKey) {
        const label = "KeyAgreement.derive";
        if (hostName() !== "browser") {
          return keyAgreementDerive(keyAgreement, publicKey);
        }
        if (!(publicKey instanceof PublicKey) || publicKey.__securePublicKey.algorithm !== "x25519") {
          throw new Error(`${label} expects an x25519 public key`);
        }
        const subtle = subtleKeyAgreementCrypto();
        if (!subtle) {
          keyAgreementUnsupported(`${label}_async`);
        }
        try {
          return new BinaryString(new Uint8Array(await subtle.deriveBits(
            { name: "X25519", public: publicKey.__securePublicKey.key },
            keyAgreement.__secureKeyAgreement.key,
            256
          )));
        } catch (_err) {
          keyAgreementUnsupported(`${label}_async`);
        }
      }
      var Secure = class {
        static capabilities() {
          return capabilities();
        }
        static has(area, name2) {
          return hasCapability(area, name2);
        }
        static require(area, name2) {
          return requireCapability(area, name2);
        }
      };
      var KeyDerivation = class {
        static hkdf_sha256(inputKeyMaterial, length, salt = null, info = null) {
          return hkdfSha256(inputKeyMaterial, length, salt, info);
        }
        static hkdf_sha256_async(inputKeyMaterial, length, salt = null, info = null) {
          const args = hkdfSha256Inputs(inputKeyMaterial, length, salt, info);
          if (subtleCrypto()) {
            return taskRuntime.Task.from(webCryptoHkdfSha256(args));
          }
          return taskRuntime.Task.resolved(
            new BinaryString(
              hkdfSha256Bytes(
                args.inputKeyMaterial,
                args.length,
                args.salt,
                args.info
              )
            )
          );
        }
      };
      var SecureRandom = class {
        static bytes(length) {
          if (arguments.length !== 1 || length == null) {
            throw new Error("SecureRandom.bytes expects a non-negative integer");
          }
          return new BinaryString(
            randomBytes(nonNegativeInteger(length, "SecureRandom.bytes"))
          );
        }
        static token(length = 32) {
          if (length == null) {
            length = 32;
          }
          return base64url(
            randomBytes(nonNegativeInteger(length, "SecureRandom.token"))
          );
        }
        static int(max) {
          return randomInt(positiveInteger(max, "SecureRandom.int"));
        }
      };
      var PasswordHash = class {
        static default_algorithm() {
          return DEFAULT_PASSWORD_HASH_ALGORITHM;
        }
        static hash(password, options = null) {
          return passwordHash(password, options);
        }
        static hash_async(password, options = null) {
          return taskRuntime.Task.from(passwordHashAsyncValue(password, options));
        }
        static verify(password, encodedHash) {
          return passwordHashVerify(password, encodedHash);
        }
        static verify_async(password, encodedHash) {
          return taskRuntime.Task.from(
            passwordHashVerifyAsyncValue(password, encodedHash)
          );
        }
        static needs_rehash(encodedHash, options = null) {
          return passwordHashNeedsRehash(encodedHash, options);
        }
        static derive_key(password, options = null) {
          return passwordHashDeriveKey(password, options);
        }
        static derive_key_async(password, options = null) {
          return taskRuntime.Task.from(
            passwordHashDeriveKeyAsyncValue(password, options)
          );
        }
      };
      var Cipher = class {
        static generate_key(algorithm = "aes-256-gcm") {
          return cipherGenerateKey(algorithm);
        }
        static encrypt(plaintext, key, options = null) {
          return cipherEncrypt(plaintext, key, options);
        }
        static decrypt(envelope, key, options = null) {
          return cipherDecrypt(envelope, key, options);
        }
        static encrypt_async(plaintext, key, options = null) {
          return cipherEncryptAsync(plaintext, key, options);
        }
        static decrypt_async(envelope, key, options = null) {
          return cipherDecryptAsync(envelope, key, options);
        }
      };
      var KeyAgreement = class {
        constructor(secureKeyAgreement) {
          if (!(secureKeyAgreement instanceof SecureKeyAgreement)) {
            throw new Error("KeyAgreement objects are created by std/secure");
          }
          this.__secureKeyAgreement = secureKeyAgreement;
        }
        static generate(algorithm = "x25519") {
          return keyAgreementGenerate(algorithm);
        }
        static generate_async(algorithm = "x25519") {
          return taskRuntime.Task.from(
            keyAgreementGenerateAsyncValue(algorithm)
          );
        }
        static import_private(key, options = null) {
          return keyAgreementImportPrivate(key, options);
        }
        static import_private_async(key, options = null) {
          return taskRuntime.Task.from(
            keyAgreementImportPrivateAsyncValue(key, options)
          );
        }
        static import_public(key, options = null) {
          return keyAgreementImportPublic(key, options);
        }
        static import_public_async(key, options = null) {
          return taskRuntime.Task.from(
            keyAgreementImportPublicAsyncValue(key, options)
          );
        }
        public_key() {
          return keyAgreementPublicKey(this);
        }
        derive(publicKey) {
          return keyAgreementDerive(this, publicKey);
        }
        derive_async(publicKey) {
          return taskRuntime.Task.from(
            keyAgreementDeriveAsyncValue(this, publicKey)
          );
        }
        export_private(options = null) {
          return keyAgreementExportPrivate(this, options);
        }
      };
      var SigningKey = class {
        constructor(secureSigningKey) {
          if (!(secureSigningKey instanceof SecureSigningKey)) {
            throw new Error("SigningKey objects are created by std/secure");
          }
          this.__secureSigningKey = secureSigningKey;
        }
        static generate(algorithm = "ed25519") {
          return signingGenerate(algorithm);
        }
        static generate_async(algorithm = "ed25519") {
          return taskRuntime.Task.from(signingGenerateAsyncValue(algorithm));
        }
        static import_private(key, options = null) {
          return signingImportPrivate(key, options);
        }
        static import_private_async(key, options = null) {
          return taskRuntime.Task.from(
            signingImportPrivateAsyncValue(key, options)
          );
        }
        static import_public(key, options = null) {
          return signingImportPublic(key, options);
        }
        static import_public_async(key, options = null) {
          return taskRuntime.Task.from(
            signingImportPublicAsyncValue(key, options)
          );
        }
        public_key() {
          return signingPublicKey(this);
        }
        sign(message) {
          return signingSign(this, message);
        }
        sign_async(message) {
          return taskRuntime.Task.from(signingSignAsyncValue(this, message));
        }
        export_private(options = null) {
          return signingExportPrivate(this, options);
        }
      };
      var Certificate = class {
        constructor(secureCertificate) {
          if (!(secureCertificate instanceof SecureCertificate)) {
            throw new Error("Certificate objects are created by std/secure");
          }
          this.__secureCertificate = secureCertificate;
        }
        static parse(input) {
          return certificateParse(input);
        }
        static parse_chain(input) {
          return certificateParseChain(input);
        }
        static verify_chain(chain, options = null) {
          return certificateVerifyChain(chain, options);
        }
        subject() {
          return certificateState(this, "Certificate.subject").subject;
        }
        issuer() {
          return certificateState(this, "Certificate.issuer").issuer;
        }
        serial_number() {
          return certificateState(this, "Certificate.serial_number").serial;
        }
        not_before() {
          return new Time(certificateState(this, "Certificate.not_before").notBefore);
        }
        not_after() {
          return new Time(certificateState(this, "Certificate.not_after").notAfter);
        }
        fingerprint(algorithm = "sha256") {
          return certificateFingerprint(this, algorithm);
        }
        to_der() {
          return new BinaryString(
            Uint8Array.from(certificateState(this, "Certificate.to_der").der)
          );
        }
        to_pem() {
          return certificateDerToPem(
            certificateState(this, "Certificate.to_pem").der
          );
        }
        public_key() {
          return certificatePublicKey(this);
        }
      };
      var PrivateKey = class {
      };
      var PublicKey = class {
        constructor(securePublicKey) {
          if (!(securePublicKey instanceof SecurePublicKey)) {
            throw new Error("PublicKey objects are created by std/secure");
          }
          this.__securePublicKey = securePublicKey;
        }
        verify(message, signature) {
          return publicKeyVerify(this, message, signature);
        }
        verify_async(message, signature) {
          return taskRuntime.Task.from(
            publicKeyVerifyAsyncValue(this, message, signature)
          );
        }
        export(options = null) {
          return publicKeyExport(this, options);
        }
      };
      var SealedBox = class {
      };
      var TlsIdentity = class {
        constructor(secureTlsIdentity) {
          if (!(secureTlsIdentity instanceof SecureTlsIdentity)) {
            throw new Error("TlsIdentity objects are created by std/secure");
          }
          this.__secureTlsIdentity = secureTlsIdentity;
        }
        static from_pem(certificatePem, privateKeyPem, password = null) {
          return tlsIdentityFromPem(certificatePem, privateKeyPem, password);
        }
        static from_pkcs12(bytes, password = null) {
          return tlsIdentityFromPkcs12(bytes, password);
        }
        certificate() {
          return tlsIdentityCertificate(this);
        }
        private_key() {
          return tlsIdentityPrivateKey(this);
        }
      };
      module.exports = {
        Secure,
        SecureRandom,
        PasswordHash,
        KeyDerivation,
        Cipher,
        KeyAgreement,
        SigningKey,
        Certificate,
        PrivateKey,
        PublicKey,
        SealedBox,
        TlsIdentity,
        __zuzu_set_runtime_policy: setRuntimePolicy
      };
    }
  });

  // modules/std/data/json.js
  var require_json = __commonJS({
    "modules/std/data/json.js"(exports2, module2) {
      "use strict";
      var { Pair, PairList, ZuzuBag } = require_collections();
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
      var utf8Encoder = new TextEncoder();
      function _isPlainObject(value) {
        return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof PairList) && !(value instanceof ZuzuBag) && Object.prototype.toString.call(value) !== "[object Set]";
      }
      function _isSet(value) {
        return Object.prototype.toString.call(value) === "[object Set]";
      }
      function _optionsObject(value) {
        if (value instanceof PairList) {
          const out = {};
          for (const [key, inner] of value.list) {
            out[String(key)] = inner;
          }
          return out;
        }
        if (_isPlainObject(value)) {
          return value;
        }
        return {};
      }
      function _decorateDict(value) {
        if (!_isPlainObject(value)) {
          return value;
        }
        const sortedKeys = () => Object.keys(value).sort();
        for (const [name2, fn2] of [
          ["length", function _length() {
            return Object.keys(this).length;
          }],
          ["count", function _count() {
            return Object.keys(this).length;
          }],
          ["empty", function _empty() {
            return Object.keys(this).length === 0 ? 1 : 0;
          }],
          ["keys", function _keys() {
            return new Set(sortedKeys());
          }],
          ["values", function _values() {
            return new ZuzuBag(sortedKeys().map((key) => this[key]));
          }],
          [
            "enumerate",
            function _enumerate() {
              return new ZuzuBag(
                sortedKeys().map(
                  (key) => new Pair({ pair: [key, this[key]] })
                )
              );
            }
          ],
          ["has", function _has(key) {
            return Object.prototype.hasOwnProperty.call(this, String(key)) ? 1 : 0;
          }],
          ["contains", function _contains(key) {
            return this.has(key);
          }],
          ["exists", function _exists(key) {
            return this.has(key);
          }],
          ["defined", function _defined(key) {
            return this.has(key) && this[String(key)] != null ? 1 : 0;
          }],
          ["get", function _get(key, fallback = null) {
            return this.has(key) ? this[String(key)] : fallback;
          }],
          ["add", function _add(key, inner) {
            this[String(key)] = inner;
            return this;
          }],
          ["set", function _set(key, inner) {
            return this.add(key, inner);
          }],
          [
            "kv",
            function _kv() {
              const out = [];
              for (const key of sortedKeys()) {
                out.push(key, this[key]);
              }
              return out;
            }
          ],
          ["sorted_keys", function _sorted_keys() {
            return sortedKeys();
          }],
          [
            "to_Array",
            function _to_array() {
              return sortedKeys().map(
                (key) => new Pair({ pair: [key, this[key]] })
              );
            }
          ],
          ["to_Iterator", function _to_iterator() {
            return sortedKeys()[Symbol.iterator]();
          }],
          [
            "for_each_key",
            function _for_each_key(fn3) {
              for (const key of sortedKeys()) {
                fn3(key);
              }
              return this;
            }
          ],
          [
            "for_each_value",
            function _for_each_value(fn3) {
              for (const key of sortedKeys()) {
                fn3(this[key]);
              }
              return this;
            }
          ],
          [
            "for_each_pair",
            function _for_each_pair(fn3) {
              for (const key of sortedKeys()) {
                fn3(new Pair({ pair: [key, this[key]] }));
              }
              return this;
            }
          ],
          [
            "remove",
            function _remove(key) {
              if (typeof key === "function") {
                for (const entryKey of Object.keys(this)) {
                  if (key(new Pair({ pair: [entryKey, this[entryKey]] }))) {
                    delete this[entryKey];
                  }
                }
                return this;
              }
              delete this[String(key)];
              return this;
            }
          ],
          [
            "clear",
            function _clear() {
              for (const key of Object.keys(this)) {
                delete this[key];
              }
              return this;
            }
          ]
        ]) {
          if (!Object.prototype.hasOwnProperty.call(value, name2)) {
            Object.defineProperty(value, name2, {
              value: fn2,
              enumerable: false,
              configurable: true,
              writable: true
            });
          }
        }
        for (const key of Object.keys(value)) {
          value[key] = _decorateValue(value[key]);
        }
        return value;
      }
      function _decoratePairList(value) {
        if (!(value instanceof PairList)) {
          return value;
        }
        for (const [name2, getter] of [
          ["keys", function _keys() {
            return value.list.map((pair) => pair[0]);
          }],
          ["values", function _values() {
            return value.list.map((pair) => pair[1]);
          }]
        ]) {
          if (!Object.prototype.hasOwnProperty.call(value, name2)) {
            Object.defineProperty(value, name2, {
              get: getter,
              enumerable: false,
              configurable: true
            });
          }
        }
        return value;
      }
      function _decorateArray(value) {
        if (!Array.isArray(value)) {
          return value;
        }
        for (let i = 0; i < value.length; i++) {
          value[i] = _decorateValue(value[i]);
        }
        return value;
      }
      function _decorateValue(value) {
        if (Array.isArray(value)) {
          return _decorateArray(value);
        }
        if (value instanceof PairList) {
          return _decoratePairList(value);
        }
        if (_isPlainObject(value)) {
          return _decorateDict(value);
        }
        return value;
      }
      function _sortCollectionValues(values) {
        return values.slice().sort((left, right) => String(left).localeCompare(String(right)));
      }
      function _collapsePairListEntries(entries) {
        const order = [];
        const values = /* @__PURE__ */ new Map();
        for (const [rawKey, entryValue] of entries) {
          const key = String(rawKey);
          if (!values.has(key)) {
            order.push(key);
          }
          values.set(key, entryValue);
        }
        return order.map((key) => [key, values.get(key)]);
      }
      function _objectEntriesForEncode(value, options) {
        if (value instanceof PairList) {
          const entries2 = value.list.map((pair) => [String(pair[0]), pair[1]]);
          if (options.pairlists) {
            return options.canonical ? entries2.slice().sort((left, right) => left[0].localeCompare(right[0])) : entries2;
          }
          value = Object.fromEntries(_collapsePairListEntries(entries2));
        }
        const entries = Object.keys(value).map((key) => [key, value[key]]);
        if (options.canonical) {
          entries.sort((left, right) => left[0].localeCompare(right[0]));
        }
        return entries;
      }
      function _encodeJson(value, options, depth = 0) {
        if (value == null) {
          return "null";
        }
        if (typeof value === "string") {
          return JSON.stringify(value);
        }
        if (typeof value === "number") {
          return Number.isFinite(value) ? String(value) : "null";
        }
        if (typeof value === "boolean") {
          return value ? "true" : "false";
        }
        if (Array.isArray(value)) {
          const items = value.map((item) => {
            const encoded = _encodeJson(item, options, depth + 1);
            return encoded === void 0 ? "null" : encoded;
          });
          if (!options.pretty) {
            return `[${items.join(",")}]`;
          }
          if (items.length === 0) {
            return "[]";
          }
          const indent = "	".repeat(depth);
          const inner = "	".repeat(depth + 1);
          return `[
${inner}${items.join(`,
${inner}`)}
${indent}]`;
        }
        if (value instanceof ZuzuBag) {
          return _encodeJson(_sortCollectionValues(value.items), options, depth);
        }
        if (_isSet(value)) {
          return _encodeJson(_sortCollectionValues([...value]), options, depth);
        }
        if (value instanceof PairList || _isPlainObject(value)) {
          const entries = _objectEntriesForEncode(value, options).map((pair) => [pair[0], _encodeJson(pair[1], options, depth + 1)]).filter((pair) => pair[1] !== void 0);
          if (!options.pretty) {
            return `{${entries.map((pair) => `${JSON.stringify(pair[0])}:${pair[1]}`).join(",")}}`;
          }
          if (entries.length === 0) {
            return "{}";
          }
          const indent = "	".repeat(depth);
          const inner = "	".repeat(depth + 1);
          return `{
${inner}${entries.map((pair) => `${JSON.stringify(pair[0])}: ${pair[1]}`).join(`,
${inner}`)}
${indent}}`;
        }
        if (typeof value.toJSON === "function") {
          return _encodeJson(value.toJSON(), options, depth);
        }
        return void 0;
      }
      function _parseJson(text, pairlists) {
        let index = 0;
        let source = "";
        if (text && text.bytes instanceof Uint8Array) {
          source = utf8Decoder.decode(text.bytes);
        } else {
          source = String(text ?? "");
        }
        function error(message) {
          throw new Error(`JSON.parse error at position ${index}: ${message}`);
        }
        function skipWhitespace() {
          while (index < source.length && /\s/u.test(source[index])) {
            index++;
          }
        }
        function parseString() {
          let out = "";
          index++;
          while (index < source.length) {
            const ch = source[index++];
            if (ch === '"') {
              return out;
            }
            if (ch !== "\\") {
              out += ch;
              continue;
            }
            if (index >= source.length) {
              error("unterminated escape sequence");
            }
            const esc = source[index++];
            if (esc === '"' || esc === "\\" || esc === "/") {
              out += esc;
              continue;
            }
            if (esc === "b") {
              out += "\b";
              continue;
            }
            if (esc === "f") {
              out += "\f";
              continue;
            }
            if (esc === "n") {
              out += "\n";
              continue;
            }
            if (esc === "r") {
              out += "\r";
              continue;
            }
            if (esc === "t") {
              out += "	";
              continue;
            }
            if (esc === "u") {
              const hex = source.slice(index, index + 4);
              if (!/^[0-9A-Fa-f]{4}$/u.test(hex)) {
                error("invalid unicode escape");
              }
              out += String.fromCharCode(Number.parseInt(hex, 16));
              index += 4;
              continue;
            }
            error(`invalid escape ${esc}`);
          }
          error("unterminated string literal");
        }
        function parseNumber() {
          const match = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u.exec(source.slice(index));
          if (!match) {
            error("invalid number");
          }
          index += match[0].length;
          return Number(match[0]);
        }
        function parseLiteral(literal, value2) {
          if (source.slice(index, index + literal.length) !== literal) {
            error(`expected ${literal}`);
          }
          index += literal.length;
          return value2;
        }
        function parseArray() {
          index++;
          skipWhitespace();
          const out = [];
          if (source[index] === "]") {
            index++;
            return out;
          }
          while (index < source.length) {
            out.push(parseValue());
            skipWhitespace();
            if (source[index] === "]") {
              index++;
              return out;
            }
            if (source[index] !== ",") {
              error("expected , or ]");
            }
            index++;
            skipWhitespace();
          }
          error("unterminated array");
        }
        function parseObject() {
          index++;
          skipWhitespace();
          const entries = [];
          if (source[index] === "}") {
            index++;
            return pairlists ? _decoratePairList(new PairList()) : _decorateDict({});
          }
          while (index < source.length) {
            if (source[index] !== '"') {
              error("expected object key string");
            }
            const key = parseString();
            skipWhitespace();
            if (source[index] !== ":") {
              error("expected :");
            }
            index++;
            skipWhitespace();
            entries.push([key, parseValue()]);
            skipWhitespace();
            if (source[index] === "}") {
              index++;
              if (pairlists) {
                return _decoratePairList(new PairList({ list: entries }));
              }
              const out = {};
              for (const [entryKey, entryValue] of entries) {
                Object.defineProperty(out, entryKey, {
                  value: entryValue,
                  enumerable: true,
                  configurable: true,
                  writable: true
                });
              }
              return _decorateDict(out);
            }
            if (source[index] !== ",") {
              error("expected , or }");
            }
            index++;
            skipWhitespace();
          }
          error("unterminated object");
        }
        function parseValue() {
          skipWhitespace();
          const ch = source[index];
          if (ch === '"') {
            return parseString();
          }
          if (ch === "[") {
            return parseArray();
          }
          if (ch === "{") {
            return parseObject();
          }
          if (ch === "t") {
            return parseLiteral("true", true);
          }
          if (ch === "f") {
            return parseLiteral("false", false);
          }
          if (ch === "n") {
            return parseLiteral("null", null);
          }
          return parseNumber();
        }
        const value = parseValue();
        skipWhitespace();
        if (index !== source.length) {
          error("unexpected trailing input");
        }
        return _decorateValue(value);
      }
      function _asPath(value, methodName) {
        if (value && typeof value.slurp === "function" && typeof value.spew === "function") {
          return value;
        }
        throw new Error(`TypeException: ${methodName} expects Path as first argument`);
      }
      var JSONCodec = class {
        constructor(options = {}, named = {}) {
          const merged = {
            ..._optionsObject(options),
            ..._optionsObject(named)
          };
          this.utf8 = Boolean(merged.utf8);
          this.pretty = Boolean(merged.pretty);
          this.canonical = Boolean(merged.canonical);
          this.pairlists = Boolean(merged.pairlists);
        }
        encode(value) {
          return _encodeJson(value, {
            canonical: this.canonical,
            pairlists: this.pairlists,
            pretty: this.pretty
          });
        }
        encode_binarystring(value) {
          return new BinaryString2(utf8Encoder.encode(this.encode(value)));
        }
        decode(text) {
          return _parseJson(text, this.pairlists);
        }
        decode_binarystring(raw) {
          if (!(raw instanceof BinaryString2)) {
            throw new Error("TypeException: JSON.decode_binarystring expects BinaryString");
          }
          return _parseJson(raw, this.pairlists);
        }
        load(pathObj) {
          const pathValue = _asPath(pathObj, "JSON.load");
          return this.decode_binarystring(pathValue.slurp());
        }
        dump(pathObj, value) {
          const pathValue = _asPath(pathObj, "JSON.dump");
          pathValue.spew(this.encode_binarystring(value));
          return pathObj;
        }
      };
      module2.exports = {
        JSON: JSONCodec
      };
    }
  });

  // node_modules/js-yaml/lib/common.js
  var require_common = __commonJS({
    "node_modules/js-yaml/lib/common.js"(exports2, module2) {
      "use strict";
      function isNothing(subject) {
        return typeof subject === "undefined" || subject === null;
      }
      function isObject(subject) {
        return typeof subject === "object" && subject !== null;
      }
      function toArray(sequence) {
        if (Array.isArray(sequence)) return sequence;
        else if (isNothing(sequence)) return [];
        return [sequence];
      }
      function extend(target, source) {
        var index, length, key, sourceKeys;
        if (source) {
          sourceKeys = Object.keys(source);
          for (index = 0, length = sourceKeys.length; index < length; index += 1) {
            key = sourceKeys[index];
            target[key] = source[key];
          }
        }
        return target;
      }
      function repeat(string, count) {
        var result = "", cycle;
        for (cycle = 0; cycle < count; cycle += 1) {
          result += string;
        }
        return result;
      }
      function isNegativeZero(number) {
        return number === 0 && Number.NEGATIVE_INFINITY === 1 / number;
      }
      module2.exports.isNothing = isNothing;
      module2.exports.isObject = isObject;
      module2.exports.toArray = toArray;
      module2.exports.repeat = repeat;
      module2.exports.isNegativeZero = isNegativeZero;
      module2.exports.extend = extend;
    }
  });

  // node_modules/js-yaml/lib/exception.js
  var require_exception = __commonJS({
    "node_modules/js-yaml/lib/exception.js"(exports2, module2) {
      "use strict";
      function formatError(exception, compact) {
        var where = "", message = exception.reason || "(unknown reason)";
        if (!exception.mark) return message;
        if (exception.mark.name) {
          where += 'in "' + exception.mark.name + '" ';
        }
        where += "(" + (exception.mark.line + 1) + ":" + (exception.mark.column + 1) + ")";
        if (!compact && exception.mark.snippet) {
          where += "\n\n" + exception.mark.snippet;
        }
        return message + " " + where;
      }
      function YAMLException(reason, mark) {
        Error.call(this);
        this.name = "YAMLException";
        this.reason = reason;
        this.mark = mark;
        this.message = formatError(this, false);
        if (Error.captureStackTrace) {
          Error.captureStackTrace(this, this.constructor);
        } else {
          this.stack = new Error().stack || "";
        }
      }
      YAMLException.prototype = Object.create(Error.prototype);
      YAMLException.prototype.constructor = YAMLException;
      YAMLException.prototype.toString = function toString(compact) {
        return this.name + ": " + formatError(this, compact);
      };
      module2.exports = YAMLException;
    }
  });

  // node_modules/js-yaml/lib/snippet.js
  var require_snippet = __commonJS({
    "node_modules/js-yaml/lib/snippet.js"(exports2, module2) {
      "use strict";
      var common = require_common();
      function getLine(buffer, lineStart, lineEnd, position, maxLineLength) {
        var head = "";
        var tail = "";
        var maxHalfLength = Math.floor(maxLineLength / 2) - 1;
        if (position - lineStart > maxHalfLength) {
          head = " ... ";
          lineStart = position - maxHalfLength + head.length;
        }
        if (lineEnd - position > maxHalfLength) {
          tail = " ...";
          lineEnd = position + maxHalfLength - tail.length;
        }
        return {
          str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, "\u2192") + tail,
          pos: position - lineStart + head.length
          // relative position
        };
      }
      function padStart(string, max) {
        return common.repeat(" ", max - string.length) + string;
      }
      function makeSnippet(mark, options) {
        options = Object.create(options || null);
        if (!mark.buffer) return null;
        if (!options.maxLength) options.maxLength = 79;
        if (typeof options.indent !== "number") options.indent = 1;
        if (typeof options.linesBefore !== "number") options.linesBefore = 3;
        if (typeof options.linesAfter !== "number") options.linesAfter = 2;
        var re = /\r?\n|\r|\0/g;
        var lineStarts = [0];
        var lineEnds = [];
        var match;
        var foundLineNo = -1;
        while (match = re.exec(mark.buffer)) {
          lineEnds.push(match.index);
          lineStarts.push(match.index + match[0].length);
          if (mark.position <= match.index && foundLineNo < 0) {
            foundLineNo = lineStarts.length - 2;
          }
        }
        if (foundLineNo < 0) foundLineNo = lineStarts.length - 1;
        var result = "", i, line;
        var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length;
        var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
        for (i = 1; i <= options.linesBefore; i++) {
          if (foundLineNo - i < 0) break;
          line = getLine(
            mark.buffer,
            lineStarts[foundLineNo - i],
            lineEnds[foundLineNo - i],
            mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),
            maxLineLength
          );
          result = common.repeat(" ", options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + " | " + line.str + "\n" + result;
        }
        line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength);
        result += common.repeat(" ", options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + " | " + line.str + "\n";
        result += common.repeat("-", options.indent + lineNoLength + 3 + line.pos) + "^\n";
        for (i = 1; i <= options.linesAfter; i++) {
          if (foundLineNo + i >= lineEnds.length) break;
          line = getLine(
            mark.buffer,
            lineStarts[foundLineNo + i],
            lineEnds[foundLineNo + i],
            mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),
            maxLineLength
          );
          result += common.repeat(" ", options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + " | " + line.str + "\n";
        }
        return result.replace(/\n$/, "");
      }
      module2.exports = makeSnippet;
    }
  });

  // node_modules/js-yaml/lib/type.js
  var require_type = __commonJS({
    "node_modules/js-yaml/lib/type.js"(exports2, module2) {
      "use strict";
      var YAMLException = require_exception();
      var TYPE_CONSTRUCTOR_OPTIONS = [
        "kind",
        "multi",
        "resolve",
        "construct",
        "instanceOf",
        "predicate",
        "represent",
        "representName",
        "defaultStyle",
        "styleAliases"
      ];
      var YAML_NODE_KINDS = [
        "scalar",
        "sequence",
        "mapping"
      ];
      function compileStyleAliases(map) {
        var result = {};
        if (map !== null) {
          Object.keys(map).forEach(function(style) {
            map[style].forEach(function(alias) {
              result[String(alias)] = style;
            });
          });
        }
        return result;
      }
      function Type(tag, options) {
        options = options || {};
        Object.keys(options).forEach(function(name2) {
          if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name2) === -1) {
            throw new YAMLException('Unknown option "' + name2 + '" is met in definition of "' + tag + '" YAML type.');
          }
        });
        this.options = options;
        this.tag = tag;
        this.kind = options["kind"] || null;
        this.resolve = options["resolve"] || function() {
          return true;
        };
        this.construct = options["construct"] || function(data) {
          return data;
        };
        this.instanceOf = options["instanceOf"] || null;
        this.predicate = options["predicate"] || null;
        this.represent = options["represent"] || null;
        this.representName = options["representName"] || null;
        this.defaultStyle = options["defaultStyle"] || null;
        this.multi = options["multi"] || false;
        this.styleAliases = compileStyleAliases(options["styleAliases"] || null);
        if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
          throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
        }
      }
      module2.exports = Type;
    }
  });

  // node_modules/js-yaml/lib/schema.js
  var require_schema = __commonJS({
    "node_modules/js-yaml/lib/schema.js"(exports2, module2) {
      "use strict";
      var YAMLException = require_exception();
      var Type = require_type();
      function compileList(schema, name2) {
        var result = [];
        schema[name2].forEach(function(currentType) {
          var newIndex = result.length;
          result.forEach(function(previousType, previousIndex) {
            if (previousType.tag === currentType.tag && previousType.kind === currentType.kind && previousType.multi === currentType.multi) {
              newIndex = previousIndex;
            }
          });
          result[newIndex] = currentType;
        });
        return result;
      }
      function compileMap() {
        var result = {
          scalar: {},
          sequence: {},
          mapping: {},
          fallback: {},
          multi: {
            scalar: [],
            sequence: [],
            mapping: [],
            fallback: []
          }
        }, index, length;
        function collectType(type) {
          if (type.multi) {
            result.multi[type.kind].push(type);
            result.multi["fallback"].push(type);
          } else {
            result[type.kind][type.tag] = result["fallback"][type.tag] = type;
          }
        }
        for (index = 0, length = arguments.length; index < length; index += 1) {
          arguments[index].forEach(collectType);
        }
        return result;
      }
      function Schema(definition) {
        return this.extend(definition);
      }
      Schema.prototype.extend = function extend(definition) {
        var implicit = [];
        var explicit = [];
        if (definition instanceof Type) {
          explicit.push(definition);
        } else if (Array.isArray(definition)) {
          explicit = explicit.concat(definition);
        } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
          if (definition.implicit) implicit = implicit.concat(definition.implicit);
          if (definition.explicit) explicit = explicit.concat(definition.explicit);
        } else {
          throw new YAMLException("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");
        }
        implicit.forEach(function(type) {
          if (!(type instanceof Type)) {
            throw new YAMLException("Specified list of YAML types (or a single Type object) contains a non-Type object.");
          }
          if (type.loadKind && type.loadKind !== "scalar") {
            throw new YAMLException("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");
          }
          if (type.multi) {
            throw new YAMLException("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.");
          }
        });
        explicit.forEach(function(type) {
          if (!(type instanceof Type)) {
            throw new YAMLException("Specified list of YAML types (or a single Type object) contains a non-Type object.");
          }
        });
        var result = Object.create(Schema.prototype);
        result.implicit = (this.implicit || []).concat(implicit);
        result.explicit = (this.explicit || []).concat(explicit);
        result.compiledImplicit = compileList(result, "implicit");
        result.compiledExplicit = compileList(result, "explicit");
        result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit);
        return result;
      };
      module2.exports = Schema;
    }
  });

  // node_modules/js-yaml/lib/type/str.js
  var require_str = __commonJS({
    "node_modules/js-yaml/lib/type/str.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      module2.exports = new Type("tag:yaml.org,2002:str", {
        kind: "scalar",
        construct: function(data) {
          return data !== null ? data : "";
        }
      });
    }
  });

  // node_modules/js-yaml/lib/type/seq.js
  var require_seq = __commonJS({
    "node_modules/js-yaml/lib/type/seq.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      module2.exports = new Type("tag:yaml.org,2002:seq", {
        kind: "sequence",
        construct: function(data) {
          return data !== null ? data : [];
        }
      });
    }
  });

  // node_modules/js-yaml/lib/type/map.js
  var require_map = __commonJS({
    "node_modules/js-yaml/lib/type/map.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      module2.exports = new Type("tag:yaml.org,2002:map", {
        kind: "mapping",
        construct: function(data) {
          return data !== null ? data : {};
        }
      });
    }
  });

  // node_modules/js-yaml/lib/schema/failsafe.js
  var require_failsafe = __commonJS({
    "node_modules/js-yaml/lib/schema/failsafe.js"(exports2, module2) {
      "use strict";
      var Schema = require_schema();
      module2.exports = new Schema({
        explicit: [
          require_str(),
          require_seq(),
          require_map()
        ]
      });
    }
  });

  // node_modules/js-yaml/lib/type/null.js
  var require_null = __commonJS({
    "node_modules/js-yaml/lib/type/null.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      function resolveYamlNull(data) {
        if (data === null) return true;
        var max = data.length;
        return max === 1 && data === "~" || max === 4 && (data === "null" || data === "Null" || data === "NULL");
      }
      function constructYamlNull() {
        return null;
      }
      function isNull(object) {
        return object === null;
      }
      module2.exports = new Type("tag:yaml.org,2002:null", {
        kind: "scalar",
        resolve: resolveYamlNull,
        construct: constructYamlNull,
        predicate: isNull,
        represent: {
          canonical: function() {
            return "~";
          },
          lowercase: function() {
            return "null";
          },
          uppercase: function() {
            return "NULL";
          },
          camelcase: function() {
            return "Null";
          },
          empty: function() {
            return "";
          }
        },
        defaultStyle: "lowercase"
      });
    }
  });

  // node_modules/js-yaml/lib/type/bool.js
  var require_bool = __commonJS({
    "node_modules/js-yaml/lib/type/bool.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      function resolveYamlBoolean(data) {
        if (data === null) return false;
        var max = data.length;
        return max === 4 && (data === "true" || data === "True" || data === "TRUE") || max === 5 && (data === "false" || data === "False" || data === "FALSE");
      }
      function constructYamlBoolean(data) {
        return data === "true" || data === "True" || data === "TRUE";
      }
      function isBoolean(object) {
        return Object.prototype.toString.call(object) === "[object Boolean]";
      }
      module2.exports = new Type("tag:yaml.org,2002:bool", {
        kind: "scalar",
        resolve: resolveYamlBoolean,
        construct: constructYamlBoolean,
        predicate: isBoolean,
        represent: {
          lowercase: function(object) {
            return object ? "true" : "false";
          },
          uppercase: function(object) {
            return object ? "TRUE" : "FALSE";
          },
          camelcase: function(object) {
            return object ? "True" : "False";
          }
        },
        defaultStyle: "lowercase"
      });
    }
  });

  // node_modules/js-yaml/lib/type/int.js
  var require_int = __commonJS({
    "node_modules/js-yaml/lib/type/int.js"(exports2, module2) {
      "use strict";
      var common = require_common();
      var Type = require_type();
      function isHexCode(c) {
        return 48 <= c && c <= 57 || 65 <= c && c <= 70 || 97 <= c && c <= 102;
      }
      function isOctCode(c) {
        return 48 <= c && c <= 55;
      }
      function isDecCode(c) {
        return 48 <= c && c <= 57;
      }
      function resolveYamlInteger(data) {
        if (data === null) return false;
        var max = data.length, index = 0, hasDigits = false, ch;
        if (!max) return false;
        ch = data[index];
        if (ch === "-" || ch === "+") {
          ch = data[++index];
        }
        if (ch === "0") {
          if (index + 1 === max) return true;
          ch = data[++index];
          if (ch === "b") {
            index++;
            for (; index < max; index++) {
              ch = data[index];
              if (ch === "_") continue;
              if (ch !== "0" && ch !== "1") return false;
              hasDigits = true;
            }
            return hasDigits && ch !== "_";
          }
          if (ch === "x") {
            index++;
            for (; index < max; index++) {
              ch = data[index];
              if (ch === "_") continue;
              if (!isHexCode(data.charCodeAt(index))) return false;
              hasDigits = true;
            }
            return hasDigits && ch !== "_";
          }
          if (ch === "o") {
            index++;
            for (; index < max; index++) {
              ch = data[index];
              if (ch === "_") continue;
              if (!isOctCode(data.charCodeAt(index))) return false;
              hasDigits = true;
            }
            return hasDigits && ch !== "_";
          }
        }
        if (ch === "_") return false;
        for (; index < max; index++) {
          ch = data[index];
          if (ch === "_") continue;
          if (!isDecCode(data.charCodeAt(index))) {
            return false;
          }
          hasDigits = true;
        }
        if (!hasDigits || ch === "_") return false;
        return true;
      }
      function constructYamlInteger(data) {
        var value = data, sign = 1, ch;
        if (value.indexOf("_") !== -1) {
          value = value.replace(/_/g, "");
        }
        ch = value[0];
        if (ch === "-" || ch === "+") {
          if (ch === "-") sign = -1;
          value = value.slice(1);
          ch = value[0];
        }
        if (value === "0") return 0;
        if (ch === "0") {
          if (value[1] === "b") return sign * parseInt(value.slice(2), 2);
          if (value[1] === "x") return sign * parseInt(value.slice(2), 16);
          if (value[1] === "o") return sign * parseInt(value.slice(2), 8);
        }
        return sign * parseInt(value, 10);
      }
      function isInteger(object) {
        return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 === 0 && !common.isNegativeZero(object));
      }
      module2.exports = new Type("tag:yaml.org,2002:int", {
        kind: "scalar",
        resolve: resolveYamlInteger,
        construct: constructYamlInteger,
        predicate: isInteger,
        represent: {
          binary: function(obj) {
            return obj >= 0 ? "0b" + obj.toString(2) : "-0b" + obj.toString(2).slice(1);
          },
          octal: function(obj) {
            return obj >= 0 ? "0o" + obj.toString(8) : "-0o" + obj.toString(8).slice(1);
          },
          decimal: function(obj) {
            return obj.toString(10);
          },
          /* eslint-disable max-len */
          hexadecimal: function(obj) {
            return obj >= 0 ? "0x" + obj.toString(16).toUpperCase() : "-0x" + obj.toString(16).toUpperCase().slice(1);
          }
        },
        defaultStyle: "decimal",
        styleAliases: {
          binary: [2, "bin"],
          octal: [8, "oct"],
          decimal: [10, "dec"],
          hexadecimal: [16, "hex"]
        }
      });
    }
  });

  // node_modules/js-yaml/lib/type/float.js
  var require_float = __commonJS({
    "node_modules/js-yaml/lib/type/float.js"(exports2, module2) {
      "use strict";
      var common = require_common();
      var Type = require_type();
      var YAML_FLOAT_PATTERN = new RegExp(
        // 2.5e4, 2.5 and integers
        "^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$"
      );
      function resolveYamlFloat(data) {
        if (data === null) return false;
        if (!YAML_FLOAT_PATTERN.test(data) || // Quick hack to not allow integers end with `_`
        // Probably should update regexp & check speed
        data[data.length - 1] === "_") {
          return false;
        }
        return true;
      }
      function constructYamlFloat(data) {
        var value, sign;
        value = data.replace(/_/g, "").toLowerCase();
        sign = value[0] === "-" ? -1 : 1;
        if ("+-".indexOf(value[0]) >= 0) {
          value = value.slice(1);
        }
        if (value === ".inf") {
          return sign === 1 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
        } else if (value === ".nan") {
          return NaN;
        }
        return sign * parseFloat(value, 10);
      }
      var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
      function representYamlFloat(object, style) {
        var res;
        if (isNaN(object)) {
          switch (style) {
            case "lowercase":
              return ".nan";
            case "uppercase":
              return ".NAN";
            case "camelcase":
              return ".NaN";
          }
        } else if (Number.POSITIVE_INFINITY === object) {
          switch (style) {
            case "lowercase":
              return ".inf";
            case "uppercase":
              return ".INF";
            case "camelcase":
              return ".Inf";
          }
        } else if (Number.NEGATIVE_INFINITY === object) {
          switch (style) {
            case "lowercase":
              return "-.inf";
            case "uppercase":
              return "-.INF";
            case "camelcase":
              return "-.Inf";
          }
        } else if (common.isNegativeZero(object)) {
          return "-0.0";
        }
        res = object.toString(10);
        return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace("e", ".e") : res;
      }
      function isFloat(object) {
        return Object.prototype.toString.call(object) === "[object Number]" && (object % 1 !== 0 || common.isNegativeZero(object));
      }
      module2.exports = new Type("tag:yaml.org,2002:float", {
        kind: "scalar",
        resolve: resolveYamlFloat,
        construct: constructYamlFloat,
        predicate: isFloat,
        represent: representYamlFloat,
        defaultStyle: "lowercase"
      });
    }
  });

  // node_modules/js-yaml/lib/schema/json.js
  var require_json2 = __commonJS({
    "node_modules/js-yaml/lib/schema/json.js"(exports2, module2) {
      "use strict";
      module2.exports = require_failsafe().extend({
        implicit: [
          require_null(),
          require_bool(),
          require_int(),
          require_float()
        ]
      });
    }
  });

  // node_modules/js-yaml/lib/schema/core.js
  var require_core = __commonJS({
    "node_modules/js-yaml/lib/schema/core.js"(exports2, module2) {
      "use strict";
      module2.exports = require_json2();
    }
  });

  // node_modules/js-yaml/lib/type/timestamp.js
  var require_timestamp = __commonJS({
    "node_modules/js-yaml/lib/type/timestamp.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      var YAML_DATE_REGEXP = new RegExp(
        "^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"
      );
      var YAML_TIMESTAMP_REGEXP = new RegExp(
        "^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$"
      );
      function resolveYamlTimestamp(data) {
        if (data === null) return false;
        if (YAML_DATE_REGEXP.exec(data) !== null) return true;
        if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
        return false;
      }
      function constructYamlTimestamp(data) {
        var match, year, month, day, hour, minute, second, fraction = 0, delta = null, tz_hour, tz_minute, date;
        match = YAML_DATE_REGEXP.exec(data);
        if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
        if (match === null) throw new Error("Date resolve error");
        year = +match[1];
        month = +match[2] - 1;
        day = +match[3];
        if (!match[4]) {
          return new Date(Date.UTC(year, month, day));
        }
        hour = +match[4];
        minute = +match[5];
        second = +match[6];
        if (match[7]) {
          fraction = match[7].slice(0, 3);
          while (fraction.length < 3) {
            fraction += "0";
          }
          fraction = +fraction;
        }
        if (match[9]) {
          tz_hour = +match[10];
          tz_minute = +(match[11] || 0);
          delta = (tz_hour * 60 + tz_minute) * 6e4;
          if (match[9] === "-") delta = -delta;
        }
        date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
        if (delta) date.setTime(date.getTime() - delta);
        return date;
      }
      function representYamlTimestamp(object) {
        return object.toISOString();
      }
      module2.exports = new Type("tag:yaml.org,2002:timestamp", {
        kind: "scalar",
        resolve: resolveYamlTimestamp,
        construct: constructYamlTimestamp,
        instanceOf: Date,
        represent: representYamlTimestamp
      });
    }
  });

  // node_modules/js-yaml/lib/type/merge.js
  var require_merge = __commonJS({
    "node_modules/js-yaml/lib/type/merge.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      function resolveYamlMerge(data) {
        return data === "<<" || data === null;
      }
      module2.exports = new Type("tag:yaml.org,2002:merge", {
        kind: "scalar",
        resolve: resolveYamlMerge
      });
    }
  });

  // node_modules/js-yaml/lib/type/binary.js
  var require_binary = __commonJS({
    "node_modules/js-yaml/lib/type/binary.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      var BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";
      function resolveYamlBinary(data) {
        if (data === null) return false;
        var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
        for (idx = 0; idx < max; idx++) {
          code = map.indexOf(data.charAt(idx));
          if (code > 64) continue;
          if (code < 0) return false;
          bitlen += 6;
        }
        return bitlen % 8 === 0;
      }
      function constructYamlBinary(data) {
        var idx, tailbits, input = data.replace(/[\r\n=]/g, ""), max = input.length, map = BASE64_MAP, bits = 0, result = [];
        for (idx = 0; idx < max; idx++) {
          if (idx % 4 === 0 && idx) {
            result.push(bits >> 16 & 255);
            result.push(bits >> 8 & 255);
            result.push(bits & 255);
          }
          bits = bits << 6 | map.indexOf(input.charAt(idx));
        }
        tailbits = max % 4 * 6;
        if (tailbits === 0) {
          result.push(bits >> 16 & 255);
          result.push(bits >> 8 & 255);
          result.push(bits & 255);
        } else if (tailbits === 18) {
          result.push(bits >> 10 & 255);
          result.push(bits >> 2 & 255);
        } else if (tailbits === 12) {
          result.push(bits >> 4 & 255);
        }
        return new Uint8Array(result);
      }
      function representYamlBinary(object) {
        var result = "", bits = 0, idx, tail, max = object.length, map = BASE64_MAP;
        for (idx = 0; idx < max; idx++) {
          if (idx % 3 === 0 && idx) {
            result += map[bits >> 18 & 63];
            result += map[bits >> 12 & 63];
            result += map[bits >> 6 & 63];
            result += map[bits & 63];
          }
          bits = (bits << 8) + object[idx];
        }
        tail = max % 3;
        if (tail === 0) {
          result += map[bits >> 18 & 63];
          result += map[bits >> 12 & 63];
          result += map[bits >> 6 & 63];
          result += map[bits & 63];
        } else if (tail === 2) {
          result += map[bits >> 10 & 63];
          result += map[bits >> 4 & 63];
          result += map[bits << 2 & 63];
          result += map[64];
        } else if (tail === 1) {
          result += map[bits >> 2 & 63];
          result += map[bits << 4 & 63];
          result += map[64];
          result += map[64];
        }
        return result;
      }
      function isBinary(obj) {
        return Object.prototype.toString.call(obj) === "[object Uint8Array]";
      }
      module2.exports = new Type("tag:yaml.org,2002:binary", {
        kind: "scalar",
        resolve: resolveYamlBinary,
        construct: constructYamlBinary,
        predicate: isBinary,
        represent: representYamlBinary
      });
    }
  });

  // node_modules/js-yaml/lib/type/omap.js
  var require_omap = __commonJS({
    "node_modules/js-yaml/lib/type/omap.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      var _hasOwnProperty = Object.prototype.hasOwnProperty;
      var _toString = Object.prototype.toString;
      function resolveYamlOmap(data) {
        if (data === null) return true;
        var objectKeys = [], index, length, pair, pairKey, pairHasKey, object = data;
        for (index = 0, length = object.length; index < length; index += 1) {
          pair = object[index];
          pairHasKey = false;
          if (_toString.call(pair) !== "[object Object]") return false;
          for (pairKey in pair) {
            if (_hasOwnProperty.call(pair, pairKey)) {
              if (!pairHasKey) pairHasKey = true;
              else return false;
            }
          }
          if (!pairHasKey) return false;
          if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
          else return false;
        }
        return true;
      }
      function constructYamlOmap(data) {
        return data !== null ? data : [];
      }
      module2.exports = new Type("tag:yaml.org,2002:omap", {
        kind: "sequence",
        resolve: resolveYamlOmap,
        construct: constructYamlOmap
      });
    }
  });

  // node_modules/js-yaml/lib/type/pairs.js
  var require_pairs = __commonJS({
    "node_modules/js-yaml/lib/type/pairs.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      var _toString = Object.prototype.toString;
      function resolveYamlPairs(data) {
        if (data === null) return true;
        var index, length, pair, keys, result, object = data;
        result = new Array(object.length);
        for (index = 0, length = object.length; index < length; index += 1) {
          pair = object[index];
          if (_toString.call(pair) !== "[object Object]") return false;
          keys = Object.keys(pair);
          if (keys.length !== 1) return false;
          result[index] = [keys[0], pair[keys[0]]];
        }
        return true;
      }
      function constructYamlPairs(data) {
        if (data === null) return [];
        var index, length, pair, keys, result, object = data;
        result = new Array(object.length);
        for (index = 0, length = object.length; index < length; index += 1) {
          pair = object[index];
          keys = Object.keys(pair);
          result[index] = [keys[0], pair[keys[0]]];
        }
        return result;
      }
      module2.exports = new Type("tag:yaml.org,2002:pairs", {
        kind: "sequence",
        resolve: resolveYamlPairs,
        construct: constructYamlPairs
      });
    }
  });

  // node_modules/js-yaml/lib/type/set.js
  var require_set = __commonJS({
    "node_modules/js-yaml/lib/type/set.js"(exports2, module2) {
      "use strict";
      var Type = require_type();
      var _hasOwnProperty = Object.prototype.hasOwnProperty;
      function resolveYamlSet(data) {
        if (data === null) return true;
        var key, object = data;
        for (key in object) {
          if (_hasOwnProperty.call(object, key)) {
            if (object[key] !== null) return false;
          }
        }
        return true;
      }
      function constructYamlSet(data) {
        return data !== null ? data : {};
      }
      module2.exports = new Type("tag:yaml.org,2002:set", {
        kind: "mapping",
        resolve: resolveYamlSet,
        construct: constructYamlSet
      });
    }
  });

  // node_modules/js-yaml/lib/schema/default.js
  var require_default = __commonJS({
    "node_modules/js-yaml/lib/schema/default.js"(exports2, module2) {
      "use strict";
      module2.exports = require_core().extend({
        implicit: [
          require_timestamp(),
          require_merge()
        ],
        explicit: [
          require_binary(),
          require_omap(),
          require_pairs(),
          require_set()
        ]
      });
    }
  });

  // node_modules/js-yaml/lib/loader.js
  var require_loader = __commonJS({
    "node_modules/js-yaml/lib/loader.js"(exports2, module2) {
      "use strict";
      var common = require_common();
      var YAMLException = require_exception();
      var makeSnippet = require_snippet();
      var DEFAULT_SCHEMA = require_default();
      var _hasOwnProperty = Object.prototype.hasOwnProperty;
      var CONTEXT_FLOW_IN = 1;
      var CONTEXT_FLOW_OUT = 2;
      var CONTEXT_BLOCK_IN = 3;
      var CONTEXT_BLOCK_OUT = 4;
      var CHOMPING_CLIP = 1;
      var CHOMPING_STRIP = 2;
      var CHOMPING_KEEP = 3;
      var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/;
      var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/;
      var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
      var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
      var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
      function _class(obj) {
        return Object.prototype.toString.call(obj);
      }
      function is_EOL(c) {
        return c === 10 || c === 13;
      }
      function is_WHITE_SPACE(c) {
        return c === 9 || c === 32;
      }
      function is_WS_OR_EOL(c) {
        return c === 9 || c === 32 || c === 10 || c === 13;
      }
      function is_FLOW_INDICATOR(c) {
        return c === 44 || c === 91 || c === 93 || c === 123 || c === 125;
      }
      function fromHexCode(c) {
        var lc;
        if (48 <= c && c <= 57) {
          return c - 48;
        }
        lc = c | 32;
        if (97 <= lc && lc <= 102) {
          return lc - 97 + 10;
        }
        return -1;
      }
      function escapedHexLen(c) {
        if (c === 120) {
          return 2;
        }
        if (c === 117) {
          return 4;
        }
        if (c === 85) {
          return 8;
        }
        return 0;
      }
      function fromDecimalCode(c) {
        if (48 <= c && c <= 57) {
          return c - 48;
        }
        return -1;
      }
      function simpleEscapeSequence(c) {
        return c === 48 ? "\0" : c === 97 ? "\x07" : c === 98 ? "\b" : c === 116 ? "	" : c === 9 ? "	" : c === 110 ? "\n" : c === 118 ? "\v" : c === 102 ? "\f" : c === 114 ? "\r" : c === 101 ? "\x1B" : c === 32 ? " " : c === 34 ? '"' : c === 47 ? "/" : c === 92 ? "\\" : c === 78 ? "\x85" : c === 95 ? "\xA0" : c === 76 ? "\u2028" : c === 80 ? "\u2029" : "";
      }
      function charFromCodepoint(c) {
        if (c <= 65535) {
          return String.fromCharCode(c);
        }
        return String.fromCharCode(
          (c - 65536 >> 10) + 55296,
          (c - 65536 & 1023) + 56320
        );
      }
      function setProperty(object, key, value) {
        if (key === "__proto__") {
          Object.defineProperty(object, key, {
            configurable: true,
            enumerable: true,
            writable: true,
            value
          });
        } else {
          object[key] = value;
        }
      }
      var simpleEscapeCheck = new Array(256);
      var simpleEscapeMap = new Array(256);
      for (i = 0; i < 256; i++) {
        simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0;
        simpleEscapeMap[i] = simpleEscapeSequence(i);
      }
      var i;
      function State(input, options) {
        this.input = input;
        this.filename = options["filename"] || null;
        this.schema = options["schema"] || DEFAULT_SCHEMA;
        this.onWarning = options["onWarning"] || null;
        this.legacy = options["legacy"] || false;
        this.json = options["json"] || false;
        this.listener = options["listener"] || null;
        this.implicitTypes = this.schema.compiledImplicit;
        this.typeMap = this.schema.compiledTypeMap;
        this.length = input.length;
        this.position = 0;
        this.line = 0;
        this.lineStart = 0;
        this.lineIndent = 0;
        this.firstTabInLine = -1;
        this.documents = [];
      }
      function generateError(state, message) {
        var mark = {
          name: state.filename,
          buffer: state.input.slice(0, -1),
          // omit trailing \0
          position: state.position,
          line: state.line,
          column: state.position - state.lineStart
        };
        mark.snippet = makeSnippet(mark);
        return new YAMLException(message, mark);
      }
      function throwError(state, message) {
        throw generateError(state, message);
      }
      function throwWarning(state, message) {
        if (state.onWarning) {
          state.onWarning.call(null, generateError(state, message));
        }
      }
      var directiveHandlers = {
        YAML: function handleYamlDirective(state, name2, args) {
          var match, major, minor;
          if (state.version !== null) {
            throwError(state, "duplication of %YAML directive");
          }
          if (args.length !== 1) {
            throwError(state, "YAML directive accepts exactly one argument");
          }
          match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]);
          if (match === null) {
            throwError(state, "ill-formed argument of the YAML directive");
          }
          major = parseInt(match[1], 10);
          minor = parseInt(match[2], 10);
          if (major !== 1) {
            throwError(state, "unacceptable YAML version of the document");
          }
          state.version = args[0];
          state.checkLineBreaks = minor < 2;
          if (minor !== 1 && minor !== 2) {
            throwWarning(state, "unsupported YAML version of the document");
          }
        },
        TAG: function handleTagDirective(state, name2, args) {
          var handle, prefix;
          if (args.length !== 2) {
            throwError(state, "TAG directive accepts exactly two arguments");
          }
          handle = args[0];
          prefix = args[1];
          if (!PATTERN_TAG_HANDLE.test(handle)) {
            throwError(state, "ill-formed tag handle (first argument) of the TAG directive");
          }
          if (_hasOwnProperty.call(state.tagMap, handle)) {
            throwError(state, 'there is a previously declared suffix for "' + handle + '" tag handle');
          }
          if (!PATTERN_TAG_URI.test(prefix)) {
            throwError(state, "ill-formed tag prefix (second argument) of the TAG directive");
          }
          try {
            prefix = decodeURIComponent(prefix);
          } catch (err) {
            throwError(state, "tag prefix is malformed: " + prefix);
          }
          state.tagMap[handle] = prefix;
        }
      };
      function captureSegment(state, start, end, checkJson) {
        var _position, _length, _character, _result;
        if (start < end) {
          _result = state.input.slice(start, end);
          if (checkJson) {
            for (_position = 0, _length = _result.length; _position < _length; _position += 1) {
              _character = _result.charCodeAt(_position);
              if (!(_character === 9 || 32 <= _character && _character <= 1114111)) {
                throwError(state, "expected valid JSON character");
              }
            }
          } else if (PATTERN_NON_PRINTABLE.test(_result)) {
            throwError(state, "the stream contains non-printable characters");
          }
          state.result += _result;
        }
      }
      function mergeMappings(state, destination, source, overridableKeys) {
        var sourceKeys, key, index, quantity;
        if (!common.isObject(source)) {
          throwError(state, "cannot merge mappings; the provided source object is unacceptable");
        }
        sourceKeys = Object.keys(source);
        for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) {
          key = sourceKeys[index];
          if (!_hasOwnProperty.call(destination, key)) {
            setProperty(destination, key, source[key]);
            overridableKeys[key] = true;
          }
        }
      }
      function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, startLine, startLineStart, startPos) {
        var index, quantity;
        if (Array.isArray(keyNode)) {
          keyNode = Array.prototype.slice.call(keyNode);
          for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {
            if (Array.isArray(keyNode[index])) {
              throwError(state, "nested arrays are not supported inside keys");
            }
            if (typeof keyNode === "object" && _class(keyNode[index]) === "[object Object]") {
              keyNode[index] = "[object Object]";
            }
          }
        }
        if (typeof keyNode === "object" && _class(keyNode) === "[object Object]") {
          keyNode = "[object Object]";
        }
        keyNode = String(keyNode);
        if (_result === null) {
          _result = {};
        }
        if (keyTag === "tag:yaml.org,2002:merge") {
          if (Array.isArray(valueNode)) {
            for (index = 0, quantity = valueNode.length; index < quantity; index += 1) {
              mergeMappings(state, _result, valueNode[index], overridableKeys);
            }
          } else {
            mergeMappings(state, _result, valueNode, overridableKeys);
          }
        } else {
          if (!state.json && !_hasOwnProperty.call(overridableKeys, keyNode) && _hasOwnProperty.call(_result, keyNode)) {
            state.line = startLine || state.line;
            state.lineStart = startLineStart || state.lineStart;
            state.position = startPos || state.position;
            throwError(state, "duplicated mapping key");
          }
          setProperty(_result, keyNode, valueNode);
          delete overridableKeys[keyNode];
        }
        return _result;
      }
      function readLineBreak(state) {
        var ch;
        ch = state.input.charCodeAt(state.position);
        if (ch === 10) {
          state.position++;
        } else if (ch === 13) {
          state.position++;
          if (state.input.charCodeAt(state.position) === 10) {
            state.position++;
          }
        } else {
          throwError(state, "a line break is expected");
        }
        state.line += 1;
        state.lineStart = state.position;
        state.firstTabInLine = -1;
      }
      function skipSeparationSpace(state, allowComments, checkIndent) {
        var lineBreaks = 0, ch = state.input.charCodeAt(state.position);
        while (ch !== 0) {
          while (is_WHITE_SPACE(ch)) {
            if (ch === 9 && state.firstTabInLine === -1) {
              state.firstTabInLine = state.position;
            }
            ch = state.input.charCodeAt(++state.position);
          }
          if (allowComments && ch === 35) {
            do {
              ch = state.input.charCodeAt(++state.position);
            } while (ch !== 10 && ch !== 13 && ch !== 0);
          }
          if (is_EOL(ch)) {
            readLineBreak(state);
            ch = state.input.charCodeAt(state.position);
            lineBreaks++;
            state.lineIndent = 0;
            while (ch === 32) {
              state.lineIndent++;
              ch = state.input.charCodeAt(++state.position);
            }
          } else {
            break;
          }
        }
        if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) {
          throwWarning(state, "deficient indentation");
        }
        return lineBreaks;
      }
      function testDocumentSeparator(state) {
        var _position = state.position, ch;
        ch = state.input.charCodeAt(_position);
        if ((ch === 45 || ch === 46) && ch === state.input.charCodeAt(_position + 1) && ch === state.input.charCodeAt(_position + 2)) {
          _position += 3;
          ch = state.input.charCodeAt(_position);
          if (ch === 0 || is_WS_OR_EOL(ch)) {
            return true;
          }
        }
        return false;
      }
      function writeFoldedLines(state, count) {
        if (count === 1) {
          state.result += " ";
        } else if (count > 1) {
          state.result += common.repeat("\n", count - 1);
        }
      }
      function readPlainScalar(state, nodeIndent, withinFlowCollection) {
        var preceding, following, captureStart, captureEnd, hasPendingContent, _line, _lineStart, _lineIndent, _kind = state.kind, _result = state.result, ch;
        ch = state.input.charCodeAt(state.position);
        if (is_WS_OR_EOL(ch) || is_FLOW_INDICATOR(ch) || ch === 35 || ch === 38 || ch === 42 || ch === 33 || ch === 124 || ch === 62 || ch === 39 || ch === 34 || ch === 37 || ch === 64 || ch === 96) {
          return false;
        }
        if (ch === 63 || ch === 45) {
          following = state.input.charCodeAt(state.position + 1);
          if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) {
            return false;
          }
        }
        state.kind = "scalar";
        state.result = "";
        captureStart = captureEnd = state.position;
        hasPendingContent = false;
        while (ch !== 0) {
          if (ch === 58) {
            following = state.input.charCodeAt(state.position + 1);
            if (is_WS_OR_EOL(following) || withinFlowCollection && is_FLOW_INDICATOR(following)) {
              break;
            }
          } else if (ch === 35) {
            preceding = state.input.charCodeAt(state.position - 1);
            if (is_WS_OR_EOL(preceding)) {
              break;
            }
          } else if (state.position === state.lineStart && testDocumentSeparator(state) || withinFlowCollection && is_FLOW_INDICATOR(ch)) {
            break;
          } else if (is_EOL(ch)) {
            _line = state.line;
            _lineStart = state.lineStart;
            _lineIndent = state.lineIndent;
            skipSeparationSpace(state, false, -1);
            if (state.lineIndent >= nodeIndent) {
              hasPendingContent = true;
              ch = state.input.charCodeAt(state.position);
              continue;
            } else {
              state.position = captureEnd;
              state.line = _line;
              state.lineStart = _lineStart;
              state.lineIndent = _lineIndent;
              break;
            }
          }
          if (hasPendingContent) {
            captureSegment(state, captureStart, captureEnd, false);
            writeFoldedLines(state, state.line - _line);
            captureStart = captureEnd = state.position;
            hasPendingContent = false;
          }
          if (!is_WHITE_SPACE(ch)) {
            captureEnd = state.position + 1;
          }
          ch = state.input.charCodeAt(++state.position);
        }
        captureSegment(state, captureStart, captureEnd, false);
        if (state.result) {
          return true;
        }
        state.kind = _kind;
        state.result = _result;
        return false;
      }
      function readSingleQuotedScalar(state, nodeIndent) {
        var ch, captureStart, captureEnd;
        ch = state.input.charCodeAt(state.position);
        if (ch !== 39) {
          return false;
        }
        state.kind = "scalar";
        state.result = "";
        state.position++;
        captureStart = captureEnd = state.position;
        while ((ch = state.input.charCodeAt(state.position)) !== 0) {
          if (ch === 39) {
            captureSegment(state, captureStart, state.position, true);
            ch = state.input.charCodeAt(++state.position);
            if (ch === 39) {
              captureStart = state.position;
              state.position++;
              captureEnd = state.position;
            } else {
              return true;
            }
          } else if (is_EOL(ch)) {
            captureSegment(state, captureStart, captureEnd, true);
            writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
            captureStart = captureEnd = state.position;
          } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
            throwError(state, "unexpected end of the document within a single quoted scalar");
          } else {
            state.position++;
            captureEnd = state.position;
          }
        }
        throwError(state, "unexpected end of the stream within a single quoted scalar");
      }
      function readDoubleQuotedScalar(state, nodeIndent) {
        var captureStart, captureEnd, hexLength, hexResult, tmp, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch !== 34) {
          return false;
        }
        state.kind = "scalar";
        state.result = "";
        state.position++;
        captureStart = captureEnd = state.position;
        while ((ch = state.input.charCodeAt(state.position)) !== 0) {
          if (ch === 34) {
            captureSegment(state, captureStart, state.position, true);
            state.position++;
            return true;
          } else if (ch === 92) {
            captureSegment(state, captureStart, state.position, true);
            ch = state.input.charCodeAt(++state.position);
            if (is_EOL(ch)) {
              skipSeparationSpace(state, false, nodeIndent);
            } else if (ch < 256 && simpleEscapeCheck[ch]) {
              state.result += simpleEscapeMap[ch];
              state.position++;
            } else if ((tmp = escapedHexLen(ch)) > 0) {
              hexLength = tmp;
              hexResult = 0;
              for (; hexLength > 0; hexLength--) {
                ch = state.input.charCodeAt(++state.position);
                if ((tmp = fromHexCode(ch)) >= 0) {
                  hexResult = (hexResult << 4) + tmp;
                } else {
                  throwError(state, "expected hexadecimal character");
                }
              }
              state.result += charFromCodepoint(hexResult);
              state.position++;
            } else {
              throwError(state, "unknown escape sequence");
            }
            captureStart = captureEnd = state.position;
          } else if (is_EOL(ch)) {
            captureSegment(state, captureStart, captureEnd, true);
            writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent));
            captureStart = captureEnd = state.position;
          } else if (state.position === state.lineStart && testDocumentSeparator(state)) {
            throwError(state, "unexpected end of the document within a double quoted scalar");
          } else {
            state.position++;
            captureEnd = state.position;
          }
        }
        throwError(state, "unexpected end of the stream within a double quoted scalar");
      }
      function readFlowCollection(state, nodeIndent) {
        var readNext = true, _line, _lineStart, _pos, _tag = state.tag, _result, _anchor = state.anchor, following, terminator, isPair, isExplicitPair, isMapping, overridableKeys = /* @__PURE__ */ Object.create(null), keyNode, keyTag, valueNode, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch === 91) {
          terminator = 93;
          isMapping = false;
          _result = [];
        } else if (ch === 123) {
          terminator = 125;
          isMapping = true;
          _result = {};
        } else {
          return false;
        }
        if (state.anchor !== null) {
          state.anchorMap[state.anchor] = _result;
        }
        ch = state.input.charCodeAt(++state.position);
        while (ch !== 0) {
          skipSeparationSpace(state, true, nodeIndent);
          ch = state.input.charCodeAt(state.position);
          if (ch === terminator) {
            state.position++;
            state.tag = _tag;
            state.anchor = _anchor;
            state.kind = isMapping ? "mapping" : "sequence";
            state.result = _result;
            return true;
          } else if (!readNext) {
            throwError(state, "missed comma between flow collection entries");
          } else if (ch === 44) {
            throwError(state, "expected the node content, but found ','");
          }
          keyTag = keyNode = valueNode = null;
          isPair = isExplicitPair = false;
          if (ch === 63) {
            following = state.input.charCodeAt(state.position + 1);
            if (is_WS_OR_EOL(following)) {
              isPair = isExplicitPair = true;
              state.position++;
              skipSeparationSpace(state, true, nodeIndent);
            }
          }
          _line = state.line;
          _lineStart = state.lineStart;
          _pos = state.position;
          composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
          keyTag = state.tag;
          keyNode = state.result;
          skipSeparationSpace(state, true, nodeIndent);
          ch = state.input.charCodeAt(state.position);
          if ((isExplicitPair || state.line === _line) && ch === 58) {
            isPair = true;
            ch = state.input.charCodeAt(++state.position);
            skipSeparationSpace(state, true, nodeIndent);
            composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
            valueNode = state.result;
          }
          if (isMapping) {
            storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos);
          } else if (isPair) {
            _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos));
          } else {
            _result.push(keyNode);
          }
          skipSeparationSpace(state, true, nodeIndent);
          ch = state.input.charCodeAt(state.position);
          if (ch === 44) {
            readNext = true;
            ch = state.input.charCodeAt(++state.position);
          } else {
            readNext = false;
          }
        }
        throwError(state, "unexpected end of the stream within a flow collection");
      }
      function readBlockScalar(state, nodeIndent) {
        var captureStart, folding, chomping = CHOMPING_CLIP, didReadContent = false, detectedIndent = false, textIndent = nodeIndent, emptyLines = 0, atMoreIndented = false, tmp, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch === 124) {
          folding = false;
        } else if (ch === 62) {
          folding = true;
        } else {
          return false;
        }
        state.kind = "scalar";
        state.result = "";
        while (ch !== 0) {
          ch = state.input.charCodeAt(++state.position);
          if (ch === 43 || ch === 45) {
            if (CHOMPING_CLIP === chomping) {
              chomping = ch === 43 ? CHOMPING_KEEP : CHOMPING_STRIP;
            } else {
              throwError(state, "repeat of a chomping mode identifier");
            }
          } else if ((tmp = fromDecimalCode(ch)) >= 0) {
            if (tmp === 0) {
              throwError(state, "bad explicit indentation width of a block scalar; it cannot be less than one");
            } else if (!detectedIndent) {
              textIndent = nodeIndent + tmp - 1;
              detectedIndent = true;
            } else {
              throwError(state, "repeat of an indentation width identifier");
            }
          } else {
            break;
          }
        }
        if (is_WHITE_SPACE(ch)) {
          do {
            ch = state.input.charCodeAt(++state.position);
          } while (is_WHITE_SPACE(ch));
          if (ch === 35) {
            do {
              ch = state.input.charCodeAt(++state.position);
            } while (!is_EOL(ch) && ch !== 0);
          }
        }
        while (ch !== 0) {
          readLineBreak(state);
          state.lineIndent = 0;
          ch = state.input.charCodeAt(state.position);
          while ((!detectedIndent || state.lineIndent < textIndent) && ch === 32) {
            state.lineIndent++;
            ch = state.input.charCodeAt(++state.position);
          }
          if (!detectedIndent && state.lineIndent > textIndent) {
            textIndent = state.lineIndent;
          }
          if (is_EOL(ch)) {
            emptyLines++;
            continue;
          }
          if (state.lineIndent < textIndent) {
            if (chomping === CHOMPING_KEEP) {
              state.result += common.repeat("\n", didReadContent ? 1 + emptyLines : emptyLines);
            } else if (chomping === CHOMPING_CLIP) {
              if (didReadContent) {
                state.result += "\n";
              }
            }
            break;
          }
          if (folding) {
            if (is_WHITE_SPACE(ch)) {
              atMoreIndented = true;
              state.result += common.repeat("\n", didReadContent ? 1 + emptyLines : emptyLines);
            } else if (atMoreIndented) {
              atMoreIndented = false;
              state.result += common.repeat("\n", emptyLines + 1);
            } else if (emptyLines === 0) {
              if (didReadContent) {
                state.result += " ";
              }
            } else {
              state.result += common.repeat("\n", emptyLines);
            }
          } else {
            state.result += common.repeat("\n", didReadContent ? 1 + emptyLines : emptyLines);
          }
          didReadContent = true;
          detectedIndent = true;
          emptyLines = 0;
          captureStart = state.position;
          while (!is_EOL(ch) && ch !== 0) {
            ch = state.input.charCodeAt(++state.position);
          }
          captureSegment(state, captureStart, state.position, false);
        }
        return true;
      }
      function readBlockSequence(state, nodeIndent) {
        var _line, _tag = state.tag, _anchor = state.anchor, _result = [], following, detected = false, ch;
        if (state.firstTabInLine !== -1) return false;
        if (state.anchor !== null) {
          state.anchorMap[state.anchor] = _result;
        }
        ch = state.input.charCodeAt(state.position);
        while (ch !== 0) {
          if (state.firstTabInLine !== -1) {
            state.position = state.firstTabInLine;
            throwError(state, "tab characters must not be used in indentation");
          }
          if (ch !== 45) {
            break;
          }
          following = state.input.charCodeAt(state.position + 1);
          if (!is_WS_OR_EOL(following)) {
            break;
          }
          detected = true;
          state.position++;
          if (skipSeparationSpace(state, true, -1)) {
            if (state.lineIndent <= nodeIndent) {
              _result.push(null);
              ch = state.input.charCodeAt(state.position);
              continue;
            }
          }
          _line = state.line;
          composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true);
          _result.push(state.result);
          skipSeparationSpace(state, true, -1);
          ch = state.input.charCodeAt(state.position);
          if ((state.line === _line || state.lineIndent > nodeIndent) && ch !== 0) {
            throwError(state, "bad indentation of a sequence entry");
          } else if (state.lineIndent < nodeIndent) {
            break;
          }
        }
        if (detected) {
          state.tag = _tag;
          state.anchor = _anchor;
          state.kind = "sequence";
          state.result = _result;
          return true;
        }
        return false;
      }
      function readBlockMapping(state, nodeIndent, flowIndent) {
        var following, allowCompact, _line, _keyLine, _keyLineStart, _keyPos, _tag = state.tag, _anchor = state.anchor, _result = {}, overridableKeys = /* @__PURE__ */ Object.create(null), keyTag = null, keyNode = null, valueNode = null, atExplicitKey = false, detected = false, ch;
        if (state.firstTabInLine !== -1) return false;
        if (state.anchor !== null) {
          state.anchorMap[state.anchor] = _result;
        }
        ch = state.input.charCodeAt(state.position);
        while (ch !== 0) {
          if (!atExplicitKey && state.firstTabInLine !== -1) {
            state.position = state.firstTabInLine;
            throwError(state, "tab characters must not be used in indentation");
          }
          following = state.input.charCodeAt(state.position + 1);
          _line = state.line;
          if ((ch === 63 || ch === 58) && is_WS_OR_EOL(following)) {
            if (ch === 63) {
              if (atExplicitKey) {
                storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
                keyTag = keyNode = valueNode = null;
              }
              detected = true;
              atExplicitKey = true;
              allowCompact = true;
            } else if (atExplicitKey) {
              atExplicitKey = false;
              allowCompact = true;
            } else {
              throwError(state, "incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line");
            }
            state.position += 1;
            ch = following;
          } else {
            _keyLine = state.line;
            _keyLineStart = state.lineStart;
            _keyPos = state.position;
            if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) {
              break;
            }
            if (state.line === _line) {
              ch = state.input.charCodeAt(state.position);
              while (is_WHITE_SPACE(ch)) {
                ch = state.input.charCodeAt(++state.position);
              }
              if (ch === 58) {
                ch = state.input.charCodeAt(++state.position);
                if (!is_WS_OR_EOL(ch)) {
                  throwError(state, "a whitespace character is expected after the key-value separator within a block mapping");
                }
                if (atExplicitKey) {
                  storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
                  keyTag = keyNode = valueNode = null;
                }
                detected = true;
                atExplicitKey = false;
                allowCompact = false;
                keyTag = state.tag;
                keyNode = state.result;
              } else if (detected) {
                throwError(state, "can not read an implicit mapping pair; a colon is missed");
              } else {
                state.tag = _tag;
                state.anchor = _anchor;
                return true;
              }
            } else if (detected) {
              throwError(state, "can not read a block mapping entry; a multiline key may not be an implicit key");
            } else {
              state.tag = _tag;
              state.anchor = _anchor;
              return true;
            }
          }
          if (state.line === _line || state.lineIndent > nodeIndent) {
            if (atExplicitKey) {
              _keyLine = state.line;
              _keyLineStart = state.lineStart;
              _keyPos = state.position;
            }
            if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) {
              if (atExplicitKey) {
                keyNode = state.result;
              } else {
                valueNode = state.result;
              }
            }
            if (!atExplicitKey) {
              storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos);
              keyTag = keyNode = valueNode = null;
            }
            skipSeparationSpace(state, true, -1);
            ch = state.input.charCodeAt(state.position);
          }
          if ((state.line === _line || state.lineIndent > nodeIndent) && ch !== 0) {
            throwError(state, "bad indentation of a mapping entry");
          } else if (state.lineIndent < nodeIndent) {
            break;
          }
        }
        if (atExplicitKey) {
          storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos);
        }
        if (detected) {
          state.tag = _tag;
          state.anchor = _anchor;
          state.kind = "mapping";
          state.result = _result;
        }
        return detected;
      }
      function readTagProperty(state) {
        var _position, isVerbatim = false, isNamed = false, tagHandle, tagName, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch !== 33) return false;
        if (state.tag !== null) {
          throwError(state, "duplication of a tag property");
        }
        ch = state.input.charCodeAt(++state.position);
        if (ch === 60) {
          isVerbatim = true;
          ch = state.input.charCodeAt(++state.position);
        } else if (ch === 33) {
          isNamed = true;
          tagHandle = "!!";
          ch = state.input.charCodeAt(++state.position);
        } else {
          tagHandle = "!";
        }
        _position = state.position;
        if (isVerbatim) {
          do {
            ch = state.input.charCodeAt(++state.position);
          } while (ch !== 0 && ch !== 62);
          if (state.position < state.length) {
            tagName = state.input.slice(_position, state.position);
            ch = state.input.charCodeAt(++state.position);
          } else {
            throwError(state, "unexpected end of the stream within a verbatim tag");
          }
        } else {
          while (ch !== 0 && !is_WS_OR_EOL(ch)) {
            if (ch === 33) {
              if (!isNamed) {
                tagHandle = state.input.slice(_position - 1, state.position + 1);
                if (!PATTERN_TAG_HANDLE.test(tagHandle)) {
                  throwError(state, "named tag handle cannot contain such characters");
                }
                isNamed = true;
                _position = state.position + 1;
              } else {
                throwError(state, "tag suffix cannot contain exclamation marks");
              }
            }
            ch = state.input.charCodeAt(++state.position);
          }
          tagName = state.input.slice(_position, state.position);
          if (PATTERN_FLOW_INDICATORS.test(tagName)) {
            throwError(state, "tag suffix cannot contain flow indicator characters");
          }
        }
        if (tagName && !PATTERN_TAG_URI.test(tagName)) {
          throwError(state, "tag name cannot contain such characters: " + tagName);
        }
        try {
          tagName = decodeURIComponent(tagName);
        } catch (err) {
          throwError(state, "tag name is malformed: " + tagName);
        }
        if (isVerbatim) {
          state.tag = tagName;
        } else if (_hasOwnProperty.call(state.tagMap, tagHandle)) {
          state.tag = state.tagMap[tagHandle] + tagName;
        } else if (tagHandle === "!") {
          state.tag = "!" + tagName;
        } else if (tagHandle === "!!") {
          state.tag = "tag:yaml.org,2002:" + tagName;
        } else {
          throwError(state, 'undeclared tag handle "' + tagHandle + '"');
        }
        return true;
      }
      function readAnchorProperty(state) {
        var _position, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch !== 38) return false;
        if (state.anchor !== null) {
          throwError(state, "duplication of an anchor property");
        }
        ch = state.input.charCodeAt(++state.position);
        _position = state.position;
        while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
          ch = state.input.charCodeAt(++state.position);
        }
        if (state.position === _position) {
          throwError(state, "name of an anchor node must contain at least one character");
        }
        state.anchor = state.input.slice(_position, state.position);
        return true;
      }
      function readAlias(state) {
        var _position, alias, ch;
        ch = state.input.charCodeAt(state.position);
        if (ch !== 42) return false;
        ch = state.input.charCodeAt(++state.position);
        _position = state.position;
        while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) {
          ch = state.input.charCodeAt(++state.position);
        }
        if (state.position === _position) {
          throwError(state, "name of an alias node must contain at least one character");
        }
        alias = state.input.slice(_position, state.position);
        if (!_hasOwnProperty.call(state.anchorMap, alias)) {
          throwError(state, 'unidentified alias "' + alias + '"');
        }
        state.result = state.anchorMap[alias];
        skipSeparationSpace(state, true, -1);
        return true;
      }
      function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) {
        var allowBlockStyles, allowBlockScalars, allowBlockCollections, indentStatus = 1, atNewLine = false, hasContent = false, typeIndex, typeQuantity, typeList, type, flowIndent, blockIndent;
        if (state.listener !== null) {
          state.listener("open", state);
        }
        state.tag = null;
        state.anchor = null;
        state.kind = null;
        state.result = null;
        allowBlockStyles = allowBlockScalars = allowBlockCollections = CONTEXT_BLOCK_OUT === nodeContext || CONTEXT_BLOCK_IN === nodeContext;
        if (allowToSeek) {
          if (skipSeparationSpace(state, true, -1)) {
            atNewLine = true;
            if (state.lineIndent > parentIndent) {
              indentStatus = 1;
            } else if (state.lineIndent === parentIndent) {
              indentStatus = 0;
            } else if (state.lineIndent < parentIndent) {
              indentStatus = -1;
            }
          }
        }
        if (indentStatus === 1) {
          while (readTagProperty(state) || readAnchorProperty(state)) {
            if (skipSeparationSpace(state, true, -1)) {
              atNewLine = true;
              allowBlockCollections = allowBlockStyles;
              if (state.lineIndent > parentIndent) {
                indentStatus = 1;
              } else if (state.lineIndent === parentIndent) {
                indentStatus = 0;
              } else if (state.lineIndent < parentIndent) {
                indentStatus = -1;
              }
            } else {
              allowBlockCollections = false;
            }
          }
        }
        if (allowBlockCollections) {
          allowBlockCollections = atNewLine || allowCompact;
        }
        if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) {
          if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) {
            flowIndent = parentIndent;
          } else {
            flowIndent = parentIndent + 1;
          }
          blockIndent = state.position - state.lineStart;
          if (indentStatus === 1) {
            if (allowBlockCollections && (readBlockSequence(state, blockIndent) || readBlockMapping(state, blockIndent, flowIndent)) || readFlowCollection(state, flowIndent)) {
              hasContent = true;
            } else {
              if (allowBlockScalars && readBlockScalar(state, flowIndent) || readSingleQuotedScalar(state, flowIndent) || readDoubleQuotedScalar(state, flowIndent)) {
                hasContent = true;
              } else if (readAlias(state)) {
                hasContent = true;
                if (state.tag !== null || state.anchor !== null) {
                  throwError(state, "alias node should not have any properties");
                }
              } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) {
                hasContent = true;
                if (state.tag === null) {
                  state.tag = "?";
                }
              }
              if (state.anchor !== null) {
                state.anchorMap[state.anchor] = state.result;
              }
            }
          } else if (indentStatus === 0) {
            hasContent = allowBlockCollections && readBlockSequence(state, blockIndent);
          }
        }
        if (state.tag === null) {
          if (state.anchor !== null) {
            state.anchorMap[state.anchor] = state.result;
          }
        } else if (state.tag === "?") {
          if (state.result !== null && state.kind !== "scalar") {
            throwError(state, 'unacceptable node kind for !<?> tag; it should be "scalar", not "' + state.kind + '"');
          }
          for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) {
            type = state.implicitTypes[typeIndex];
            if (type.resolve(state.result)) {
              state.result = type.construct(state.result);
              state.tag = type.tag;
              if (state.anchor !== null) {
                state.anchorMap[state.anchor] = state.result;
              }
              break;
            }
          }
        } else if (state.tag !== "!") {
          if (_hasOwnProperty.call(state.typeMap[state.kind || "fallback"], state.tag)) {
            type = state.typeMap[state.kind || "fallback"][state.tag];
          } else {
            type = null;
            typeList = state.typeMap.multi[state.kind || "fallback"];
            for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) {
              if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) {
                type = typeList[typeIndex];
                break;
              }
            }
          }
          if (!type) {
            throwError(state, "unknown tag !<" + state.tag + ">");
          }
          if (state.result !== null && type.kind !== state.kind) {
            throwError(state, "unacceptable node kind for !<" + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"');
          }
          if (!type.resolve(state.result, state.tag)) {
            throwError(state, "cannot resolve a node with !<" + state.tag + "> explicit tag");
          } else {
            state.result = type.construct(state.result, state.tag);
            if (state.anchor !== null) {
              state.anchorMap[state.anchor] = state.result;
            }
          }
        }
        if (state.listener !== null) {
          state.listener("close", state);
        }
        return state.tag !== null || state.anchor !== null || hasContent;
      }
      function readDocument(state) {
        var documentStart = state.position, _position, directiveName, directiveArgs, hasDirectives = false, ch;
        state.version = null;
        state.checkLineBreaks = state.legacy;
        state.tagMap = /* @__PURE__ */ Object.create(null);
        state.anchorMap = /* @__PURE__ */ Object.create(null);
        while ((ch = state.input.charCodeAt(state.position)) !== 0) {
          skipSeparationSpace(state, true, -1);
          ch = state.input.charCodeAt(state.position);
          if (state.lineIndent > 0 || ch !== 37) {
            break;
          }
          hasDirectives = true;
          ch = state.input.charCodeAt(++state.position);
          _position = state.position;
          while (ch !== 0 && !is_WS_OR_EOL(ch)) {
            ch = state.input.charCodeAt(++state.position);
          }
          directiveName = state.input.slice(_position, state.position);
          directiveArgs = [];
          if (directiveName.length < 1) {
            throwError(state, "directive name must not be less than one character in length");
          }
          while (ch !== 0) {
            while (is_WHITE_SPACE(ch)) {
              ch = state.input.charCodeAt(++state.position);
            }
            if (ch === 35) {
              do {
                ch = state.input.charCodeAt(++state.position);
              } while (ch !== 0 && !is_EOL(ch));
              break;
            }
            if (is_EOL(ch)) break;
            _position = state.position;
            while (ch !== 0 && !is_WS_OR_EOL(ch)) {
              ch = state.input.charCodeAt(++state.position);
            }
            directiveArgs.push(state.input.slice(_position, state.position));
          }
          if (ch !== 0) readLineBreak(state);
          if (_hasOwnProperty.call(directiveHandlers, directiveName)) {
            directiveHandlers[directiveName](state, directiveName, directiveArgs);
          } else {
            throwWarning(state, 'unknown document directive "' + directiveName + '"');
          }
        }
        skipSeparationSpace(state, true, -1);
        if (state.lineIndent === 0 && state.input.charCodeAt(state.position) === 45 && state.input.charCodeAt(state.position + 1) === 45 && state.input.charCodeAt(state.position + 2) === 45) {
          state.position += 3;
          skipSeparationSpace(state, true, -1);
        } else if (hasDirectives) {
          throwError(state, "directives end mark is expected");
        }
        composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true);
        skipSeparationSpace(state, true, -1);
        if (state.checkLineBreaks && PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) {
          throwWarning(state, "non-ASCII line breaks are interpreted as content");
        }
        state.documents.push(state.result);
        if (state.position === state.lineStart && testDocumentSeparator(state)) {
          if (state.input.charCodeAt(state.position) === 46) {
            state.position += 3;
            skipSeparationSpace(state, true, -1);
          }
          return;
        }
        if (state.position < state.length - 1) {
          throwError(state, "end of the stream or a document separator is expected");
        } else {
          return;
        }
      }
      function loadDocuments(input, options) {
        input = String(input);
        options = options || {};
        if (input.length !== 0) {
          if (input.charCodeAt(input.length - 1) !== 10 && input.charCodeAt(input.length - 1) !== 13) {
            input += "\n";
          }
          if (input.charCodeAt(0) === 65279) {
            input = input.slice(1);
          }
        }
        var state = new State(input, options);
        var nullpos = input.indexOf("\0");
        if (nullpos !== -1) {
          state.position = nullpos;
          throwError(state, "null byte is not allowed in input");
        }
        state.input += "\0";
        while (state.input.charCodeAt(state.position) === 32) {
          state.lineIndent += 1;
          state.position += 1;
        }
        while (state.position < state.length - 1) {
          readDocument(state);
        }
        return state.documents;
      }
      function loadAll(input, iterator, options) {
        if (iterator !== null && typeof iterator === "object" && typeof options === "undefined") {
          options = iterator;
          iterator = null;
        }
        var documents = loadDocuments(input, options);
        if (typeof iterator !== "function") {
          return documents;
        }
        for (var index = 0, length = documents.length; index < length; index += 1) {
          iterator(documents[index]);
        }
      }
      function load(input, options) {
        var documents = loadDocuments(input, options);
        if (documents.length === 0) {
          return void 0;
        } else if (documents.length === 1) {
          return documents[0];
        }
        throw new YAMLException("expected a single document in the stream, but found more");
      }
      module2.exports.loadAll = loadAll;
      module2.exports.load = load;
    }
  });

  // node_modules/js-yaml/lib/dumper.js
  var require_dumper = __commonJS({
    "node_modules/js-yaml/lib/dumper.js"(exports2, module2) {
      "use strict";
      var common = require_common();
      var YAMLException = require_exception();
      var DEFAULT_SCHEMA = require_default();
      var _toString = Object.prototype.toString;
      var _hasOwnProperty = Object.prototype.hasOwnProperty;
      var CHAR_BOM = 65279;
      var CHAR_TAB = 9;
      var CHAR_LINE_FEED = 10;
      var CHAR_CARRIAGE_RETURN = 13;
      var CHAR_SPACE = 32;
      var CHAR_EXCLAMATION = 33;
      var CHAR_DOUBLE_QUOTE = 34;
      var CHAR_SHARP = 35;
      var CHAR_PERCENT = 37;
      var CHAR_AMPERSAND = 38;
      var CHAR_SINGLE_QUOTE = 39;
      var CHAR_ASTERISK = 42;
      var CHAR_COMMA = 44;
      var CHAR_MINUS = 45;
      var CHAR_COLON = 58;
      var CHAR_EQUALS = 61;
      var CHAR_GREATER_THAN = 62;
      var CHAR_QUESTION = 63;
      var CHAR_COMMERCIAL_AT = 64;
      var CHAR_LEFT_SQUARE_BRACKET = 91;
      var CHAR_RIGHT_SQUARE_BRACKET = 93;
      var CHAR_GRAVE_ACCENT = 96;
      var CHAR_LEFT_CURLY_BRACKET = 123;
      var CHAR_VERTICAL_LINE = 124;
      var CHAR_RIGHT_CURLY_BRACKET = 125;
      var ESCAPE_SEQUENCES = {};
      ESCAPE_SEQUENCES[0] = "\\0";
      ESCAPE_SEQUENCES[7] = "\\a";
      ESCAPE_SEQUENCES[8] = "\\b";
      ESCAPE_SEQUENCES[9] = "\\t";
      ESCAPE_SEQUENCES[10] = "\\n";
      ESCAPE_SEQUENCES[11] = "\\v";
      ESCAPE_SEQUENCES[12] = "\\f";
      ESCAPE_SEQUENCES[13] = "\\r";
      ESCAPE_SEQUENCES[27] = "\\e";
      ESCAPE_SEQUENCES[34] = '\\"';
      ESCAPE_SEQUENCES[92] = "\\\\";
      ESCAPE_SEQUENCES[133] = "\\N";
      ESCAPE_SEQUENCES[160] = "\\_";
      ESCAPE_SEQUENCES[8232] = "\\L";
      ESCAPE_SEQUENCES[8233] = "\\P";
      var DEPRECATED_BOOLEANS_SYNTAX = [
        "y",
        "Y",
        "yes",
        "Yes",
        "YES",
        "on",
        "On",
        "ON",
        "n",
        "N",
        "no",
        "No",
        "NO",
        "off",
        "Off",
        "OFF"
      ];
      var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;
      function compileStyleMap(schema, map) {
        var result, keys, index, length, tag, style, type;
        if (map === null) return {};
        result = {};
        keys = Object.keys(map);
        for (index = 0, length = keys.length; index < length; index += 1) {
          tag = keys[index];
          style = String(map[tag]);
          if (tag.slice(0, 2) === "!!") {
            tag = "tag:yaml.org,2002:" + tag.slice(2);
          }
          type = schema.compiledTypeMap["fallback"][tag];
          if (type && _hasOwnProperty.call(type.styleAliases, style)) {
            style = type.styleAliases[style];
          }
          result[tag] = style;
        }
        return result;
      }
      function encodeHex(character) {
        var string, handle, length;
        string = character.toString(16).toUpperCase();
        if (character <= 255) {
          handle = "x";
          length = 2;
        } else if (character <= 65535) {
          handle = "u";
          length = 4;
        } else if (character <= 4294967295) {
          handle = "U";
          length = 8;
        } else {
          throw new YAMLException("code point within a string may not be greater than 0xFFFFFFFF");
        }
        return "\\" + handle + common.repeat("0", length - string.length) + string;
      }
      var QUOTING_TYPE_SINGLE = 1;
      var QUOTING_TYPE_DOUBLE = 2;
      function State(options) {
        this.schema = options["schema"] || DEFAULT_SCHEMA;
        this.indent = Math.max(1, options["indent"] || 2);
        this.noArrayIndent = options["noArrayIndent"] || false;
        this.skipInvalid = options["skipInvalid"] || false;
        this.flowLevel = common.isNothing(options["flowLevel"]) ? -1 : options["flowLevel"];
        this.styleMap = compileStyleMap(this.schema, options["styles"] || null);
        this.sortKeys = options["sortKeys"] || false;
        this.lineWidth = options["lineWidth"] || 80;
        this.noRefs = options["noRefs"] || false;
        this.noCompatMode = options["noCompatMode"] || false;
        this.condenseFlow = options["condenseFlow"] || false;
        this.quotingType = options["quotingType"] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE;
        this.forceQuotes = options["forceQuotes"] || false;
        this.replacer = typeof options["replacer"] === "function" ? options["replacer"] : null;
        this.implicitTypes = this.schema.compiledImplicit;
        this.explicitTypes = this.schema.compiledExplicit;
        this.tag = null;
        this.result = "";
        this.duplicates = [];
        this.usedDuplicates = null;
      }
      function indentString(string, spaces) {
        var ind = common.repeat(" ", spaces), position = 0, next = -1, result = "", line, length = string.length;
        while (position < length) {
          next = string.indexOf("\n", position);
          if (next === -1) {
            line = string.slice(position);
            position = length;
          } else {
            line = string.slice(position, next + 1);
            position = next + 1;
          }
          if (line.length && line !== "\n") result += ind;
          result += line;
        }
        return result;
      }
      function generateNextLine(state, level) {
        return "\n" + common.repeat(" ", state.indent * level);
      }
      function testImplicitResolving(state, str) {
        var index, length, type;
        for (index = 0, length = state.implicitTypes.length; index < length; index += 1) {
          type = state.implicitTypes[index];
          if (type.resolve(str)) {
            return true;
          }
        }
        return false;
      }
      function isWhitespace(c) {
        return c === CHAR_SPACE || c === CHAR_TAB;
      }
      function isPrintable(c) {
        return 32 <= c && c <= 126 || 161 <= c && c <= 55295 && c !== 8232 && c !== 8233 || 57344 <= c && c <= 65533 && c !== CHAR_BOM || 65536 <= c && c <= 1114111;
      }
      function isNsCharOrWhitespace(c) {
        return isPrintable(c) && c !== CHAR_BOM && c !== CHAR_CARRIAGE_RETURN && c !== CHAR_LINE_FEED;
      }
      function isPlainSafe(c, prev, inblock) {
        var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);
        var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);
        return (
          // ns-plain-safe
          (inblock ? (
            // c = flow-in
            cIsNsCharOrWhitespace
          ) : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar
        );
      }
      function isPlainSafeFirst(c) {
        return isPrintable(c) && c !== CHAR_BOM && !isWhitespace(c) && c !== CHAR_MINUS && c !== CHAR_QUESTION && c !== CHAR_COLON && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET && c !== CHAR_SHARP && c !== CHAR_AMPERSAND && c !== CHAR_ASTERISK && c !== CHAR_EXCLAMATION && c !== CHAR_VERTICAL_LINE && c !== CHAR_EQUALS && c !== CHAR_GREATER_THAN && c !== CHAR_SINGLE_QUOTE && c !== CHAR_DOUBLE_QUOTE && c !== CHAR_PERCENT && c !== CHAR_COMMERCIAL_AT && c !== CHAR_GRAVE_ACCENT;
      }
      function isPlainSafeLast(c) {
        return !isWhitespace(c) && c !== CHAR_COLON;
      }
      function codePointAt(string, pos) {
        var first = string.charCodeAt(pos), second;
        if (first >= 55296 && first <= 56319 && pos + 1 < string.length) {
          second = string.charCodeAt(pos + 1);
          if (second >= 56320 && second <= 57343) {
            return (first - 55296) * 1024 + second - 56320 + 65536;
          }
        }
        return first;
      }
      function needIndentIndicator(string) {
        var leadingSpaceRe = /^\n* /;
        return leadingSpaceRe.test(string);
      }
      var STYLE_PLAIN = 1;
      var STYLE_SINGLE = 2;
      var STYLE_LITERAL = 3;
      var STYLE_FOLDED = 4;
      var STYLE_DOUBLE = 5;
      function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, testAmbiguousType, quotingType, forceQuotes, inblock) {
        var i;
        var char = 0;
        var prevChar = null;
        var hasLineBreak = false;
        var hasFoldableLine = false;
        var shouldTrackWidth = lineWidth !== -1;
        var previousLineBreak = -1;
        var plain = isPlainSafeFirst(codePointAt(string, 0)) && isPlainSafeLast(codePointAt(string, string.length - 1));
        if (singleLineOnly || forceQuotes) {
          for (i = 0; i < string.length; char >= 65536 ? i += 2 : i++) {
            char = codePointAt(string, i);
            if (!isPrintable(char)) {
              return STYLE_DOUBLE;
            }
            plain = plain && isPlainSafe(char, prevChar, inblock);
            prevChar = char;
          }
        } else {
          for (i = 0; i < string.length; char >= 65536 ? i += 2 : i++) {
            char = codePointAt(string, i);
            if (char === CHAR_LINE_FEED) {
              hasLineBreak = true;
              if (shouldTrackWidth) {
                hasFoldableLine = hasFoldableLine || // Foldable line = too long, and not more-indented.
                i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " ";
                previousLineBreak = i;
              }
            } else if (!isPrintable(char)) {
              return STYLE_DOUBLE;
            }
            plain = plain && isPlainSafe(char, prevChar, inblock);
            prevChar = char;
          }
          hasFoldableLine = hasFoldableLine || shouldTrackWidth && (i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1] !== " ");
        }
        if (!hasLineBreak && !hasFoldableLine) {
          if (plain && !forceQuotes && !testAmbiguousType(string)) {
            return STYLE_PLAIN;
          }
          return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;
        }
        if (indentPerLevel > 9 && needIndentIndicator(string)) {
          return STYLE_DOUBLE;
        }
        if (!forceQuotes) {
          return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL;
        }
        return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE;
      }
      function writeScalar(state, string, level, iskey, inblock) {
        state.dump = (function() {
          if (string.length === 0) {
            return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''";
          }
          if (!state.noCompatMode) {
            if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {
              return state.quotingType === QUOTING_TYPE_DOUBLE ? '"' + string + '"' : "'" + string + "'";
            }
          }
          var indent = state.indent * Math.max(1, level);
          var lineWidth = state.lineWidth === -1 ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent);
          var singleLineOnly = iskey || state.flowLevel > -1 && level >= state.flowLevel;
          function testAmbiguity(string2) {
            return testImplicitResolving(state, string2);
          }
          switch (chooseScalarStyle(
            string,
            singleLineOnly,
            state.indent,
            lineWidth,
            testAmbiguity,
            state.quotingType,
            state.forceQuotes && !iskey,
            inblock
          )) {
            case STYLE_PLAIN:
              return string;
            case STYLE_SINGLE:
              return "'" + string.replace(/'/g, "''") + "'";
            case STYLE_LITERAL:
              return "|" + blockHeader(string, state.indent) + dropEndingNewline(indentString(string, indent));
            case STYLE_FOLDED:
              return ">" + blockHeader(string, state.indent) + dropEndingNewline(indentString(foldString(string, lineWidth), indent));
            case STYLE_DOUBLE:
              return '"' + escapeString(string, lineWidth) + '"';
            default:
              throw new YAMLException("impossible error: invalid scalar style");
          }
        })();
      }
      function blockHeader(string, indentPerLevel) {
        var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : "";
        var clip = string[string.length - 1] === "\n";
        var keep = clip && (string[string.length - 2] === "\n" || string === "\n");
        var chomp = keep ? "+" : clip ? "" : "-";
        return indentIndicator + chomp + "\n";
      }
      function dropEndingNewline(string) {
        return string[string.length - 1] === "\n" ? string.slice(0, -1) : string;
      }
      function foldString(string, width) {
        var lineRe = /(\n+)([^\n]*)/g;
        var result = (function() {
          var nextLF = string.indexOf("\n");
          nextLF = nextLF !== -1 ? nextLF : string.length;
          lineRe.lastIndex = nextLF;
          return foldLine(string.slice(0, nextLF), width);
        })();
        var prevMoreIndented = string[0] === "\n" || string[0] === " ";
        var moreIndented;
        var match;
        while (match = lineRe.exec(string)) {
          var prefix = match[1], line = match[2];
          moreIndented = line[0] === " ";
          result += prefix + (!prevMoreIndented && !moreIndented && line !== "" ? "\n" : "") + foldLine(line, width);
          prevMoreIndented = moreIndented;
        }
        return result;
      }
      function foldLine(line, width) {
        if (line === "" || line[0] === " ") return line;
        var breakRe = / [^ ]/g;
        var match;
        var start = 0, end, curr = 0, next = 0;
        var result = "";
        while (match = breakRe.exec(line)) {
          next = match.index;
          if (next - start > width) {
            end = curr > start ? curr : next;
            result += "\n" + line.slice(start, end);
            start = end + 1;
          }
          curr = next;
        }
        result += "\n";
        if (line.length - start > width && curr > start) {
          result += line.slice(start, curr) + "\n" + line.slice(curr + 1);
        } else {
          result += line.slice(start);
        }
        return result.slice(1);
      }
      function escapeString(string) {
        var result = "";
        var char = 0;
        var escapeSeq;
        for (var i = 0; i < string.length; char >= 65536 ? i += 2 : i++) {
          char = codePointAt(string, i);
          escapeSeq = ESCAPE_SEQUENCES[char];
          if (!escapeSeq && isPrintable(char)) {
            result += string[i];
            if (char >= 65536) result += string[i + 1];
          } else {
            result += escapeSeq || encodeHex(char);
          }
        }
        return result;
      }
      function writeFlowSequence(state, level, object) {
        var _result = "", _tag = state.tag, index, length, value;
        for (index = 0, length = object.length; index < length; index += 1) {
          value = object[index];
          if (state.replacer) {
            value = state.replacer.call(object, String(index), value);
          }
          if (writeNode(state, level, value, false, false) || typeof value === "undefined" && writeNode(state, level, null, false, false)) {
            if (_result !== "") _result += "," + (!state.condenseFlow ? " " : "");
            _result += state.dump;
          }
        }
        state.tag = _tag;
        state.dump = "[" + _result + "]";
      }
      function writeBlockSequence(state, level, object, compact) {
        var _result = "", _tag = state.tag, index, length, value;
        for (index = 0, length = object.length; index < length; index += 1) {
          value = object[index];
          if (state.replacer) {
            value = state.replacer.call(object, String(index), value);
          }
          if (writeNode(state, level + 1, value, true, true, false, true) || typeof value === "undefined" && writeNode(state, level + 1, null, true, true, false, true)) {
            if (!compact || _result !== "") {
              _result += generateNextLine(state, level);
            }
            if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
              _result += "-";
            } else {
              _result += "- ";
            }
            _result += state.dump;
          }
        }
        state.tag = _tag;
        state.dump = _result || "[]";
      }
      function writeFlowMapping(state, level, object) {
        var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, pairBuffer;
        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
          pairBuffer = "";
          if (_result !== "") pairBuffer += ", ";
          if (state.condenseFlow) pairBuffer += '"';
          objectKey = objectKeyList[index];
          objectValue = object[objectKey];
          if (state.replacer) {
            objectValue = state.replacer.call(object, objectKey, objectValue);
          }
          if (!writeNode(state, level, objectKey, false, false)) {
            continue;
          }
          if (state.dump.length > 1024) pairBuffer += "? ";
          pairBuffer += state.dump + (state.condenseFlow ? '"' : "") + ":" + (state.condenseFlow ? "" : " ");
          if (!writeNode(state, level, objectValue, false, false)) {
            continue;
          }
          pairBuffer += state.dump;
          _result += pairBuffer;
        }
        state.tag = _tag;
        state.dump = "{" + _result + "}";
      }
      function writeBlockMapping(state, level, object, compact) {
        var _result = "", _tag = state.tag, objectKeyList = Object.keys(object), index, length, objectKey, objectValue, explicitPair, pairBuffer;
        if (state.sortKeys === true) {
          objectKeyList.sort();
        } else if (typeof state.sortKeys === "function") {
          objectKeyList.sort(state.sortKeys);
        } else if (state.sortKeys) {
          throw new YAMLException("sortKeys must be a boolean or a function");
        }
        for (index = 0, length = objectKeyList.length; index < length; index += 1) {
          pairBuffer = "";
          if (!compact || _result !== "") {
            pairBuffer += generateNextLine(state, level);
          }
          objectKey = objectKeyList[index];
          objectValue = object[objectKey];
          if (state.replacer) {
            objectValue = state.replacer.call(object, objectKey, objectValue);
          }
          if (!writeNode(state, level + 1, objectKey, true, true, true)) {
            continue;
          }
          explicitPair = state.tag !== null && state.tag !== "?" || state.dump && state.dump.length > 1024;
          if (explicitPair) {
            if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
              pairBuffer += "?";
            } else {
              pairBuffer += "? ";
            }
          }
          pairBuffer += state.dump;
          if (explicitPair) {
            pairBuffer += generateNextLine(state, level);
          }
          if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
            continue;
          }
          if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
            pairBuffer += ":";
          } else {
            pairBuffer += ": ";
          }
          pairBuffer += state.dump;
          _result += pairBuffer;
        }
        state.tag = _tag;
        state.dump = _result || "{}";
      }
      function detectType(state, object, explicit) {
        var _result, typeList, index, length, type, style;
        typeList = explicit ? state.explicitTypes : state.implicitTypes;
        for (index = 0, length = typeList.length; index < length; index += 1) {
          type = typeList[index];
          if ((type.instanceOf || type.predicate) && (!type.instanceOf || typeof object === "object" && object instanceof type.instanceOf) && (!type.predicate || type.predicate(object))) {
            if (explicit) {
              if (type.multi && type.representName) {
                state.tag = type.representName(object);
              } else {
                state.tag = type.tag;
              }
            } else {
              state.tag = "?";
            }
            if (type.represent) {
              style = state.styleMap[type.tag] || type.defaultStyle;
              if (_toString.call(type.represent) === "[object Function]") {
                _result = type.represent(object, style);
              } else if (_hasOwnProperty.call(type.represent, style)) {
                _result = type.represent[style](object, style);
              } else {
                throw new YAMLException("!<" + type.tag + '> tag resolver accepts not "' + style + '" style');
              }
              state.dump = _result;
            }
            return true;
          }
        }
        return false;
      }
      function writeNode(state, level, object, block, compact, iskey, isblockseq) {
        state.tag = null;
        state.dump = object;
        if (!detectType(state, object, false)) {
          detectType(state, object, true);
        }
        var type = _toString.call(state.dump);
        var inblock = block;
        var tagStr;
        if (block) {
          block = state.flowLevel < 0 || state.flowLevel > level;
        }
        var objectOrArray = type === "[object Object]" || type === "[object Array]", duplicateIndex, duplicate;
        if (objectOrArray) {
          duplicateIndex = state.duplicates.indexOf(object);
          duplicate = duplicateIndex !== -1;
        }
        if (state.tag !== null && state.tag !== "?" || duplicate || state.indent !== 2 && level > 0) {
          compact = false;
        }
        if (duplicate && state.usedDuplicates[duplicateIndex]) {
          state.dump = "*ref_" + duplicateIndex;
        } else {
          if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
            state.usedDuplicates[duplicateIndex] = true;
          }
          if (type === "[object Object]") {
            if (block && Object.keys(state.dump).length !== 0) {
              writeBlockMapping(state, level, state.dump, compact);
              if (duplicate) {
                state.dump = "&ref_" + duplicateIndex + state.dump;
              }
            } else {
              writeFlowMapping(state, level, state.dump);
              if (duplicate) {
                state.dump = "&ref_" + duplicateIndex + " " + state.dump;
              }
            }
          } else if (type === "[object Array]") {
            if (block && state.dump.length !== 0) {
              if (state.noArrayIndent && !isblockseq && level > 0) {
                writeBlockSequence(state, level - 1, state.dump, compact);
              } else {
                writeBlockSequence(state, level, state.dump, compact);
              }
              if (duplicate) {
                state.dump = "&ref_" + duplicateIndex + state.dump;
              }
            } else {
              writeFlowSequence(state, level, state.dump);
              if (duplicate) {
                state.dump = "&ref_" + duplicateIndex + " " + state.dump;
              }
            }
          } else if (type === "[object String]") {
            if (state.tag !== "?") {
              writeScalar(state, state.dump, level, iskey, inblock);
            }
          } else if (type === "[object Undefined]") {
            return false;
          } else {
            if (state.skipInvalid) return false;
            throw new YAMLException("unacceptable kind of an object to dump " + type);
          }
          if (state.tag !== null && state.tag !== "?") {
            tagStr = encodeURI(
              state.tag[0] === "!" ? state.tag.slice(1) : state.tag
            ).replace(/!/g, "%21");
            if (state.tag[0] === "!") {
              tagStr = "!" + tagStr;
            } else if (tagStr.slice(0, 18) === "tag:yaml.org,2002:") {
              tagStr = "!!" + tagStr.slice(18);
            } else {
              tagStr = "!<" + tagStr + ">";
            }
            state.dump = tagStr + " " + state.dump;
          }
        }
        return true;
      }
      function getDuplicateReferences(object, state) {
        var objects = [], duplicatesIndexes = [], index, length;
        inspectNode(object, objects, duplicatesIndexes);
        for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) {
          state.duplicates.push(objects[duplicatesIndexes[index]]);
        }
        state.usedDuplicates = new Array(length);
      }
      function inspectNode(object, objects, duplicatesIndexes) {
        var objectKeyList, index, length;
        if (object !== null && typeof object === "object") {
          index = objects.indexOf(object);
          if (index !== -1) {
            if (duplicatesIndexes.indexOf(index) === -1) {
              duplicatesIndexes.push(index);
            }
          } else {
            objects.push(object);
            if (Array.isArray(object)) {
              for (index = 0, length = object.length; index < length; index += 1) {
                inspectNode(object[index], objects, duplicatesIndexes);
              }
            } else {
              objectKeyList = Object.keys(object);
              for (index = 0, length = objectKeyList.length; index < length; index += 1) {
                inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes);
              }
            }
          }
        }
      }
      function dump(input, options) {
        options = options || {};
        var state = new State(options);
        if (!state.noRefs) getDuplicateReferences(input, state);
        var value = input;
        if (state.replacer) {
          value = state.replacer.call({ "": value }, "", value);
        }
        if (writeNode(state, 0, value, true, true)) return state.dump + "\n";
        return "";
      }
      module2.exports.dump = dump;
    }
  });

  // node_modules/js-yaml/index.js
  var require_js_yaml = __commonJS({
    "node_modules/js-yaml/index.js"(exports2, module2) {
      "use strict";
      var loader = require_loader();
      var dumper = require_dumper();
      function renamed(from, to) {
        return function() {
          throw new Error("Function yaml." + from + " is removed in js-yaml 4. Use yaml." + to + " instead, which is now safe by default.");
        };
      }
      module2.exports.Type = require_type();
      module2.exports.Schema = require_schema();
      module2.exports.FAILSAFE_SCHEMA = require_failsafe();
      module2.exports.JSON_SCHEMA = require_json2();
      module2.exports.CORE_SCHEMA = require_core();
      module2.exports.DEFAULT_SCHEMA = require_default();
      module2.exports.load = loader.load;
      module2.exports.loadAll = loader.loadAll;
      module2.exports.dump = dumper.dump;
      module2.exports.YAMLException = require_exception();
      module2.exports.types = {
        binary: require_binary(),
        float: require_float(),
        map: require_map(),
        null: require_null(),
        pairs: require_pairs(),
        set: require_set(),
        timestamp: require_timestamp(),
        bool: require_bool(),
        int: require_int(),
        merge: require_merge(),
        omap: require_omap(),
        seq: require_seq(),
        str: require_str()
      };
      module2.exports.safeLoad = renamed("safeLoad", "load");
      module2.exports.safeLoadAll = renamed("safeLoadAll", "loadAll");
      module2.exports.safeDump = renamed("safeDump", "dump");
    }
  });

  // modules/std/data/yaml.js
  var require_yaml = __commonJS({
    "modules/std/data/yaml.js"(exports2, module2) {
      "use strict";
      var yaml = require_js_yaml();
      var { Pair, PairList, ZuzuBag } = require_collections();
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
      var utf8Encoder = new TextEncoder();
      function isPlainObject2(value) {
        return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof PairList) && !(value instanceof ZuzuBag) && Object.prototype.toString.call(value) !== "[object Set]";
      }
      function isPath(value) {
        return value && value.constructor && value.constructor.name === "Path" && typeof value.slurp === "function" && typeof value.spew === "function";
      }
      function normalizeValue(value) {
        if (value instanceof PairList) {
          const out = {};
          for (const [key, inner] of value.list) {
            if (!Object.prototype.hasOwnProperty.call(out, String(key))) {
              out[String(key)] = normalizeValue(inner);
            }
          }
          return out;
        }
        if (value && Array.isArray(value.items) && typeof value.to_Array === "function") {
          return normalizeValue(
            value.to_Array().slice().sort((left, right) => String(left).localeCompare(String(right)))
          );
        }
        if (value && value.constructor && value.constructor.name === "Set" && typeof value.to_Array === "function") {
          return normalizeValue(
            value.to_Array().slice().sort((left, right) => String(left).localeCompare(String(right)))
          );
        }
        if (value && value.constructor && value.constructor.name === "ZuzuBag" && typeof value.to_Array === "function") {
          return normalizeValue(
            value.to_Array().slice().sort((left, right) => String(left).localeCompare(String(right)))
          );
        }
        if (value && value.constructor && ["Set", "ZuzuBag", "PairList"].includes(value.constructor.name) && typeof value.to_Array === "function") {
          return normalizeValue(value.to_Array());
        }
        if (Array.isArray(value)) {
          return value.map((item) => normalizeValue(item));
        }
        if (value && value.constructor && value.constructor.name === "Object") {
          const out = {};
          for (const key of Object.keys(value).sort()) {
            out[key] = normalizeValue(value[key]);
          }
          return out;
        }
        return value;
      }
      function decorateValue(value) {
        if (Array.isArray(value)) {
          for (let i = 0; i < value.length; i++) {
            value[i] = decorateValue(value[i]);
          }
          return value;
        }
        if (!isPlainObject2(value)) {
          return value;
        }
        const sortedKeys = () => Object.keys(value).sort();
        for (const [name2, fn2] of [
          ["length", function _length() {
            return Object.keys(this).length;
          }],
          ["count", function _count() {
            return Object.keys(this).length;
          }],
          ["empty", function _empty() {
            return Object.keys(this).length === 0 ? 1 : 0;
          }],
          ["keys", function _keys() {
            return new Set(sortedKeys());
          }],
          ["values", function _values() {
            return new ZuzuBag(sortedKeys().map((key) => this[key]));
          }],
          [
            "enumerate",
            function _enumerate() {
              return new ZuzuBag(
                sortedKeys().map(
                  (key) => new Pair({ pair: [key, this[key]] })
                )
              );
            }
          ],
          ["has", function _has(key) {
            return Object.prototype.hasOwnProperty.call(this, String(key)) ? 1 : 0;
          }],
          ["contains", function _contains(key) {
            return this.has(key);
          }],
          ["exists", function _exists(key) {
            return this.has(key);
          }],
          ["defined", function _defined(key) {
            return this.has(key) && this[String(key)] != null ? 1 : 0;
          }],
          ["get", function _get(key, fallback = null) {
            return this.has(key) ? this[String(key)] : fallback;
          }],
          ["add", function _add(key, inner) {
            this[String(key)] = inner;
            return this;
          }],
          ["set", function _set(key, inner) {
            return this.add(key, inner);
          }],
          [
            "kv",
            function _kv() {
              const out = [];
              for (const key of sortedKeys()) {
                out.push(key, this[key]);
              }
              return out;
            }
          ],
          ["sorted_keys", function _sorted_keys() {
            return sortedKeys();
          }],
          [
            "to_Array",
            function _to_array() {
              return sortedKeys().map(
                (key) => new Pair({ pair: [key, this[key]] })
              );
            }
          ],
          ["to_Iterator", function _to_iterator() {
            return sortedKeys()[Symbol.iterator]();
          }],
          [
            "for_each_key",
            function _for_each_key(fn3) {
              for (const key of sortedKeys()) {
                fn3(key);
              }
              return this;
            }
          ],
          [
            "for_each_value",
            function _for_each_value(fn3) {
              for (const key of sortedKeys()) {
                fn3(this[key]);
              }
              return this;
            }
          ],
          [
            "for_each_pair",
            function _for_each_pair(fn3) {
              for (const key of sortedKeys()) {
                fn3(new Pair({ pair: [key, this[key]] }));
              }
              return this;
            }
          ],
          [
            "remove",
            function _remove(key) {
              delete this[String(key)];
              return this;
            }
          ],
          [
            "clear",
            function _clear() {
              for (const key of Object.keys(this)) {
                delete this[key];
              }
              return this;
            }
          ]
        ]) {
          if (!Object.prototype.hasOwnProperty.call(value, name2)) {
            Object.defineProperty(value, name2, {
              value: fn2,
              enumerable: false,
              configurable: true,
              writable: true
            });
          }
        }
        for (const key of Object.keys(value)) {
          value[key] = decorateValue(value[key]);
        }
        return value;
      }
      var YAML = class {
        constructor(options = {}) {
          const merged = options instanceof PairList ? Object.fromEntries(options.list.map(([key, value]) => [String(key), value])) : options;
          this.pretty = !!merged.pretty;
          this.canonical = !!merged.canonical;
        }
        encode(value) {
          const text = yaml.dump(normalizeValue(value), {
            lineWidth: -1,
            noArrayIndent: true,
            noRefs: true,
            sortKeys: true
          });
          return this.pretty ? text : text.replace(/\n$/u, "");
        }
        encode_binarystring(value) {
          return new BinaryString2(utf8Encoder.encode(this.encode(value)));
        }
        decode(text) {
          const value = yaml.load(String(text));
          return value === void 0 ? null : decorateValue(value);
        }
        decode_binarystring(raw) {
          if (!(raw instanceof BinaryString2)) {
            throw new Error("TypeException: YAML.decode_binarystring expects BinaryString");
          }
          return this.decode(utf8Decoder.decode(raw.bytes));
        }
        dump(pathValue, value) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: YAML.dump expects Path as first argument");
          }
          pathValue.spew(this.encode_binarystring(value));
          return pathValue;
        }
        load(pathValue) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: YAML.load expects Path as first argument");
          }
          return this.decode_binarystring(pathValue.slurp());
        }
      };
      module2.exports = {
        YAML
      };
    }
  });

  // modules/std/data/csv.js
  var require_csv = __commonJS({
    "modules/std/data/csv.js"(exports2, module2) {
      "use strict";
      var { PairList } = require_collections();
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
      var utf8Encoder = new TextEncoder();
      var runtimePolicy2 = {
        deny_fs: false,
        deny_db: false,
        host_name: "node"
      };
      var nodeFs;
      var nodeFsLoaded = false;
      var PathClass;
      var PathClassLoaded = false;
      var DatabaseHandleClass;
      var DatabaseHandleClassLoaded = false;
      function _safeRequire(moduleName) {
        if (typeof __require !== "function") {
          return null;
        }
        try {
          return __require(moduleName);
        } catch (_err) {
          return null;
        }
      }
      function _nodeFs() {
        if (nodeFsLoaded) {
          return nodeFs;
        }
        nodeFsLoaded = true;
        nodeFs = _safeRequire("node:fs");
        return nodeFs;
      }
      function _PathClass() {
        if (PathClassLoaded) {
          return PathClass;
        }
        PathClassLoaded = true;
        const loaded = _safeRequire("../io.js");
        PathClass = loaded && loaded.Path ? loaded.Path : null;
        return PathClass;
      }
      function _DatabaseHandleClass() {
        if (DatabaseHandleClassLoaded) {
          return DatabaseHandleClass;
        }
        DatabaseHandleClassLoaded = true;
        const loaded = _safeRequire("../db.js");
        DatabaseHandleClass = loaded && loaded.DatabaseHandle ? loaded.DatabaseHandle : null;
        return DatabaseHandleClass;
      }
      function assertCapability(capability, message) {
        if (runtimePolicy2[`deny_${capability}`]) {
          throw new Error(message);
        }
      }
      function bool(value) {
        return value ? 1 : 0;
      }
      function isPlainObject2(value) {
        return value != null && typeof value === "object" && !Array.isArray(value) && !(value instanceof PairList);
      }
      function isPath(value) {
        if (value == null || typeof value !== "object") {
          return false;
        }
        const Path = _PathClass();
        return Path ? value instanceof Path : false;
      }
      function isDbHandle(value) {
        if (value == null || typeof value !== "object") {
          return false;
        }
        const DatabaseHandle = _DatabaseHandleClass();
        return DatabaseHandle ? value instanceof DatabaseHandle : false;
      }
      function optionsObject(value) {
        if (value instanceof PairList) {
          return Object.fromEntries(
            value.list.map(([key, inner]) => [String(key), inner])
          );
        }
        if (isPlainObject2(value)) {
          return { ...value };
        }
        return {};
      }
      function arrayValue(value) {
        if (Array.isArray(value)) {
          return value.slice();
        }
        return [];
      }
      function objectValue(value) {
        return isPlainObject2(value) ? { ...value } : {};
      }
      function normalizeConfig(...parts) {
        const out = {};
        for (const part of parts) {
          Object.assign(out, optionsObject(part));
        }
        return out;
      }
      function runtimeConfig(...parts) {
        const config = normalizeConfig(...parts);
        for (const key of ["columns", "required_columns", "sniff_candidates"]) {
          if (key in config) {
            config[key] = arrayValue(config[key]);
          }
        }
        for (const key of [
          "defaults",
          "rename_headers",
          "column_map",
          "column_types",
          "types",
          "parsers",
          "formatters"
        ]) {
          if (key in config) {
            config[key] = objectValue(config[key]);
          }
        }
        return config;
      }
      function columnNamesFromConfig(config) {
        if (Array.isArray(config.columns)) {
          return config.columns.map((name2) => String(name2 ?? ""));
        }
        return null;
      }
      function defaultColumnsForRow(row) {
        const out = [];
        for (let i = 0; i < row.length; i++) {
          out.push(`column${i + 1}`);
        }
        return out;
      }
      function normalizeFieldValue(value, config) {
        if (value === "" && config.blank_is_undef) {
          return null;
        }
        if (value === "" && config.empty_is_undef) {
          return null;
        }
        return value;
      }
      function headerName(raw, config) {
        let value = String(raw ?? "");
        if (config.trim_headers) {
          value = value.trim();
        }
        if (config.lowercase_headers) {
          value = value.toLowerCase();
        }
        if (config.rename_headers && Object.prototype.hasOwnProperty.call(config.rename_headers, value)) {
          value = String(config.rename_headers[value]);
        }
        return value;
      }
      function normalizeHeaders(headers, config) {
        if (!Array.isArray(headers)) {
          return [];
        }
        const seen = /* @__PURE__ */ new Map();
        const out = [];
        const policy = String(config.duplicate_headers || "overwrite").toLowerCase();
        for (const raw of headers) {
          let name2 = headerName(raw, config);
          if (seen.has(name2)) {
            if (policy === "error") {
              throw new Error(`Duplicate CSV header '${name2}'`);
            }
            if (policy === "suffix") {
              const next = seen.get(name2) + 1;
              seen.set(name2, next);
              name2 = `${name2}_${next}`;
            } else {
              seen.set(name2, seen.get(name2) + 1);
            }
          } else {
            seen.set(name2, 1);
          }
          out.push(name2);
        }
        return out;
      }
      function requireColumns(headers, config) {
        const required = arrayValue(config.required_columns);
        if (required.length === 0) {
          return;
        }
        const have = new Set(headers || []);
        for (const name2 of required) {
          if (!have.has(name2)) {
            throw new Error(`Required CSV column '${name2}' missing`);
          }
        }
      }
      function typeForColumn(config, headers, index) {
        const types = config.types;
        if (Array.isArray(types)) {
          return types[index];
        }
        if (isPlainObject2(types) && Array.isArray(headers)) {
          return types[headers[index]];
        }
        return void 0;
      }
      function coerceScalar(value, type) {
        if (type == null) {
          return value;
        }
        const name2 = String(type).toLowerCase();
        if (name2 === "null") {
          return null;
        }
        if (value == null) {
          return name2 === "string" ? "" : null;
        }
        if (name2 === "integer" || name2 === "int") {
          return parseInt(String(value), 10) || 0;
        }
        if (["number", "float", "real"].includes(name2)) {
          return Number(value) || 0;
        }
        if (name2 === "boolean" || name2 === "bool") {
          const text = String(value).toLowerCase();
          if (/^(1|true|yes|on)$/u.test(text)) {
            return 1;
          }
          if (/^(0|false|no|off)?$/u.test(text)) {
            return 0;
          }
          return bool(value);
        }
        return String(value);
      }
      function applyRowRules(row, headers, config, state = {}) {
        const working = row.slice();
        if (Array.isArray(headers)) {
          const expected = headers.length;
          const actual = working.length;
          const ragged = String(config.ragged || "allow").toLowerCase();
          if (actual < expected) {
            if (ragged === "fill") {
              while (working.length < expected) {
                working.push(config.fill_value ?? null);
              }
            } else if (ragged === "error") {
              throw new Error(`CSV row has too few fields at line ${state.line_number ?? "?"}`);
            }
          } else if (actual > expected) {
            if (ragged === "truncate") {
              working.length = expected;
            } else if (ragged === "error") {
              throw new Error(`CSV row has too many fields at line ${state.line_number ?? "?"}`);
            }
          }
        }
        for (let i = 0; i < working.length; i++) {
          working[i] = coerceScalar(
            normalizeFieldValue(working[i], config),
            typeForColumn(config, headers, i)
          );
        }
        if (Array.isArray(headers)) {
          const out = {};
          for (let i = 0; i < headers.length; i++) {
            out[headers[i]] = working[i];
          }
          for (const [key, value] of Object.entries(objectValue(config.defaults))) {
            if (out[key] == null || out[key] === "") {
              out[key] = value;
            }
          }
          if (String(config.unknown_columns || "keep").toLowerCase() === "ignore") {
            const allowed = new Set(headers);
            for (const key of Object.keys(out)) {
              if (!allowed.has(key)) {
                delete out[key];
              }
            }
          }
          return out;
        }
        return working;
      }
      var UnterminatedQuoteError = class extends Error {
      };
      function parseRecord(record, config) {
        const sep = String(config.sep_char ?? ",");
        const quote = String(config.quote_char ?? '"');
        const escape = String(config.escape_char ?? quote);
        const allowWhitespace = !!config.allow_whitespace;
        const row = [];
        let field = "";
        let inQuotes = false;
        let afterQuote = false;
        for (let i = 0; i < record.length; i++) {
          const ch = record[i];
          if (inQuotes) {
            if (ch === quote) {
              if (escape === quote && record[i + 1] === quote) {
                field += quote;
                i++;
              } else {
                inQuotes = false;
                afterQuote = true;
              }
              continue;
            }
            if (escape !== quote && ch === escape && i + 1 < record.length) {
              field += record[i + 1];
              i++;
              continue;
            }
            field += ch;
            continue;
          }
          if (afterQuote) {
            if (ch === sep) {
              row.push(normalizeFieldValue(field, config));
              field = "";
              afterQuote = false;
              continue;
            }
            if (ch === "\n") {
              row.push(normalizeFieldValue(field, config));
              return row;
            }
            if (ch === "\r") {
              continue;
            }
            if (allowWhitespace && /\s/u.test(ch)) {
              continue;
            }
            throw new Error(`unexpected trailing text after closing quote near column ${row.length + 1}`);
          }
          if (ch === sep) {
            row.push(normalizeFieldValue(field, config));
            field = "";
            continue;
          }
          if (ch === quote && field === "") {
            inQuotes = true;
            continue;
          }
          if (ch === "\n") {
            row.push(normalizeFieldValue(field, config));
            return row;
          }
          if (ch === "\r") {
            continue;
          }
          field += ch;
        }
        if (inQuotes) {
          throw new UnterminatedQuoteError("unterminated quoted field");
        }
        row.push(normalizeFieldValue(field, config));
        return row;
      }
      function csvErrorDetail(error, state = {}) {
        const parts = [];
        if (state.line_number != null) {
          parts.push(`line ${state.line_number}`);
        }
        if (state.column_number != null) {
          parts.push(`column ${state.column_number}`);
        }
        if (state.raw_line != null) {
          parts.push(`row ${state.raw_line}`);
        }
        return {
          message: parts.length > 0 ? `${error.message} (${parts.join(", ")})` : error.message,
          line_number: state.line_number ?? null,
          column_number: state.column_number ?? null,
          raw_line: state.raw_line ?? null
        };
      }
      function sourceLinesFromText(text) {
        const source = String(text ?? "");
        let index = 0;
        return function nextLine() {
          if (index >= source.length) {
            return null;
          }
          let end = source.indexOf("\n", index);
          if (end === -1) {
            end = source.length;
          } else {
            end += 1;
          }
          const line = source.slice(index, end);
          index = end;
          return line;
        };
      }
      var FileLineSource = class {
        constructor(target) {
          const fs = _nodeFs();
          if (!fs) {
            throw new Error("CSV file access requires filesystem support");
          }
          this.fd = fs.openSync(target.to_String(), "r");
          this.buffer = "";
          this.eof = false;
        }
        nextLine() {
          const fs = _nodeFs();
          while (true) {
            const idx = this.buffer.indexOf("\n");
            if (idx >= 0) {
              const line = this.buffer.slice(0, idx + 1);
              this.buffer = this.buffer.slice(idx + 1);
              return line;
            }
            if (this.eof) {
              if (this.buffer === "") {
                return null;
              }
              const tail = this.buffer;
              this.buffer = "";
              return tail;
            }
            const chunk = Buffer.allocUnsafe(8192);
            const bytesRead = fs.readSync(this.fd, chunk, 0, chunk.length, null);
            if (bytesRead === 0) {
              this.eof = true;
            } else {
              this.buffer += chunk.toString("utf8", 0, bytesRead);
            }
          }
        }
        close() {
          if (this.fd != null) {
            const fs = _nodeFs();
            fs.closeSync(this.fd);
            this.fd = null;
          }
        }
      };
      var CSVReader = class {
        constructor(target, options = {}) {
          if (!isPath(target)) {
            throw new Error("TypeException: CSV.open expects Path as first argument");
          }
          this.config = runtimeConfig(options);
          this.source = new FileLineSource(target);
          this.headersList = columnNamesFromConfig(this.config);
          this.mode = this.headersList ? "dict" : "array";
          this.lineNumberValue = 0;
          this.rowNumberValue = 0;
          this.errorsList = [];
          this.recordBuffer = "";
          this.recordStartLine = null;
          this.skipRemaining = Number(this.config.skip_lines || 0);
          this.closed = false;
          if (!this.headersList && this.config.headers) {
            const headerRow = this._readNextArray(true);
            this.headersList = normalizeHeaders(headerRow || [], this.config);
            requireColumns(this.headersList, this.config);
            this.mode = "dict";
          } else if (this.headersList) {
            requireColumns(this.headersList, this.config);
          }
        }
        _state() {
          return {
            line_number: this.recordStartLine ?? this.lineNumberValue,
            row_number: this.rowNumberValue,
            raw_line: this.recordBuffer
          };
        }
        _nextPhysicalLine() {
          const line = this.source.nextLine();
          if (line != null) {
            this.lineNumberValue++;
          }
          return line;
        }
        _readNextArray(internal = false) {
          while (true) {
            const line = this._nextPhysicalLine();
            if (line == null) {
              if (this.recordBuffer === "") {
                return null;
              }
              try {
                const finalRow = parseRecord(this.recordBuffer, this.config);
                this.recordBuffer = "";
                return finalRow;
              } catch (error) {
                if (error instanceof UnterminatedQuoteError) {
                  const detail = csvErrorDetail(error, this._state());
                  this.errorsList.push(detail);
                  if (internal || String(this.config.on_error || "die").toLowerCase() !== "collect") {
                    throw new Error(detail.message);
                  }
                  this.recordBuffer = "";
                  return null;
                }
                throw error;
              }
            }
            if (this.recordBuffer === "") {
              if (this.skipRemaining > 0) {
                this.skipRemaining--;
                continue;
              }
              if (this.config.comment_char && line.startsWith(String(this.config.comment_char))) {
                continue;
              }
              if (this.config.skip_empty_rows && /^\s*$/u.test(line)) {
                continue;
              }
              this.recordStartLine = this.lineNumberValue;
            }
            this.recordBuffer += line;
            try {
              const row = parseRecord(this.recordBuffer, this.config);
              this.recordBuffer = "";
              return row;
            } catch (error) {
              if (error instanceof UnterminatedQuoteError) {
                continue;
              }
              const detail = csvErrorDetail(error, this._state());
              this.errorsList.push(detail);
              this.recordBuffer = "";
              if (internal || String(this.config.on_error || "die").toLowerCase() !== "collect") {
                throw new Error(detail.message);
              }
            }
          }
        }
        next_array() {
          while (true) {
            const row = this._readNextArray(false);
            if (row == null) {
              return null;
            }
            const result = applyRowRules(
              row,
              this.headersList,
              this.config,
              {
                line_number: this.recordStartLine,
                row_number: this.rowNumberValue + 1,
                raw_line: this.recordBuffer
              }
            );
            this.rowNumberValue++;
            if (Array.isArray(result)) {
              return result;
            }
            return (this.headersList || []).map((name2) => result[name2]);
          }
        }
        next_dict() {
          if (!Array.isArray(this.headersList) || this.headersList.length === 0) {
            throw new Error("CSVReader.next_dict requires headers or columns");
          }
          const row = this._readNextArray(false);
          if (row == null) {
            return null;
          }
          this.rowNumberValue++;
          const result = applyRowRules(
            row,
            this.headersList,
            this.config,
            {
              line_number: this.recordStartLine,
              row_number: this.rowNumberValue,
              raw_line: this.recordBuffer
            }
          );
          return Array.isArray(result) ? Object.fromEntries(this.headersList.map((name2, index) => [name2, result[index]])) : result;
        }
        next() {
          return this.mode === "dict" ? this.next_dict() : this.next_array();
        }
        all_array() {
          const out = [];
          let row;
          while ((row = this.next_array()) !== null) {
            out.push(row);
          }
          return out;
        }
        all_dict() {
          const out = [];
          let row;
          while ((row = this.next_dict()) !== null) {
            out.push(row);
          }
          return out;
        }
        headers() {
          return this.headersList ? this.headersList.slice() : null;
        }
        columns() {
          return this.headers();
        }
        set_columns(columns) {
          this.headersList = arrayValue(columns).map((name2) => String(name2));
          this.mode = "dict";
          return this.headers();
        }
        row_number() {
          return this.rowNumberValue;
        }
        skip_lines(count) {
          let skipped = 0;
          while (skipped < Number(count || 0)) {
            if (this._nextPhysicalLine() == null) {
              break;
            }
            skipped++;
          }
          return skipped;
        }
        errors() {
          return this.errorsList.slice();
        }
        close() {
          if (!this.closed) {
            this.closed = true;
            this.source.close();
          }
          return 1;
        }
        *[Symbol.iterator]() {
          let row;
          while ((row = this.next()) !== null) {
            yield row;
          }
        }
        to_Iterator() {
          return this[Symbol.iterator]();
        }
      };
      function outputColumnsFromRows(rows, config) {
        const configured = columnNamesFromConfig(config);
        if (configured && configured.length > 0) {
          return configured;
        }
        for (const row of rows) {
          if (Array.isArray(row)) {
            return config.headers ? defaultColumnsForRow(row) : null;
          }
          if (isPlainObject2(row)) {
            const keys = Object.keys(row);
            if (config.sort_columns) {
              keys.sort((left, right) => left.localeCompare(right));
            }
            return keys;
          }
        }
        return null;
      }
      function formatOutputRow(row, columns) {
        if (Array.isArray(row)) {
          return row.slice();
        }
        if (isPlainObject2(row)) {
          return (columns || Object.keys(row)).map((name2) => row[name2]);
        }
        return [row];
      }
      function encodeCell(value, config) {
        if (value == null) {
          return "";
        }
        const sep = String(config.sep_char ?? ",");
        const quote = String(config.quote_char ?? '"');
        const escape = String(config.escape_char ?? quote);
        let text = String(value);
        const needsQuote = config.always_quote || text.includes(sep) || text.includes("\n") || text.includes("\r") || text.includes(quote) || config.quote_space && /^\s|\s$/u.test(text) || config.quote_empty && text === "";
        if (!needsQuote) {
          return text;
        }
        if (escape === quote) {
          text = text.replaceAll(quote, quote + quote);
        } else {
          text = text.replaceAll(escape, escape + escape);
          text = text.replaceAll(quote, escape + quote);
        }
        return `${quote}${text}${quote}`;
      }
      function quotedIdentifier(name2) {
        return `"${String(name2).replaceAll('"', '""')}"`;
      }
      var CSVWriter = class {
        constructor(target, options = {}) {
          if (!isPath(target)) {
            throw new Error("TypeException: CSV.open_writer expects Path as first argument");
          }
          const fs = _nodeFs();
          if (!fs) {
            throw new Error("CSV file access requires filesystem support");
          }
          this.config = runtimeConfig(options);
          this.columnsList = columnNamesFromConfig(this.config);
          this.rowNumberValue = 0;
          this.wroteHeader = !!this.config.append;
          const flag = this.config.append ? "a" : "w";
          this.fd = fs.openSync(target.to_String(), flag);
          this.closed = false;
        }
        _writeText(text) {
          const fs = _nodeFs();
          fs.writeSync(this.fd, text, null, "utf8");
        }
        columns() {
          return this.columnsList ? this.columnsList.slice() : null;
        }
        write_header(columns = null) {
          if (columns != null) {
            this.columnsList = arrayValue(columns).map((name2) => String(name2));
          }
          if (!Array.isArray(this.columnsList)) {
            this.columnsList = [];
          }
          this._writeText(
            this.columnsList.map((value) => encodeCell(value, this.config)).join(String(this.config.sep_char ?? ",")) + String(this.config.eol ?? "\n")
          );
          this.wroteHeader = true;
          return this.columns();
        }
        write_row(row) {
          if (this.closed) {
            throw new Error("CSVWriter is closed");
          }
          if (!this.columnsList) {
            if (Array.isArray(row) && this.config.headers) {
              this.columnsList = defaultColumnsForRow(row);
            } else if (isPlainObject2(row)) {
              this.columnsList = Object.keys(row);
              if (this.config.sort_columns) {
                this.columnsList.sort((left, right) => left.localeCompare(right));
              }
            }
          }
          if (this.config.headers && !this.wroteHeader && this.columnsList) {
            this.write_header(this.columnsList);
          }
          const fields = formatOutputRow(row, this.columnsList);
          this._writeText(
            fields.map((value) => encodeCell(value, this.config)).join(String(this.config.sep_char ?? ",")) + String(this.config.eol ?? "\n")
          );
          this.rowNumberValue++;
          return fields;
        }
        print_row(row) {
          return this.write_row(row);
        }
        row_number() {
          return this.rowNumberValue;
        }
        close() {
          if (!this.closed) {
            this.closed = true;
            const fs = _nodeFs();
            fs.closeSync(this.fd);
          }
          return 1;
        }
      };
      function sniffCounts(text, char) {
        return String(text ?? "").split(/\r?\n/u).filter((line) => line !== "").slice(0, 5).reduce((count, line) => count + (line.split(char).length - 1), 0);
      }
      function sniffText(source, config = {}) {
        const candidates = arrayValue(config.sniff_candidates);
        const chars = candidates.length > 0 ? candidates : [",", "	", ";", "|"];
        let best = chars[0];
        let bestScore = -1;
        for (const char of chars) {
          const score = sniffCounts(source, char);
          if (score > bestScore) {
            bestScore = score;
            best = char;
          }
        }
        const first = String(source ?? "").split(/\r?\n/u).find((line) => /\S/u.test(line)) || "";
        let headers = 0;
        if (first !== "") {
          const parts = first.split(best);
          headers = parts.length > 0 && parts.every((part) => !/^-?(?:\d+(?:\.\d+)?)$/u.test(part)) ? 1 : 0;
        }
        return {
          sep_char: best,
          headers,
          quote_char: '"'
        };
      }
      var CSV = class _CSV {
        constructor(options = {}) {
          this.config = runtimeConfig(options);
        }
        sniff(source) {
          if (isPath(source)) {
            assertCapability("fs", "CSV.sniff is denied by runtime policy");
            return this.sniff_binarystring(source.slurp());
          }
          return sniffText(source, this.config);
        }
        sniff_binarystring(source) {
          if (!(source instanceof BinaryString2)) {
            throw new Error("TypeException: CSV.sniff_binarystring expects BinaryString");
          }
          return sniffText(utf8Decoder.decode(source.bytes), this.config);
        }
        transpose(rows) {
          const matrix = Array.isArray(rows) ? rows : [];
          let max = 0;
          for (const row of matrix) {
            max = Math.max(max, Array.isArray(row) ? row.length : 1);
          }
          const out = [];
          for (let i = 0; i < max; i++) {
            const next = [];
            for (const row of matrix) {
              next.push(Array.isArray(row) ? row[i] : i === 0 ? row : null);
            }
            out.push(next);
          }
          return out;
        }
        decode(text) {
          const report = this.decode_report(text);
          if (report.errors.length > 0 && String(this.config.on_error || "die").toLowerCase() !== "collect") {
            throw new Error(report.errors[0].message);
          }
          return report.rows;
        }
        decode_binarystring(raw) {
          if (!(raw instanceof BinaryString2)) {
            throw new Error("TypeException: CSV.decode_binarystring expects BinaryString");
          }
          return this.decode(utf8Decoder.decode(raw.bytes));
        }
        decode_report(text) {
          const config = runtimeConfig(this.config, { on_error: "collect" });
          const rows = [];
          const errors = [];
          const nextLine = sourceLinesFromText(text);
          let headers = columnNamesFromConfig(config);
          let lineNumber = 0;
          let rowNumber = 0;
          let buffer = "";
          let recordStartLine = null;
          let skipRemaining = Number(config.skip_lines || 0);
          while (true) {
            const line = nextLine();
            if (line == null) {
              break;
            }
            lineNumber++;
            if (buffer === "") {
              if (skipRemaining > 0) {
                skipRemaining--;
                continue;
              }
              if (config.comment_char && line.startsWith(String(config.comment_char))) {
                continue;
              }
              if (config.skip_empty_rows && /^\s*$/u.test(line)) {
                continue;
              }
              recordStartLine = lineNumber;
            }
            buffer += line;
            let row;
            try {
              row = parseRecord(buffer, config);
            } catch (error) {
              if (error instanceof UnterminatedQuoteError) {
                continue;
              }
              errors.push(
                csvErrorDetail(
                  error,
                  {
                    line_number: recordStartLine,
                    row_number: rowNumber + 1,
                    raw_line: buffer
                  }
                )
              );
              buffer = "";
              break;
            }
            buffer = "";
            if (!headers && config.headers) {
              headers = normalizeHeaders(row, config);
              requireColumns(headers, config);
              continue;
            }
            try {
              rowNumber++;
              rows.push(
                applyRowRules(
                  row,
                  headers,
                  config,
                  {
                    line_number: recordStartLine,
                    row_number: rowNumber,
                    raw_line: line
                  }
                )
              );
            } catch (error) {
              errors.push(
                csvErrorDetail(
                  error,
                  {
                    line_number: recordStartLine,
                    row_number: rowNumber,
                    raw_line: line
                  }
                )
              );
              buffer = "";
            }
          }
          if (buffer !== "") {
            try {
              const row = parseRecord(buffer, config);
              if (!headers && config.headers) {
                headers = normalizeHeaders(row, config);
                requireColumns(headers, config);
              } else {
                rowNumber++;
                rows.push(
                  applyRowRules(
                    row,
                    headers,
                    config,
                    {
                      line_number: recordStartLine,
                      row_number: rowNumber,
                      raw_line: buffer
                    }
                  )
                );
              }
            } catch (error) {
              errors.push(
                csvErrorDetail(
                  error,
                  {
                    line_number: recordStartLine,
                    row_number: rowNumber + 1,
                    raw_line: buffer
                  }
                )
              );
            }
          }
          return { rows, errors };
        }
        decode_report_binarystring(raw) {
          if (!(raw instanceof BinaryString2)) {
            throw new Error(
              "TypeException: CSV.decode_report_binarystring expects BinaryString"
            );
          }
          return this.decode_report(utf8Decoder.decode(raw.bytes));
        }
        encode(rows) {
          const input = Array.isArray(rows) ? rows : [];
          const columns = outputColumnsFromRows(input, this.config);
          const lines = [];
          if (this.config.headers && columns) {
            lines.push(this.encode_row(columns).replace(/\n$/u, ""));
          }
          for (const row of input) {
            lines.push(
              formatOutputRow(row, columns).map((value) => encodeCell(value, this.config)).join(String(this.config.sep_char ?? ","))
            );
          }
          return lines.join(String(this.config.eol ?? "\n")) + (lines.length > 0 ? String(this.config.eol ?? "\n") : "");
        }
        encode_binarystring(rows) {
          return new BinaryString2(utf8Encoder.encode(this.encode(rows)));
        }
        encode_row(row) {
          const fields = formatOutputRow(row, null);
          return fields.map((value) => encodeCell(value, this.config)).join(String(this.config.sep_char ?? ",")) + String(this.config.eol ?? "\n");
        }
        encode_row_binarystring(row) {
          return new BinaryString2(utf8Encoder.encode(this.encode_row(row)));
        }
        load(pathValue) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.load expects Path as first argument");
          }
          assertCapability("fs", "CSV.load is denied by runtime policy");
          return this.decode_binarystring(pathValue.slurp());
        }
        load_report(pathValue) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.load_report expects Path as first argument");
          }
          assertCapability("fs", "CSV.load_report is denied by runtime policy");
          return this.decode_report_binarystring(pathValue.slurp());
        }
        dump(pathValue, rows) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.dump expects Path as first argument");
          }
          assertCapability("fs", "CSV.dump is denied by runtime policy");
          pathValue.spew(this.encode_binarystring(rows));
          return pathValue;
        }
        open(pathValue) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.open expects Path as first argument");
          }
          assertCapability("fs", "CSV.open is denied by runtime policy");
          return new CSVReader(pathValue, this.config);
        }
        open_writer(pathValue, options = {}) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.open_writer expects Path as first argument");
          }
          assertCapability("fs", "CSV.open_writer is denied by runtime policy");
          return new CSVWriter(pathValue, normalizeConfig(this.config, options));
        }
        dump_query(pathValue, dbh, sql, bind = [], options = {}) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.dump_query expects Path as first argument");
          }
          if (!isDbHandle(dbh)) {
            throw new Error("TypeException: CSV.dump_query expects DatabaseHandle");
          }
          assertCapability("fs", "CSV.dump_query is denied by runtime policy");
          assertCapability("db", "CSV.dump_query is denied by runtime policy");
          const stmt = dbh.prepare(String(sql));
          stmt.execute(...Array.isArray(bind) ? bind : []);
          const rows = stmt.all_dict();
          const config = normalizeConfig(this.config, { headers: true }, options);
          return new _CSV(config).dump(pathValue, rows);
        }
        dump_table(pathValue, dbh, table, options = {}) {
          return this.dump_query(
            pathValue,
            dbh,
            `select * from ${quotedIdentifier(table)}`,
            [],
            normalizeConfig({ headers: true }, options)
          );
        }
        load_table(pathValue, dbh, table, options = {}) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: CSV.load_table expects Path as first argument");
          }
          if (!isDbHandle(dbh)) {
            throw new Error("TypeException: CSV.load_table expects DatabaseHandle");
          }
          assertCapability("fs", "CSV.load_table is denied by runtime policy");
          assertCapability("db", "CSV.load_table is denied by runtime policy");
          const config = normalizeConfig(this.config, options);
          const reader = new _CSV(config).open(pathValue);
          let sourceColumns = reader.columns();
          let firstRow = sourceColumns ? reader.next_dict() : reader.next_array();
          if (firstRow == null) {
            reader.close();
            return 0;
          }
          if (!sourceColumns) {
            sourceColumns = Array.isArray(firstRow) ? defaultColumnsForRow(firstRow) : Object.keys(firstRow);
            reader.set_columns(sourceColumns);
            if (Array.isArray(firstRow)) {
              firstRow = Object.fromEntries(
                sourceColumns.map((name2, index) => [name2, firstRow[index]])
              );
            }
          }
          const targetColumns = sourceColumns.map(
            (name2) => config.column_map && Object.prototype.hasOwnProperty.call(config.column_map, name2) ? config.column_map[name2] : name2
          );
          if (config.create_table) {
            if (String(config.if_exists || "append").toLowerCase() === "replace") {
              dbh.prepare(`drop table if exists ${quotedIdentifier(table)}`).execute();
            }
            const defs = targetColumns.map((name2, index) => {
              let type = "TEXT";
              if (Array.isArray(config.column_types)) {
                type = String(config.column_types[index] || "TEXT");
              } else if (isPlainObject2(config.column_types)) {
                type = String(config.column_types[name2] || "TEXT");
              }
              return `${quotedIdentifier(name2)} ${type}`;
            });
            const ifNotExists = String(config.if_exists || "append").toLowerCase() === "append" ? " if not exists" : "";
            dbh.prepare(
              `create table${ifNotExists} ${quotedIdentifier(table)} (${defs.join(", ")})`
            ).execute();
          }
          const conflict = String(config.conflict || "").trim();
          const insertPrefix = conflict === "" || conflict.toLowerCase() === "default" ? "insert" : `insert or ${conflict.toUpperCase()}`;
          const placeholders = targetColumns.map(() => "?").join(", ");
          const stmt = dbh.prepare(
            `${insertPrefix} into ${quotedIdentifier(table)} (${targetColumns.map(quotedIdentifier).join(", ")}) values (${placeholders})`
          );
          const transactionEnabled = config.transaction !== false;
          const commitInterval = Number(config.commit_interval || 0);
          let count = 0;
          if (transactionEnabled) {
            dbh.begin();
          }
          try {
            const writeRow = (row2) => {
              const dict = Array.isArray(row2) ? Object.fromEntries(sourceColumns.map((name2, index) => [name2, row2[index]])) : row2;
              const values = sourceColumns.map((name2) => dict[name2]);
              stmt.execute(...values);
              count++;
              if (transactionEnabled && commitInterval > 0 && count % commitInterval === 0) {
                dbh.commit();
                dbh.begin();
              }
            };
            writeRow(firstRow);
            let row;
            while ((row = reader.next_dict()) !== null) {
              writeRow(row);
            }
            if (transactionEnabled) {
              dbh.commit();
            }
          } catch (error) {
            if (transactionEnabled) {
              dbh.rollback();
            }
            reader.close();
            throw error;
          }
          reader.close();
          return count;
        }
      };
      module2.exports = {
        CSV,
        CSVReader,
        CSVWriter,
        __zuzu_set_runtime_policy(policy = {}) {
          runtimePolicy2 = { ...runtimePolicy2, ...policy };
        }
      };
    }
  });

  // node_modules/@xmldom/xmldom/lib/conventions.js
  var require_conventions = __commonJS({
    "node_modules/@xmldom/xmldom/lib/conventions.js"(exports2) {
      "use strict";
      function find(list, predicate, ac) {
        if (ac === void 0) {
          ac = Array.prototype;
        }
        if (list && typeof ac.find === "function") {
          return ac.find.call(list, predicate);
        }
        for (var i = 0; i < list.length; i++) {
          if (hasOwn(list, i)) {
            var item = list[i];
            if (predicate.call(void 0, item, i, list)) {
              return item;
            }
          }
        }
      }
      function freeze(object, oc) {
        if (oc === void 0) {
          oc = Object;
        }
        if (oc && typeof oc.getOwnPropertyDescriptors === "function") {
          object = oc.create(null, oc.getOwnPropertyDescriptors(object));
        }
        return oc && typeof oc.freeze === "function" ? oc.freeze(object) : object;
      }
      function hasOwn(object, key) {
        return Object.prototype.hasOwnProperty.call(object, key);
      }
      function assign(target, source) {
        if (target === null || typeof target !== "object") {
          throw new TypeError("target is not an object");
        }
        for (var key in source) {
          if (hasOwn(source, key)) {
            target[key] = source[key];
          }
        }
        return target;
      }
      var HTML_BOOLEAN_ATTRIBUTES = freeze({
        allowfullscreen: true,
        async: true,
        autofocus: true,
        autoplay: true,
        checked: true,
        controls: true,
        default: true,
        defer: true,
        disabled: true,
        formnovalidate: true,
        hidden: true,
        ismap: true,
        itemscope: true,
        loop: true,
        multiple: true,
        muted: true,
        nomodule: true,
        novalidate: true,
        open: true,
        playsinline: true,
        readonly: true,
        required: true,
        reversed: true,
        selected: true
      });
      function isHTMLBooleanAttribute(name2) {
        return hasOwn(HTML_BOOLEAN_ATTRIBUTES, name2.toLowerCase());
      }
      var HTML_VOID_ELEMENTS = freeze({
        area: true,
        base: true,
        br: true,
        col: true,
        embed: true,
        hr: true,
        img: true,
        input: true,
        link: true,
        meta: true,
        param: true,
        source: true,
        track: true,
        wbr: true
      });
      function isHTMLVoidElement(tagName) {
        return hasOwn(HTML_VOID_ELEMENTS, tagName.toLowerCase());
      }
      var HTML_RAW_TEXT_ELEMENTS = freeze({
        script: false,
        style: false,
        textarea: true,
        title: true
      });
      function isHTMLRawTextElement(tagName) {
        var key = tagName.toLowerCase();
        return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && !HTML_RAW_TEXT_ELEMENTS[key];
      }
      function isHTMLEscapableRawTextElement(tagName) {
        var key = tagName.toLowerCase();
        return hasOwn(HTML_RAW_TEXT_ELEMENTS, key) && HTML_RAW_TEXT_ELEMENTS[key];
      }
      function isHTMLMimeType(mimeType) {
        return mimeType === MIME_TYPE.HTML;
      }
      function hasDefaultHTMLNamespace(mimeType) {
        return isHTMLMimeType(mimeType) || mimeType === MIME_TYPE.XML_XHTML_APPLICATION;
      }
      var MIME_TYPE = freeze({
        /**
         * `text/html`, the only mime type that triggers treating an XML document as HTML.
         *
         * @see https://www.iana.org/assignments/media-types/text/html IANA MimeType registration
         * @see https://en.wikipedia.org/wiki/HTML Wikipedia
         * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString MDN
         * @see https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
         *      WHATWG HTML Spec
         */
        HTML: "text/html",
        /**
         * `application/xml`, the standard mime type for XML documents.
         *
         * @see https://www.iana.org/assignments/media-types/application/xml IANA MimeType
         *      registration
         * @see https://tools.ietf.org/html/rfc7303#section-9.1 RFC 7303
         * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
         */
        XML_APPLICATION: "application/xml",
        /**
         * `text/xml`, an alias for `application/xml`.
         *
         * @see https://tools.ietf.org/html/rfc7303#section-9.2 RFC 7303
         * @see https://www.iana.org/assignments/media-types/text/xml IANA MimeType registration
         * @see https://en.wikipedia.org/wiki/XML_and_MIME Wikipedia
         */
        XML_TEXT: "text/xml",
        /**
         * `application/xhtml+xml`, indicates an XML document that has the default HTML namespace,
         * but is parsed as an XML document.
         *
         * @see https://www.iana.org/assignments/media-types/application/xhtml+xml IANA MimeType
         *      registration
         * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument WHATWG DOM Spec
         * @see https://en.wikipedia.org/wiki/XHTML Wikipedia
         */
        XML_XHTML_APPLICATION: "application/xhtml+xml",
        /**
         * `image/svg+xml`,
         *
         * @see https://www.iana.org/assignments/media-types/image/svg+xml IANA MimeType registration
         * @see https://www.w3.org/TR/SVG11/ W3C SVG 1.1
         * @see https://en.wikipedia.org/wiki/Scalable_Vector_Graphics Wikipedia
         */
        XML_SVG_IMAGE: "image/svg+xml"
      });
      var _MIME_TYPES = Object.keys(MIME_TYPE).map(function(key) {
        return MIME_TYPE[key];
      });
      function isValidMimeType(mimeType) {
        return _MIME_TYPES.indexOf(mimeType) > -1;
      }
      var NAMESPACE = freeze({
        /**
         * The XHTML namespace.
         *
         * @see http://www.w3.org/1999/xhtml
         */
        HTML: "http://www.w3.org/1999/xhtml",
        /**
         * The SVG namespace.
         *
         * @see http://www.w3.org/2000/svg
         */
        SVG: "http://www.w3.org/2000/svg",
        /**
         * The `xml:` namespace.
         *
         * @see http://www.w3.org/XML/1998/namespace
         */
        XML: "http://www.w3.org/XML/1998/namespace",
        /**
         * The `xmlns:` namespace.
         *
         * @see https://www.w3.org/2000/xmlns/
         */
        XMLNS: "http://www.w3.org/2000/xmlns/"
      });
      exports2.assign = assign;
      exports2.find = find;
      exports2.freeze = freeze;
      exports2.HTML_BOOLEAN_ATTRIBUTES = HTML_BOOLEAN_ATTRIBUTES;
      exports2.HTML_RAW_TEXT_ELEMENTS = HTML_RAW_TEXT_ELEMENTS;
      exports2.HTML_VOID_ELEMENTS = HTML_VOID_ELEMENTS;
      exports2.hasDefaultHTMLNamespace = hasDefaultHTMLNamespace;
      exports2.hasOwn = hasOwn;
      exports2.isHTMLBooleanAttribute = isHTMLBooleanAttribute;
      exports2.isHTMLRawTextElement = isHTMLRawTextElement;
      exports2.isHTMLEscapableRawTextElement = isHTMLEscapableRawTextElement;
      exports2.isHTMLMimeType = isHTMLMimeType;
      exports2.isHTMLVoidElement = isHTMLVoidElement;
      exports2.isValidMimeType = isValidMimeType;
      exports2.MIME_TYPE = MIME_TYPE;
      exports2.NAMESPACE = NAMESPACE;
    }
  });

  // node_modules/@xmldom/xmldom/lib/errors.js
  var require_errors2 = __commonJS({
    "node_modules/@xmldom/xmldom/lib/errors.js"(exports2) {
      "use strict";
      var conventions = require_conventions();
      function extendError(constructor, writableName) {
        constructor.prototype = Object.create(Error.prototype, {
          constructor: { value: constructor },
          name: { value: constructor.name, enumerable: true, writable: writableName }
        });
      }
      var DOMExceptionName = conventions.freeze({
        /**
         * the default value as defined by the spec
         */
        Error: "Error",
        /**
         * @deprecated
         * Use RangeError instead.
         */
        IndexSizeError: "IndexSizeError",
        /**
         * @deprecated
         * Just to match the related static code, not part of the spec.
         */
        DomstringSizeError: "DomstringSizeError",
        HierarchyRequestError: "HierarchyRequestError",
        WrongDocumentError: "WrongDocumentError",
        InvalidCharacterError: "InvalidCharacterError",
        /**
         * @deprecated
         * Just to match the related static code, not part of the spec.
         */
        NoDataAllowedError: "NoDataAllowedError",
        NoModificationAllowedError: "NoModificationAllowedError",
        NotFoundError: "NotFoundError",
        NotSupportedError: "NotSupportedError",
        InUseAttributeError: "InUseAttributeError",
        InvalidStateError: "InvalidStateError",
        SyntaxError: "SyntaxError",
        InvalidModificationError: "InvalidModificationError",
        NamespaceError: "NamespaceError",
        /**
         * @deprecated
         * Use TypeError for invalid arguments,
         * "NotSupportedError" DOMException for unsupported operations,
         * and "NotAllowedError" DOMException for denied requests instead.
         */
        InvalidAccessError: "InvalidAccessError",
        /**
         * @deprecated
         * Just to match the related static code, not part of the spec.
         */
        ValidationError: "ValidationError",
        /**
         * @deprecated
         * Use TypeError instead.
         */
        TypeMismatchError: "TypeMismatchError",
        SecurityError: "SecurityError",
        NetworkError: "NetworkError",
        AbortError: "AbortError",
        /**
         * @deprecated
         * Just to match the related static code, not part of the spec.
         */
        URLMismatchError: "URLMismatchError",
        QuotaExceededError: "QuotaExceededError",
        TimeoutError: "TimeoutError",
        InvalidNodeTypeError: "InvalidNodeTypeError",
        DataCloneError: "DataCloneError",
        EncodingError: "EncodingError",
        NotReadableError: "NotReadableError",
        UnknownError: "UnknownError",
        ConstraintError: "ConstraintError",
        DataError: "DataError",
        TransactionInactiveError: "TransactionInactiveError",
        ReadOnlyError: "ReadOnlyError",
        VersionError: "VersionError",
        OperationError: "OperationError",
        NotAllowedError: "NotAllowedError",
        OptOutError: "OptOutError"
      });
      var DOMExceptionNames = Object.keys(DOMExceptionName);
      function isValidDomExceptionCode(value) {
        return typeof value === "number" && value >= 1 && value <= 25;
      }
      function endsWithError(value) {
        return typeof value === "string" && value.substring(value.length - DOMExceptionName.Error.length) === DOMExceptionName.Error;
      }
      function DOMException(messageOrCode, nameOrMessage) {
        if (isValidDomExceptionCode(messageOrCode)) {
          this.name = DOMExceptionNames[messageOrCode];
          this.message = nameOrMessage || "";
        } else {
          this.message = messageOrCode;
          this.name = endsWithError(nameOrMessage) ? nameOrMessage : DOMExceptionName.Error;
        }
        if (Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
      }
      extendError(DOMException, true);
      Object.defineProperties(DOMException.prototype, {
        code: {
          enumerable: true,
          get: function() {
            var code = DOMExceptionNames.indexOf(this.name);
            if (isValidDomExceptionCode(code)) return code;
            return 0;
          }
        }
      });
      var ExceptionCode = {
        INDEX_SIZE_ERR: 1,
        DOMSTRING_SIZE_ERR: 2,
        HIERARCHY_REQUEST_ERR: 3,
        WRONG_DOCUMENT_ERR: 4,
        INVALID_CHARACTER_ERR: 5,
        NO_DATA_ALLOWED_ERR: 6,
        NO_MODIFICATION_ALLOWED_ERR: 7,
        NOT_FOUND_ERR: 8,
        NOT_SUPPORTED_ERR: 9,
        INUSE_ATTRIBUTE_ERR: 10,
        INVALID_STATE_ERR: 11,
        SYNTAX_ERR: 12,
        INVALID_MODIFICATION_ERR: 13,
        NAMESPACE_ERR: 14,
        INVALID_ACCESS_ERR: 15,
        VALIDATION_ERR: 16,
        TYPE_MISMATCH_ERR: 17,
        SECURITY_ERR: 18,
        NETWORK_ERR: 19,
        ABORT_ERR: 20,
        URL_MISMATCH_ERR: 21,
        QUOTA_EXCEEDED_ERR: 22,
        TIMEOUT_ERR: 23,
        INVALID_NODE_TYPE_ERR: 24,
        DATA_CLONE_ERR: 25
      };
      var entries = Object.entries(ExceptionCode);
      for (i = 0; i < entries.length; i++) {
        key = entries[i][0];
        DOMException[key] = entries[i][1];
      }
      var key;
      var i;
      function ParseError(message, locator) {
        this.message = message;
        this.locator = locator;
        if (Error.captureStackTrace) Error.captureStackTrace(this, ParseError);
      }
      extendError(ParseError);
      exports2.DOMException = DOMException;
      exports2.DOMExceptionName = DOMExceptionName;
      exports2.ExceptionCode = ExceptionCode;
      exports2.ParseError = ParseError;
    }
  });

  // node_modules/@xmldom/xmldom/lib/grammar.js
  var require_grammar = __commonJS({
    "node_modules/@xmldom/xmldom/lib/grammar.js"(exports2) {
      "use strict";
      function detectUnicodeSupport(RegExpImpl) {
        try {
          if (typeof RegExpImpl !== "function") {
            RegExpImpl = RegExp;
          }
          var match = new RegExpImpl("\u{1D306}", "u").exec("\u{1D306}");
          return !!match && match[0].length === 2;
        } catch (error) {
        }
        return false;
      }
      var UNICODE_SUPPORT = detectUnicodeSupport();
      function chars(regexp) {
        if (regexp.source[0] !== "[") {
          throw new Error(regexp + " can not be used with chars");
        }
        return regexp.source.slice(1, regexp.source.lastIndexOf("]"));
      }
      function chars_without(regexp, search) {
        if (regexp.source[0] !== "[") {
          throw new Error("/" + regexp.source + "/ can not be used with chars_without");
        }
        if (!search || typeof search !== "string") {
          throw new Error(JSON.stringify(search) + " is not a valid search");
        }
        if (regexp.source.indexOf(search) === -1) {
          throw new Error('"' + search + '" is not is /' + regexp.source + "/");
        }
        if (search === "-" && regexp.source.indexOf(search) !== 1) {
          throw new Error('"' + search + '" is not at the first postion of /' + regexp.source + "/");
        }
        return new RegExp(regexp.source.replace(search, ""), UNICODE_SUPPORT ? "u" : "");
      }
      function reg(args) {
        var self = this;
        return new RegExp(
          Array.prototype.slice.call(arguments).map(function(part) {
            var isStr = typeof part === "string";
            if (isStr && self === void 0 && part === "|") {
              throw new Error("use regg instead of reg to wrap expressions with `|`!");
            }
            return isStr ? part : part.source;
          }).join(""),
          UNICODE_SUPPORT ? "mu" : "m"
        );
      }
      function regg(args) {
        if (arguments.length === 0) {
          throw new Error("no parameters provided");
        }
        return reg.apply(regg, ["(?:"].concat(Array.prototype.slice.call(arguments), [")"]));
      }
      var UNICODE_REPLACEMENT_CHARACTER = "\uFFFD";
      var Char = /[-\x09\x0A\x0D\x20-\x2C\x2E-\uD7FF\uE000-\uFFFD]/;
      if (UNICODE_SUPPORT) {
        Char = reg("[", chars(Char), "\\u{10000}-\\u{10FFFF}", "]");
      }
      var InvalidChar = new RegExp("[^" + chars(Char) + "]", UNICODE_SUPPORT ? "u" : "");
      var _SChar = /[\x20\x09\x0D\x0A]/;
      var SChar_s = chars(_SChar);
      var S = reg(_SChar, "+");
      var S_OPT = reg(_SChar, "*");
      var NameStartChar = /[:_a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;
      if (UNICODE_SUPPORT) {
        NameStartChar = reg("[", chars(NameStartChar), "\\u{10000}-\\u{10FFFF}", "]");
      }
      var NameStartChar_s = chars(NameStartChar);
      var NameChar = reg("[", NameStartChar_s, chars(/[-.0-9\xB7]/), chars(/[\u0300-\u036F\u203F-\u2040]/), "]");
      var Name = reg(NameStartChar, NameChar, "*");
      var Nmtoken = reg(NameChar, "+");
      var EntityRef = reg("&", Name, ";");
      var CharRef = regg(/&#[0-9]+;|&#x[0-9a-fA-F]+;/);
      var Reference = regg(EntityRef, "|", CharRef);
      var PEReference = reg("%", Name, ";");
      var EntityValue = regg(
        reg('"', regg(/[^%&"]/, "|", PEReference, "|", Reference), "*", '"'),
        "|",
        reg("'", regg(/[^%&']/, "|", PEReference, "|", Reference), "*", "'")
      );
      var AttValue = regg('"', regg(/[^<&"]/, "|", Reference), "*", '"', "|", "'", regg(/[^<&']/, "|", Reference), "*", "'");
      var NCNameStartChar = chars_without(NameStartChar, ":");
      var NCNameChar = chars_without(NameChar, ":");
      var NCName = reg(NCNameStartChar, NCNameChar, "*");
      var QName = reg(NCName, regg(":", NCName), "?");
      var QName_exact = reg("^", QName, "$");
      var QName_group = reg("(", QName, ")");
      var SystemLiteral = regg(/"[^"]*"|'[^']*'/);
      var PI = reg(/^<\?/, "(", Name, ")", regg(S, "(", Char, "*?)"), "?", /\?>/);
      var PubidChar = /[\x20\x0D\x0Aa-zA-Z0-9-'()+,./:=?;!*#@$_%]/;
      var PubidLiteral = regg('"', PubidChar, '*"', "|", "'", chars_without(PubidChar, "'"), "*'");
      var COMMENT_START = "<!--";
      var COMMENT_END = "-->";
      var Comment = reg(COMMENT_START, regg(chars_without(Char, "-"), "|", reg("-", chars_without(Char, "-"))), "*", COMMENT_END);
      var PCDATA = "#PCDATA";
      var Mixed = regg(
        reg(/\(/, S_OPT, PCDATA, regg(S_OPT, /\|/, S_OPT, QName), "*", S_OPT, /\)\*/),
        "|",
        reg(/\(/, S_OPT, PCDATA, S_OPT, /\)/)
      );
      var _children_quantity = /[?*+]?/;
      var children = reg(
        /\([^>]+\)/,
        _children_quantity
        /*regg(choice, '|', seq), _children_quantity*/
      );
      var contentspec = regg("EMPTY", "|", "ANY", "|", Mixed, "|", children);
      var ELEMENTDECL_START = "<!ELEMENT";
      var elementdecl = reg(ELEMENTDECL_START, S, regg(QName, "|", PEReference), S, regg(contentspec, "|", PEReference), S_OPT, ">");
      var NotationType = reg("NOTATION", S, /\(/, S_OPT, Name, regg(S_OPT, /\|/, S_OPT, Name), "*", S_OPT, /\)/);
      var Enumeration = reg(/\(/, S_OPT, Nmtoken, regg(S_OPT, /\|/, S_OPT, Nmtoken), "*", S_OPT, /\)/);
      var EnumeratedType = regg(NotationType, "|", Enumeration);
      var AttType = regg(/CDATA|ID|IDREF|IDREFS|ENTITY|ENTITIES|NMTOKEN|NMTOKENS/, "|", EnumeratedType);
      var DefaultDecl = regg(/#REQUIRED|#IMPLIED/, "|", regg(regg("#FIXED", S), "?", AttValue));
      var AttDef = regg(S, Name, S, AttType, S, DefaultDecl);
      var ATTLIST_DECL_START = "<!ATTLIST";
      var AttlistDecl = reg(ATTLIST_DECL_START, S, Name, AttDef, "*", S_OPT, ">");
      var ABOUT_LEGACY_COMPAT = "about:legacy-compat";
      var ABOUT_LEGACY_COMPAT_SystemLiteral = regg('"' + ABOUT_LEGACY_COMPAT + '"', "|", "'" + ABOUT_LEGACY_COMPAT + "'");
      var SYSTEM = "SYSTEM";
      var PUBLIC = "PUBLIC";
      var ExternalID = regg(regg(SYSTEM, S, SystemLiteral), "|", regg(PUBLIC, S, PubidLiteral, S, SystemLiteral));
      var ExternalID_match = reg(
        "^",
        regg(
          regg(SYSTEM, S, "(?<SystemLiteralOnly>", SystemLiteral, ")"),
          "|",
          regg(PUBLIC, S, "(?<PubidLiteral>", PubidLiteral, ")", S, "(?<SystemLiteral>", SystemLiteral, ")")
        )
      );
      var PubidLiteral_match = reg("^", PubidLiteral, "$");
      var SystemLiteral_match = reg("^", SystemLiteral, "$");
      var NDataDecl = regg(S, "NDATA", S, Name);
      var EntityDef = regg(EntityValue, "|", regg(ExternalID, NDataDecl, "?"));
      var ENTITY_DECL_START = "<!ENTITY";
      var GEDecl = reg(ENTITY_DECL_START, S, Name, S, EntityDef, S_OPT, ">");
      var PEDef = regg(EntityValue, "|", ExternalID);
      var PEDecl = reg(ENTITY_DECL_START, S, "%", S, Name, S, PEDef, S_OPT, ">");
      var EntityDecl = regg(GEDecl, "|", PEDecl);
      var PublicID = reg(PUBLIC, S, PubidLiteral);
      var NotationDecl = reg("<!NOTATION", S, Name, S, regg(ExternalID, "|", PublicID), S_OPT, ">");
      var Eq = reg(S_OPT, "=", S_OPT);
      var VersionNum = /1[.]\d+/;
      var VersionInfo = reg(S, "version", Eq, regg("'", VersionNum, "'", "|", '"', VersionNum, '"'));
      var EncName = /[A-Za-z][-A-Za-z0-9._]*/;
      var EncodingDecl = regg(S, "encoding", Eq, regg('"', EncName, '"', "|", "'", EncName, "'"));
      var SDDecl = regg(S, "standalone", Eq, regg("'", regg("yes", "|", "no"), "'", "|", '"', regg("yes", "|", "no"), '"'));
      var XMLDecl = reg(/^<\?xml/, VersionInfo, EncodingDecl, "?", SDDecl, "?", S_OPT, /\?>/);
      var DOCTYPE_DECL_START = "<!DOCTYPE";
      var CDATA_START = "<![CDATA[";
      var CDATA_END = "]]>";
      var CDStart = /<!\[CDATA\[/;
      var CDEnd = /\]\]>/;
      var CData = reg(Char, "*?", CDEnd);
      var CDSect = reg(CDStart, CData);
      exports2.chars = chars;
      exports2.chars_without = chars_without;
      exports2.detectUnicodeSupport = detectUnicodeSupport;
      exports2.reg = reg;
      exports2.regg = regg;
      exports2.ABOUT_LEGACY_COMPAT = ABOUT_LEGACY_COMPAT;
      exports2.ABOUT_LEGACY_COMPAT_SystemLiteral = ABOUT_LEGACY_COMPAT_SystemLiteral;
      exports2.AttlistDecl = AttlistDecl;
      exports2.CDATA_START = CDATA_START;
      exports2.CDATA_END = CDATA_END;
      exports2.CDSect = CDSect;
      exports2.Char = Char;
      exports2.Comment = Comment;
      exports2.COMMENT_START = COMMENT_START;
      exports2.COMMENT_END = COMMENT_END;
      exports2.DOCTYPE_DECL_START = DOCTYPE_DECL_START;
      exports2.elementdecl = elementdecl;
      exports2.EntityDecl = EntityDecl;
      exports2.EntityValue = EntityValue;
      exports2.ExternalID = ExternalID;
      exports2.ExternalID_match = ExternalID_match;
      exports2.Name = Name;
      exports2.NotationDecl = NotationDecl;
      exports2.Reference = Reference;
      exports2.PEReference = PEReference;
      exports2.PI = PI;
      exports2.PUBLIC = PUBLIC;
      exports2.PubidLiteral = PubidLiteral;
      exports2.PubidLiteral_match = PubidLiteral_match;
      exports2.QName = QName;
      exports2.QName_exact = QName_exact;
      exports2.QName_group = QName_group;
      exports2.S = S;
      exports2.SChar_s = SChar_s;
      exports2.S_OPT = S_OPT;
      exports2.SYSTEM = SYSTEM;
      exports2.SystemLiteral = SystemLiteral;
      exports2.SystemLiteral_match = SystemLiteral_match;
      exports2.InvalidChar = InvalidChar;
      exports2.UNICODE_REPLACEMENT_CHARACTER = UNICODE_REPLACEMENT_CHARACTER;
      exports2.UNICODE_SUPPORT = UNICODE_SUPPORT;
      exports2.XMLDecl = XMLDecl;
    }
  });

  // node_modules/@xmldom/xmldom/lib/dom.js
  var require_dom = __commonJS({
    "node_modules/@xmldom/xmldom/lib/dom.js"(exports2) {
      "use strict";
      var conventions = require_conventions();
      var find = conventions.find;
      var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
      var hasOwn = conventions.hasOwn;
      var isHTMLMimeType = conventions.isHTMLMimeType;
      var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
      var isHTMLVoidElement = conventions.isHTMLVoidElement;
      var MIME_TYPE = conventions.MIME_TYPE;
      var NAMESPACE = conventions.NAMESPACE;
      var PDC = /* @__PURE__ */ Symbol();
      var errors = require_errors2();
      var DOMException = errors.DOMException;
      var DOMExceptionName = errors.DOMExceptionName;
      var g = require_grammar();
      function checkSymbol(symbol) {
        if (symbol !== PDC) {
          throw new TypeError("Illegal constructor");
        }
      }
      function notEmptyString(input) {
        return input !== "";
      }
      function splitOnASCIIWhitespace(input) {
        return input ? input.split(/[\t\n\f\r ]+/).filter(notEmptyString) : [];
      }
      function orderedSetReducer(current, element) {
        if (!hasOwn(current, element)) {
          current[element] = true;
        }
        return current;
      }
      function toOrderedSet(input) {
        if (!input) return [];
        var list = splitOnASCIIWhitespace(input);
        return Object.keys(list.reduce(orderedSetReducer, {}));
      }
      function arrayIncludes(list) {
        return function(element) {
          return list && list.indexOf(element) !== -1;
        };
      }
      function validateQualifiedName(qualifiedName) {
        if (!g.QName_exact.test(qualifiedName)) {
          throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in qualified name "' + qualifiedName + '"');
        }
      }
      function validateAndExtract(namespace, qualifiedName) {
        validateQualifiedName(qualifiedName);
        namespace = namespace || null;
        var prefix = null;
        var localName = qualifiedName;
        if (qualifiedName.indexOf(":") >= 0) {
          var splitResult = qualifiedName.split(":");
          prefix = splitResult[0];
          localName = splitResult[1];
        }
        if (prefix !== null && namespace === null) {
          throw new DOMException(DOMException.NAMESPACE_ERR, "prefix is non-null and namespace is null");
        }
        if (prefix === "xml" && namespace !== conventions.NAMESPACE.XML) {
          throw new DOMException(DOMException.NAMESPACE_ERR, 'prefix is "xml" and namespace is not the XML namespace');
        }
        if ((prefix === "xmlns" || qualifiedName === "xmlns") && namespace !== conventions.NAMESPACE.XMLNS) {
          throw new DOMException(
            DOMException.NAMESPACE_ERR,
            'either qualifiedName or prefix is "xmlns" and namespace is not the XMLNS namespace'
          );
        }
        if (namespace === conventions.NAMESPACE.XMLNS && prefix !== "xmlns" && qualifiedName !== "xmlns") {
          throw new DOMException(
            DOMException.NAMESPACE_ERR,
            'namespace is the XMLNS namespace and neither qualifiedName nor prefix is "xmlns"'
          );
        }
        return [namespace, prefix, localName];
      }
      function copy(src, dest) {
        for (var p in src) {
          if (hasOwn(src, p)) {
            dest[p] = src[p];
          }
        }
      }
      function _extends(Class, Super) {
        var pt = Class.prototype;
        if (!(pt instanceof Super)) {
          let t = function() {
          };
          t.prototype = Super.prototype;
          t = new t();
          copy(pt, t);
          Class.prototype = pt = t;
        }
        if (pt.constructor != Class) {
          if (typeof Class != "function") {
            console.error("unknown Class:" + Class);
          }
          pt.constructor = Class;
        }
      }
      var NodeType = {};
      var ELEMENT_NODE = NodeType.ELEMENT_NODE = 1;
      var ATTRIBUTE_NODE = NodeType.ATTRIBUTE_NODE = 2;
      var TEXT_NODE = NodeType.TEXT_NODE = 3;
      var CDATA_SECTION_NODE = NodeType.CDATA_SECTION_NODE = 4;
      var ENTITY_REFERENCE_NODE = NodeType.ENTITY_REFERENCE_NODE = 5;
      var ENTITY_NODE = NodeType.ENTITY_NODE = 6;
      var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
      var COMMENT_NODE = NodeType.COMMENT_NODE = 8;
      var DOCUMENT_NODE = NodeType.DOCUMENT_NODE = 9;
      var DOCUMENT_TYPE_NODE = NodeType.DOCUMENT_TYPE_NODE = 10;
      var DOCUMENT_FRAGMENT_NODE = NodeType.DOCUMENT_FRAGMENT_NODE = 11;
      var NOTATION_NODE = NodeType.NOTATION_NODE = 12;
      var DocumentPosition = conventions.freeze({
        DOCUMENT_POSITION_DISCONNECTED: 1,
        DOCUMENT_POSITION_PRECEDING: 2,
        DOCUMENT_POSITION_FOLLOWING: 4,
        DOCUMENT_POSITION_CONTAINS: 8,
        DOCUMENT_POSITION_CONTAINED_BY: 16,
        DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: 32
      });
      function commonAncestor(a, b) {
        if (b.length < a.length) return commonAncestor(b, a);
        var c = null;
        for (var n in a) {
          if (a[n] !== b[n]) return c;
          c = a[n];
        }
        return c;
      }
      function docGUID(doc) {
        if (!doc.guid) doc.guid = Math.random();
        return doc.guid;
      }
      function NodeList() {
      }
      NodeList.prototype = {
        /**
         * The number of nodes in the list. The range of valid child node indices is 0 to length-1
         * inclusive.
         *
         * @type {number}
         */
        length: 0,
        /**
         * Returns the item at `index`. If index is greater than or equal to the number of nodes in
         * the list, this returns null.
         *
         * @param index
         * Unsigned long Index into the collection.
         * @returns {Node | null}
         * The node at position `index` in the NodeList,
         * or null if that is not a valid index.
         */
        item: function(index) {
          return index >= 0 && index < this.length ? this[index] : null;
        },
        /**
         * Returns a string representation of the NodeList.
         *
         * Accepts the same `options` object as `XMLSerializer.prototype.serializeToString`
         * (`requireWellFormed`, `splitCDATASections`, `nodeFilter`). Passing a function is treated as
         * a legacy `nodeFilter` for backward compatibility.
         *
         * @param {Object | function} [options]
         * @param {boolean} [options.requireWellFormed=false]
         * @param {boolean} [options.splitCDATASections=true]
         * @param {function} [options.nodeFilter]
         * @returns {string}
         */
        toString: function(options) {
          var opts;
          if (typeof options === "function") {
            opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
          } else if (!!options) {
            opts = {
              requireWellFormed: !!options.requireWellFormed,
              splitCDATASections: options.splitCDATASections !== false,
              nodeFilter: options.nodeFilter || null
            };
          } else {
            opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
          }
          for (var buf = [], i = 0; i < this.length; i++) {
            serializeToString(this[i], buf, null, opts);
          }
          return buf.join("");
        },
        /**
         * Filters the NodeList based on a predicate.
         *
         * @param {function(Node): boolean} predicate
         * - A predicate function to filter the NodeList.
         * @returns {Node[]}
         * An array of nodes that satisfy the predicate.
         * @private
         */
        filter: function(predicate) {
          return Array.prototype.filter.call(this, predicate);
        },
        /**
         * Returns the first index at which a given node can be found in the NodeList, or -1 if it is
         * not present.
         *
         * @param {Node} item
         * - The Node item to locate in the NodeList.
         * @returns {number}
         * The first index of the node in the NodeList; -1 if not found.
         * @private
         */
        indexOf: function(item) {
          return Array.prototype.indexOf.call(this, item);
        }
      };
      NodeList.prototype[Symbol.iterator] = function() {
        var me = this;
        var index = 0;
        return {
          next: function() {
            if (index < me.length) {
              return {
                value: me[index++],
                done: false
              };
            } else {
              return {
                done: true
              };
            }
          },
          return: function() {
            return {
              done: true
            };
          }
        };
      };
      function LiveNodeList(node, refresh) {
        this._node = node;
        this._refresh = refresh;
        _updateLiveList(this);
      }
      function _updateLiveList(list) {
        var inc = list._node._inc || list._node.ownerDocument._inc;
        if (list._inc !== inc) {
          var ls = list._refresh(list._node);
          __set__(list, "length", ls.length);
          if (!list.$$length || ls.length < list.$$length) {
            for (var i = ls.length; i in list; i++) {
              if (hasOwn(list, i)) {
                delete list[i];
              }
            }
          }
          copy(ls, list);
          list._inc = inc;
        }
      }
      LiveNodeList.prototype.item = function(i) {
        _updateLiveList(this);
        return this[i] || null;
      };
      _extends(LiveNodeList, NodeList);
      function NamedNodeMap() {
      }
      function _findNodeIndex(list, node) {
        var i = 0;
        while (i < list.length) {
          if (list[i] === node) {
            return i;
          }
          i++;
        }
      }
      function _addNamedNode(el, list, newAttr, oldAttr) {
        if (oldAttr) {
          list[_findNodeIndex(list, oldAttr)] = newAttr;
        } else {
          list[list.length] = newAttr;
          list.length++;
        }
        if (el) {
          newAttr.ownerElement = el;
          var doc = el.ownerDocument;
          if (doc) {
            oldAttr && _onRemoveAttribute(doc, el, oldAttr);
            _onAddAttribute(doc, el, newAttr);
          }
        }
      }
      function _removeNamedNode(el, list, attr) {
        var i = _findNodeIndex(list, attr);
        if (i >= 0) {
          var lastIndex = list.length - 1;
          while (i <= lastIndex) {
            list[i] = list[++i];
          }
          list.length = lastIndex;
          if (el) {
            var doc = el.ownerDocument;
            if (doc) {
              _onRemoveAttribute(doc, el, attr);
            }
            attr.ownerElement = null;
          }
        }
      }
      NamedNodeMap.prototype = {
        length: 0,
        item: NodeList.prototype.item,
        /**
         * Get an attribute by name. Note: Name is in lower case in case of HTML namespace and
         * document.
         *
         * @param {string} localName
         * The local name of the attribute.
         * @returns {Attr | null}
         * The attribute with the given local name, or null if no such attribute exists.
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
         */
        getNamedItem: function(localName) {
          if (this._ownerElement && this._ownerElement._isInHTMLDocumentAndNamespace()) {
            localName = localName.toLowerCase();
          }
          var i = 0;
          while (i < this.length) {
            var attr = this[i];
            if (attr.nodeName === localName) {
              return attr;
            }
            i++;
          }
          return null;
        },
        /**
         * Set an attribute.
         *
         * @param {Attr} attr
         * The attribute to set.
         * @returns {Attr | null}
         * The old attribute with the same local name and namespace URI as the new one, or null if no
         * such attribute exists.
         * @throws {DOMException}
         * With code:
         * - {@link INUSE_ATTRIBUTE_ERR} - If the attribute is already an attribute of another
         * element.
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
         */
        setNamedItem: function(attr) {
          var el = attr.ownerElement;
          if (el && el !== this._ownerElement) {
            throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
          }
          var oldAttr = this.getNamedItemNS(attr.namespaceURI, attr.localName);
          if (oldAttr === attr) {
            return attr;
          }
          _addNamedNode(this._ownerElement, this, attr, oldAttr);
          return oldAttr;
        },
        /**
         * Set an attribute, replacing an existing attribute with the same local name and namespace
         * URI if one exists.
         *
         * @param {Attr} attr
         * The attribute to set.
         * @returns {Attr | null}
         * The old attribute with the same local name and namespace URI as the new one, or null if no
         * such attribute exists.
         * @throws {DOMException}
         * Throws a DOMException with the name "InUseAttributeError" if the attribute is already an
         * attribute of another element.
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-set
         */
        setNamedItemNS: function(attr) {
          return this.setNamedItem(attr);
        },
        /**
         * Removes an attribute specified by the local name.
         *
         * @param {string} localName
         * The local name of the attribute to be removed.
         * @returns {Attr}
         * The attribute node that was removed.
         * @throws {DOMException}
         * With code:
         * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given name is found.
         * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditem
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
         */
        removeNamedItem: function(localName) {
          var attr = this.getNamedItem(localName);
          if (!attr) {
            throw new DOMException(DOMException.NOT_FOUND_ERR, localName);
          }
          _removeNamedNode(this._ownerElement, this, attr);
          return attr;
        },
        /**
         * Removes an attribute specified by the namespace and local name.
         *
         * @param {string | null} namespaceURI
         * The namespace URI of the attribute to be removed.
         * @param {string} localName
         * The local name of the attribute to be removed.
         * @returns {Attr}
         * The attribute node that was removed.
         * @throws {DOMException}
         * With code:
         * - {@link DOMException.NOT_FOUND_ERR} if no attribute with the given namespace URI and local
         * name is found.
         * @see https://dom.spec.whatwg.org/#dom-namednodemap-removenameditemns
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
         */
        removeNamedItemNS: function(namespaceURI, localName) {
          var attr = this.getNamedItemNS(namespaceURI, localName);
          if (!attr) {
            throw new DOMException(DOMException.NOT_FOUND_ERR, namespaceURI ? namespaceURI + " : " + localName : localName);
          }
          _removeNamedNode(this._ownerElement, this, attr);
          return attr;
        },
        /**
         * Get an attribute by namespace and local name.
         *
         * @param {string | null} namespaceURI
         * The namespace URI of the attribute.
         * @param {string} localName
         * The local name of the attribute.
         * @returns {Attr | null}
         * The attribute with the given namespace URI and local name, or null if no such attribute
         * exists.
         * @see https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
         */
        getNamedItemNS: function(namespaceURI, localName) {
          if (!namespaceURI) {
            namespaceURI = null;
          }
          var i = 0;
          while (i < this.length) {
            var node = this[i];
            if (node.localName === localName && node.namespaceURI === namespaceURI) {
              return node;
            }
            i++;
          }
          return null;
        }
      };
      NamedNodeMap.prototype[Symbol.iterator] = function() {
        var me = this;
        var index = 0;
        return {
          next: function() {
            if (index < me.length) {
              return {
                value: me[index++],
                done: false
              };
            } else {
              return {
                done: true
              };
            }
          },
          return: function() {
            return {
              done: true
            };
          }
        };
      };
      function DOMImplementation() {
      }
      DOMImplementation.prototype = {
        /**
         * Test if the DOM implementation implements a specific feature and version, as specified in
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/core.html#DOMFeatures DOM Features}.
         *
         * The DOMImplementation.hasFeature() method returns a Boolean flag indicating if a given
         * feature is supported. The different implementations fairly diverged in what kind of
         * features were reported. The latest version of the spec settled to force this method to
         * always return true, where the functionality was accurate and in use.
         *
         * @deprecated
         * It is deprecated and modern browsers return true in all cases.
         * @function DOMImplementation#hasFeature
         * @param {string} feature
         * The name of the feature to test.
         * @param {string} [version]
         * This is the version number of the feature to test.
         * @returns {boolean}
         * Always returns true.
         * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/hasFeature MDN
         * @see https://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-5CED94D7 DOM Level 1 Core
         * @see https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature DOM Living Standard
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-5CED94D7 DOM Level 3 Core
         */
        hasFeature: function(feature, version) {
          return true;
        },
        /**
         * Creates a DOM Document object of the specified type with its document element. Note that
         * based on the {@link DocumentType}
         * given to create the document, the implementation may instantiate specialized
         * {@link Document} objects that support additional features than the "Core", such as "HTML"
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML}.
         * On the other hand, setting the {@link DocumentType} after the document was created makes
         * this very unlikely to happen. Alternatively, specialized {@link Document} creation methods,
         * such as createHTMLDocument
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#DOM2HTML DOM Level 2 HTML},
         * can be used to obtain specific types of {@link Document} objects.
         *
         * __It behaves slightly different from the description in the living standard__:
         * - There is no interface/class `XMLDocument`, it returns a `Document`
         * instance (with it's `type` set to `'xml'`).
         * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
         *
         * @function DOMImplementation.createDocument
         * @param {string | null} namespaceURI
         * The
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-namespaceURI namespace URI}
         * of the document element to create or null.
         * @param {string | null} qualifiedName
         * The
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified name}
         * of the document element to be created or null.
         * @param {DocumentType | null} [doctype=null]
         * The type of document to be created or null. When doctype is not null, its
         * {@link Node#ownerDocument} attribute is set to the document being created. Default is
         * `null`
         * @returns {Document}
         * A new {@link Document} object with its document element. If the NamespaceURI,
         * qualifiedName, and doctype are null, the returned {@link Document} is empty with no
         * document element.
         * @throws {DOMException}
         * With code:
         *
         * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
         * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
         * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed, if the qualifiedName has a
         * prefix and the namespaceURI is null, or if the qualifiedName is null and the namespaceURI
         * is different from null, or if the qualifiedName has a prefix that is "xml" and the
         * namespaceURI is different from "{@link http://www.w3.org/XML/1998/namespace}"
         * {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#Namespaces XML Namespaces},
         * or if the DOM implementation does not support the "XML" feature but a non-null namespace
         * URI was provided, since namespaces were defined by XML.
         * - `WRONG_DOCUMENT_ERR`: Raised if doctype has already been used with a different document
         * or was created from a different implementation.
         * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
         * "XML" and the language exposed through the Document does not support XML Namespaces (such
         * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
         * @since DOM Level 2.
         * @see {@link #createHTMLDocument}
         * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocument MDN
         * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocument DOM Living Standard
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-2-Core-DOM-createDocument DOM
         *      Level 3 Core
         * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocument DOM
         *      Level 2 Core (initial)
         */
        createDocument: function(namespaceURI, qualifiedName, doctype) {
          var contentType = MIME_TYPE.XML_APPLICATION;
          if (namespaceURI === NAMESPACE.HTML) {
            contentType = MIME_TYPE.XML_XHTML_APPLICATION;
          } else if (namespaceURI === NAMESPACE.SVG) {
            contentType = MIME_TYPE.XML_SVG_IMAGE;
          }
          var doc = new Document(PDC, { contentType });
          doc.implementation = this;
          doc.childNodes = new NodeList();
          doc.doctype = doctype || null;
          if (doctype) {
            doc.appendChild(doctype);
          }
          if (qualifiedName) {
            var root = doc.createElementNS(namespaceURI, qualifiedName);
            doc.appendChild(root);
          }
          return doc;
        },
        /**
         * Creates an empty DocumentType node. Entity declarations and notations are not made
         * available. Entity reference expansions and default attribute additions do not occur.
         *
         * **This behavior is slightly different from the one in the specs**:
         * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
         * - `publicId` and `systemId` contain the raw data including any possible quotes,
         *   so they can always be serialized back to the original value
         * - `internalSubset` contains the raw string between `[` and `]` if present,
         *   but is not parsed or validated in any form.
         *
         * @function DOMImplementation#createDocumentType
         * @param {string} qualifiedName
         * The {@link https://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-qualifiedname qualified
         * name} of the document type to be created.
         * @param {string} [publicId]
         * The external subset public identifier. Stored verbatim including surrounding quotes.
         * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
         * if the value is non-empty and does not match the XML `PubidLiteral` production
         * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [12]). Creation-time validation is not
         * enforced — deferred to a future breaking release.
         * @param {string} [systemId]
         * The external subset system identifier. Stored verbatim including surrounding quotes.
         * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
         * if the value is non-empty and does not match the XML `SystemLiteral` production
         * (W3C DOM Parsing §3.2.1.3; XML 1.0 production [11]). Creation-time validation is not
         * enforced — deferred to a future breaking release.
         * @param {string} [internalSubset]
         * The internal subset or an empty string if it is not present. Stored verbatim.
         * When serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
         * if the value contains `"]>"`. Creation-time validation is not enforced.
         * @returns {DocumentType}
         * A new {@link DocumentType} node with {@link Node#ownerDocument} set to null.
         * @throws {DOMException}
         * With code:
         *
         * - `INVALID_CHARACTER_ERR`: Raised if the specified qualified name is not an XML name
         * according to {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#XML XML 1.0}.
         * - `NAMESPACE_ERR`: Raised if the qualifiedName is malformed.
         * - `NOT_SUPPORTED_ERR`: May be raised if the implementation does not support the feature
         * "XML" and the language exposed through the Document does not support XML Namespaces (such
         * as {@link https://www.w3.org/TR/DOM-Level-3-Core/references.html#HTML40 HTML 4.01}).
         * @since DOM Level 2.
         * @see https://developer.mozilla.org/en-US/docs/Web/API/DOMImplementation/createDocumentType
         *      MDN
         * @see https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype DOM Living
         *      Standard
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Level-3-Core-DOM-createDocType DOM
         *      Level 3 Core
         * @see https://www.w3.org/TR/DOM-Level-2-Core/core.html#Level-2-Core-DOM-createDocType DOM
         *      Level 2 Core
         * @see https://github.com/xmldom/xmldom/blob/master/CHANGELOG.md#050
         * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-Core-DocType-internalSubset
         * @prettierignore
         */
        createDocumentType: function(qualifiedName, publicId, systemId, internalSubset) {
          validateQualifiedName(qualifiedName);
          var node = new DocumentType(PDC);
          node.name = qualifiedName;
          node.nodeName = qualifiedName;
          node.publicId = publicId || "";
          node.systemId = systemId || "";
          node.internalSubset = internalSubset || "";
          node.childNodes = new NodeList();
          return node;
        },
        /**
         * Returns an HTML document, that might already have a basic DOM structure.
         *
         * __It behaves slightly different from the description in the living standard__:
         * - If the first argument is `false` no initial nodes are added (steps 3-7 in the specs are
         * omitted)
         * - `encoding`, `mode`, `origin`, `url` fields are currently not declared.
         *
         * @param {string | false} [title]
         * A string containing the title to give the new HTML document.
         * @returns {Document}
         * The HTML document.
         * @since WHATWG Living Standard.
         * @see {@link #createDocument}
         * @see https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
         * @see https://dom.spec.whatwg.org/#html-document
         */
        createHTMLDocument: function(title) {
          var doc = new Document(PDC, { contentType: MIME_TYPE.HTML });
          doc.implementation = this;
          doc.childNodes = new NodeList();
          if (title !== false) {
            doc.doctype = this.createDocumentType("html");
            doc.doctype.ownerDocument = doc;
            doc.appendChild(doc.doctype);
            var htmlNode = doc.createElement("html");
            doc.appendChild(htmlNode);
            var headNode = doc.createElement("head");
            htmlNode.appendChild(headNode);
            if (typeof title === "string") {
              var titleNode = doc.createElement("title");
              titleNode.appendChild(doc.createTextNode(title));
              headNode.appendChild(titleNode);
            }
            htmlNode.appendChild(doc.createElement("body"));
          }
          return doc;
        }
      };
      function Node(symbol) {
        checkSymbol(symbol);
      }
      Node.prototype = {
        /**
         * The first child of this node.
         *
         * @type {Node | null}
         */
        firstChild: null,
        /**
         * The last child of this node.
         *
         * @type {Node | null}
         */
        lastChild: null,
        /**
         * The previous sibling of this node.
         *
         * @type {Node | null}
         */
        previousSibling: null,
        /**
         * The next sibling of this node.
         *
         * @type {Node | null}
         */
        nextSibling: null,
        /**
         * The parent node of this node.
         *
         * @type {Node | null}
         */
        parentNode: null,
        /**
         * The parent element of this node.
         *
         * @type {Element | null}
         */
        get parentElement() {
          return this.parentNode && this.parentNode.nodeType === this.ELEMENT_NODE ? this.parentNode : null;
        },
        /**
         * The child nodes of this node.
         *
         * @type {NodeList}
         */
        childNodes: null,
        /**
         * The document object associated with this node.
         *
         * @type {Document | null}
         */
        ownerDocument: null,
        /**
         * The value of this node.
         *
         * @type {string | null}
         */
        nodeValue: null,
        /**
         * The namespace URI of this node.
         *
         * @type {string | null}
         */
        namespaceURI: null,
        /**
         * The prefix of the namespace for this node.
         *
         * @type {string | null}
         */
        prefix: null,
        /**
         * The local part of the qualified name of this node.
         *
         * @type {string | null}
         */
        localName: null,
        /**
         * The baseURI is currently always `about:blank`,
         * since that's what happens when you create a document from scratch.
         *
         * @type {'about:blank'}
         */
        baseURI: "about:blank",
        /**
         * Is true if this node is part of a document.
         *
         * @type {boolean}
         */
        get isConnected() {
          var rootNode = this.getRootNode();
          return rootNode && rootNode.nodeType === rootNode.DOCUMENT_NODE;
        },
        /**
         * Checks whether `other` is an inclusive descendant of this node.
         *
         * @param {Node | null | undefined} other
         * The node to check.
         * @returns {boolean}
         * True if `other` is an inclusive descendant of this node; false otherwise.
         * @see https://dom.spec.whatwg.org/#dom-node-contains
         */
        contains: function(other) {
          if (!other) return false;
          var parent = other;
          do {
            if (this === parent) return true;
            parent = parent.parentNode;
          } while (parent);
          return false;
        },
        /**
         * @typedef GetRootNodeOptions
         * @property {boolean} [composed=false]
         */
        /**
         * Searches for the root node of this node.
         *
         * **This behavior is slightly different from the in the specs**:
         * - ignores `options.composed`, since `ShadowRoot`s are unsupported, always returns root.
         *
         * @param {GetRootNodeOptions} [options]
         * @returns {Node}
         * Root node.
         * @see https://dom.spec.whatwg.org/#dom-node-getrootnode
         * @see https://dom.spec.whatwg.org/#concept-shadow-including-root
         */
        getRootNode: function(options) {
          var parent = this;
          do {
            if (!parent.parentNode) {
              return parent;
            }
            parent = parent.parentNode;
          } while (parent);
        },
        /**
         * Checks whether the given node is equal to this node.
         *
         * Two nodes are equal when they have the same type, defining characteristics (for the type),
         * and the same childNodes. The comparison is iterative to avoid stack overflows on
         * deeply-nested trees. Attribute nodes of each Element pair are also pushed onto the stack
         * and compared the same way.
         *
         * @param {Node} [otherNode]
         * @returns {boolean}
         * @see https://dom.spec.whatwg.org/#concept-node-equals
         * @see ../docs/walk-dom.md.
         */
        isEqualNode: function(otherNode) {
          if (!otherNode) return false;
          var stack = [{ node: this, other: otherNode }];
          while (stack.length > 0) {
            var pair = stack.pop();
            var node = pair.node;
            var other = pair.other;
            if (node.nodeType !== other.nodeType) return false;
            switch (node.nodeType) {
              case node.DOCUMENT_TYPE_NODE:
                if (node.name !== other.name) return false;
                if (node.publicId !== other.publicId) return false;
                if (node.systemId !== other.systemId) return false;
                break;
              case node.ELEMENT_NODE:
                if (node.namespaceURI !== other.namespaceURI) return false;
                if (node.prefix !== other.prefix) return false;
                if (node.localName !== other.localName) return false;
                if (node.attributes.length !== other.attributes.length) return false;
                for (var i = 0; i < node.attributes.length; i++) {
                  var attr = node.attributes.item(i);
                  var otherAttr = other.getAttributeNodeNS(attr.namespaceURI, attr.localName);
                  if (!otherAttr) return false;
                  stack.push({ node: attr, other: otherAttr });
                }
                break;
              case node.ATTRIBUTE_NODE:
                if (node.namespaceURI !== other.namespaceURI) return false;
                if (node.localName !== other.localName) return false;
                if (node.value !== other.value) return false;
                break;
              case node.PROCESSING_INSTRUCTION_NODE:
                if (node.target !== other.target || node.data !== other.data) return false;
                break;
              case node.TEXT_NODE:
              case node.CDATA_SECTION_NODE:
              case node.COMMENT_NODE:
                if (node.data !== other.data) return false;
                break;
            }
            if (node.childNodes.length !== other.childNodes.length) return false;
            for (var i = node.childNodes.length - 1; i >= 0; i--) {
              stack.push({ node: node.childNodes[i], other: other.childNodes[i] });
            }
          }
          return true;
        },
        /**
         * Checks whether or not the given node is this node.
         *
         * @param {Node} [otherNode]
         */
        isSameNode: function(otherNode) {
          return this === otherNode;
        },
        /**
         * Inserts a node before a reference node as a child of this node.
         *
         * @param {Node} newChild
         * The new child node to be inserted.
         * @param {Node | null} refChild
         * The reference node before which newChild will be inserted.
         * @returns {Node}
         * The new child node successfully inserted.
         * @throws {DOMException}
         * Throws a DOMException if inserting the node would result in a DOM tree that is not
         * well-formed, or if `child` is provided but is not a child of `parent`.
         * See {@link _insertBefore} for more details.
         * @since Modified in DOM L2
         */
        insertBefore: function(newChild, refChild) {
          return _insertBefore(this, newChild, refChild);
        },
        /**
         * Replaces an old child node with a new child node within this node.
         *
         * @param {Node} newChild
         * The new node that is to replace the old node.
         * If it already exists in the DOM, it is removed from its original position.
         * @param {Node} oldChild
         * The existing child node to be replaced.
         * @returns {Node}
         * Returns the replaced child node.
         * @throws {DOMException}
         * Throws a DOMException if replacing the node would result in a DOM tree that is not
         * well-formed, or if `oldChild` is not a child of `this`.
         * This can also occur if the pre-replacement validity assertion fails.
         * See {@link _insertBefore}, {@link Node.removeChild}, and
         * {@link assertPreReplacementValidityInDocument} for more details.
         * @see https://dom.spec.whatwg.org/#concept-node-replace
         */
        replaceChild: function(newChild, oldChild) {
          _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
          if (oldChild) {
            this.removeChild(oldChild);
          }
        },
        /**
         * Removes an existing child node from this node.
         *
         * @param {Node} oldChild
         * The child node to be removed.
         * @returns {Node}
         * Returns the removed child node.
         * @throws {DOMException}
         * Throws a DOMException if `oldChild` is not a child of `this`.
         * See {@link _removeChild} for more details.
         */
        removeChild: function(oldChild) {
          return _removeChild(this, oldChild);
        },
        /**
         * Appends a child node to this node.
         *
         * @param {Node} newChild
         * The child node to be appended to this node.
         * If it already exists in the DOM, it is removed from its original position.
         * @returns {Node}
         * Returns the appended child node.
         * @throws {DOMException}
         * Throws a DOMException if appending the node would result in a DOM tree that is not
         * well-formed, or if `newChild` is not a valid Node.
         * See {@link insertBefore} for more details.
         */
        appendChild: function(newChild) {
          return this.insertBefore(newChild, null);
        },
        /**
         * Determines whether this node has any child nodes.
         *
         * @returns {boolean}
         * Returns true if this node has any child nodes, and false otherwise.
         */
        hasChildNodes: function() {
          return this.firstChild != null;
        },
        /**
         * Creates a copy of the calling node.
         *
         * @param {boolean} deep
         * If true, the contents of the node are recursively copied.
         * If false, only the node itself (and its attributes, if it is an element) are copied.
         * @returns {Node}
         * Returns the newly created copy of the node.
         * @throws {DOMException}
         * May throw a DOMException if operations within {@link Element#setAttributeNode} or
         * {@link Node#appendChild} (which are potentially invoked in this method) do not meet their
         * specific constraints.
         * @see {@link cloneNode}
         */
        cloneNode: function(deep) {
          return cloneNode(this.ownerDocument || this, this, deep);
        },
        /**
         * Puts the specified node and all of its subtree into a "normalized" form. In a normalized
         * subtree, no text nodes in the subtree are empty and there are no adjacent text nodes.
         *
         * Specifically, this method merges any adjacent text nodes (i.e., nodes for which `nodeType`
         * is `TEXT_NODE`) into a single node with the combined data. It also removes any empty text
         * nodes.
         *
         * This method iterativly traverses all child nodes to normalize all descendent nodes within
         * the subtree.
         *
         * @throws {DOMException}
         * May throw a DOMException if operations within removeChild or appendData (which are
         * potentially invoked in this method) do not meet their specific constraints.
         * @since Modified in DOM Level 2
         * @see {@link Node.removeChild}
         * @see {@link CharacterData.appendData}
         * @see ../docs/walk-dom.md.
         */
        normalize: function() {
          walkDOM(this, null, {
            enter: function(node) {
              var child = node.firstChild;
              while (child) {
                var next = child.nextSibling;
                if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
                  node.removeChild(next);
                  child.appendData(next.data);
                } else {
                  child = next;
                }
              }
              return true;
            }
          });
        },
        /**
         * Checks whether the DOM implementation implements a specific feature and its version.
         *
         * @deprecated
         * Since `DOMImplementation.hasFeature` is deprecated and always returns true.
         * @param {string} feature
         * The package name of the feature to test. This is the same name that can be passed to the
         * method `hasFeature` on `DOMImplementation`.
         * @param {string} version
         * This is the version number of the package name to test.
         * @returns {boolean}
         * Returns true in all cases in the current implementation.
         * @since Introduced in DOM Level 2
         * @see {@link DOMImplementation.hasFeature}
         */
        isSupported: function(feature, version) {
          return this.ownerDocument.implementation.hasFeature(feature, version);
        },
        /**
         * Look up the prefix associated to the given namespace URI, starting from this node.
         * **The default namespace declarations are ignored by this method.**
         * See Namespace Prefix Lookup for details on the algorithm used by this method.
         *
         * **This behavior is different from the in the specs**:
         * - no node type specific handling
         * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
         *
         * @param {string | null} namespaceURI
         * The namespace URI for which to find the associated prefix.
         * @returns {string | null}
         * The associated prefix, if found; otherwise, null.
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespacePrefix
         * @see https://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#lookupNamespacePrefixAlgo
         * @see https://dom.spec.whatwg.org/#dom-node-lookupprefix
         * @see https://github.com/xmldom/xmldom/issues/322
         * @prettierignore
         */
        lookupPrefix: function(namespaceURI) {
          var el = this;
          while (el) {
            var map = el._nsMap;
            if (map) {
              for (var n in map) {
                if (hasOwn(map, n) && map[n] === namespaceURI) {
                  return n;
                }
              }
            }
            el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
          }
          return null;
        },
        /**
         * This function is used to look up the namespace URI associated with the given prefix,
         * starting from this node.
         *
         * **This behavior is different from the in the specs**:
         * - no node type specific handling
         * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
         *
         * @param {string | null} prefix
         * The prefix for which to find the associated namespace URI.
         * @returns {string | null}
         * The associated namespace URI, if found; otherwise, null.
         * @since DOM Level 3
         * @see https://dom.spec.whatwg.org/#dom-node-lookupnamespaceuri
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI
         * @prettierignore
         */
        lookupNamespaceURI: function(prefix) {
          var el = this;
          while (el) {
            var map = el._nsMap;
            if (map) {
              if (hasOwn(map, prefix)) {
                return map[prefix];
              }
            }
            el = el.nodeType == ATTRIBUTE_NODE ? el.ownerDocument : el.parentNode;
          }
          return null;
        },
        /**
         * Determines whether the given namespace URI is the default namespace.
         *
         * The function works by looking up the prefix associated with the given namespace URI. If no
         * prefix is found (i.e., the namespace URI is not registered in the namespace map of this
         * node or any of its ancestors), it returns `true`, implying the namespace URI is considered
         * the default.
         *
         * **This behavior is different from the in the specs**:
         * - no node type specific handling
         * - uses the internal attribute _nsMap for resolving namespaces that is updated when changing attributes
         *
         * @param {string | null} namespaceURI
         * The namespace URI to be checked.
         * @returns {boolean}
         * Returns true if the given namespace URI is the default namespace, false otherwise.
         * @since DOM Level 3
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isDefaultNamespace
         * @see https://dom.spec.whatwg.org/#dom-node-isdefaultnamespace
         * @prettierignore
         */
        isDefaultNamespace: function(namespaceURI) {
          var prefix = this.lookupPrefix(namespaceURI);
          return prefix == null;
        },
        /**
         * Compares the reference node with a node with regard to their position in the document and
         * according to the document order.
         *
         * @param {Node} other
         * The node to compare the reference node to.
         * @returns {number}
         * Returns how the node is positioned relatively to the reference node according to the
         * bitmask. 0 if reference node and given node are the same.
         * @since DOM Level 3
         * @see https://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-compare
         * @see https://dom.spec.whatwg.org/#dom-node-comparedocumentposition
         */
        compareDocumentPosition: function(other) {
          if (this === other) return 0;
          var node1 = other;
          var node2 = this;
          var attr1 = null;
          var attr2 = null;
          if (node1 instanceof Attr) {
            attr1 = node1;
            node1 = attr1.ownerElement;
          }
          if (node2 instanceof Attr) {
            attr2 = node2;
            node2 = attr2.ownerElement;
            if (attr1 && node1 && node2 === node1) {
              for (var i = 0, attr; attr = node2.attributes[i]; i++) {
                if (attr === attr1)
                  return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
                if (attr === attr2)
                  return DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
              }
            }
          }
          if (!node1 || !node2 || node2.ownerDocument !== node1.ownerDocument) {
            return DocumentPosition.DOCUMENT_POSITION_DISCONNECTED + DocumentPosition.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + (docGUID(node2.ownerDocument) > docGUID(node1.ownerDocument) ? DocumentPosition.DOCUMENT_POSITION_FOLLOWING : DocumentPosition.DOCUMENT_POSITION_PRECEDING);
          }
          if (attr2 && node1 === node2) {
            return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
          }
          if (attr1 && node1 === node2) {
            return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
          }
          var chain1 = [];
          var ancestor1 = node1.parentNode;
          while (ancestor1) {
            if (!attr2 && ancestor1 === node2) {
              return DocumentPosition.DOCUMENT_POSITION_CONTAINED_BY + DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
            }
            chain1.push(ancestor1);
            ancestor1 = ancestor1.parentNode;
          }
          chain1.reverse();
          var chain2 = [];
          var ancestor2 = node2.parentNode;
          while (ancestor2) {
            if (!attr1 && ancestor2 === node1) {
              return DocumentPosition.DOCUMENT_POSITION_CONTAINS + DocumentPosition.DOCUMENT_POSITION_PRECEDING;
            }
            chain2.push(ancestor2);
            ancestor2 = ancestor2.parentNode;
          }
          chain2.reverse();
          var ca = commonAncestor(chain1, chain2);
          for (var n in ca.childNodes) {
            var child = ca.childNodes[n];
            if (child === node2) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
            if (child === node1) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
            if (chain2.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_FOLLOWING;
            if (chain1.indexOf(child) >= 0) return DocumentPosition.DOCUMENT_POSITION_PRECEDING;
          }
          return 0;
        }
      };
      function _xmlEncoder(c) {
        return c == "<" && "&lt;" || c == ">" && "&gt;" || c == "&" && "&amp;" || c == '"' && "&quot;" || "&#" + c.charCodeAt() + ";";
      }
      copy(NodeType, Node);
      copy(NodeType, Node.prototype);
      copy(DocumentPosition, Node);
      copy(DocumentPosition, Node.prototype);
      function _visitNode(node, callback) {
        walkDOM(node, null, {
          enter: function(n) {
            return callback(n) ? walkDOM.STOP : true;
          }
        });
      }
      function walkDOM(node, context, callbacks) {
        var stack = [{ node, context, phase: walkDOM.ENTER }];
        while (stack.length > 0) {
          var frame = stack.pop();
          if (frame.phase === walkDOM.ENTER) {
            var childContext = callbacks.enter(frame.node, frame.context);
            if (childContext === walkDOM.STOP) {
              return walkDOM.STOP;
            }
            stack.push({ node: frame.node, context: childContext, phase: walkDOM.EXIT });
            if (childContext === null || childContext === void 0) {
              continue;
            }
            var child = frame.node.lastChild;
            while (child) {
              stack.push({ node: child, context: childContext, phase: walkDOM.ENTER });
              child = child.previousSibling;
            }
          } else {
            if (callbacks.exit) {
              callbacks.exit(frame.node, frame.context);
            }
          }
        }
      }
      walkDOM.STOP = /* @__PURE__ */ Symbol("walkDOM.STOP");
      walkDOM.ENTER = 0;
      walkDOM.EXIT = 1;
      function Document(symbol, options) {
        checkSymbol(symbol);
        var opt = options || {};
        this.ownerDocument = this;
        this.contentType = opt.contentType || MIME_TYPE.XML_APPLICATION;
        this.type = isHTMLMimeType(this.contentType) ? "html" : "xml";
      }
      function _onAddAttribute(doc, el, newAttr) {
        doc && doc._inc++;
        var ns = newAttr.namespaceURI;
        if (ns === NAMESPACE.XMLNS) {
          el._nsMap[newAttr.prefix ? newAttr.localName : ""] = newAttr.value;
        }
      }
      function _onRemoveAttribute(doc, el, newAttr, remove) {
        doc && doc._inc++;
        var ns = newAttr.namespaceURI;
        if (ns === NAMESPACE.XMLNS) {
          delete el._nsMap[newAttr.prefix ? newAttr.localName : ""];
        }
      }
      function _onUpdateChild(doc, parent, newChild) {
        if (doc && doc._inc) {
          doc._inc++;
          var childNodes = parent.childNodes;
          if (newChild && !newChild.nextSibling) {
            childNodes[childNodes.length++] = newChild;
          } else {
            var child = parent.firstChild;
            var i = 0;
            while (child) {
              childNodes[i++] = child;
              child = child.nextSibling;
            }
            childNodes.length = i;
            delete childNodes[childNodes.length];
          }
        }
      }
      function _removeChild(parentNode, child) {
        if (parentNode !== child.parentNode) {
          throw new DOMException(DOMException.NOT_FOUND_ERR, "child's parent is not parent");
        }
        var oldPreviousSibling = child.previousSibling;
        var oldNextSibling = child.nextSibling;
        if (oldPreviousSibling) {
          oldPreviousSibling.nextSibling = oldNextSibling;
        } else {
          parentNode.firstChild = oldNextSibling;
        }
        if (oldNextSibling) {
          oldNextSibling.previousSibling = oldPreviousSibling;
        } else {
          parentNode.lastChild = oldPreviousSibling;
        }
        _onUpdateChild(parentNode.ownerDocument, parentNode);
        child.parentNode = null;
        child.previousSibling = null;
        child.nextSibling = null;
        return child;
      }
      function hasValidParentNodeType(node) {
        return node && (node.nodeType === Node.DOCUMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.ELEMENT_NODE);
      }
      function hasInsertableNodeType(node) {
        return node && (node.nodeType === Node.CDATA_SECTION_NODE || node.nodeType === Node.COMMENT_NODE || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE || node.nodeType === Node.DOCUMENT_TYPE_NODE || node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.PROCESSING_INSTRUCTION_NODE || node.nodeType === Node.TEXT_NODE);
      }
      function isDocTypeNode(node) {
        return node && node.nodeType === Node.DOCUMENT_TYPE_NODE;
      }
      function isElementNode(node) {
        return node && node.nodeType === Node.ELEMENT_NODE;
      }
      function isTextNode(node) {
        return node && node.nodeType === Node.TEXT_NODE;
      }
      function isElementInsertionPossible(doc, child) {
        var parentChildNodes = doc.childNodes || [];
        if (find(parentChildNodes, isElementNode) || isDocTypeNode(child)) {
          return false;
        }
        var docTypeNode = find(parentChildNodes, isDocTypeNode);
        return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
      }
      function isElementReplacementPossible(doc, child) {
        var parentChildNodes = doc.childNodes || [];
        function hasElementChildThatIsNotChild(node) {
          return isElementNode(node) && node !== child;
        }
        if (find(parentChildNodes, hasElementChildThatIsNotChild)) {
          return false;
        }
        var docTypeNode = find(parentChildNodes, isDocTypeNode);
        return !(child && docTypeNode && parentChildNodes.indexOf(docTypeNode) > parentChildNodes.indexOf(child));
      }
      function assertPreInsertionValidity1to5(parent, node, child) {
        if (!hasValidParentNodeType(parent)) {
          throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Unexpected parent node type " + parent.nodeType);
        }
        if (child && child.parentNode !== parent) {
          throw new DOMException(DOMException.NOT_FOUND_ERR, "child not in parent");
        }
        if (
          // 4. If `node` is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
          !hasInsertableNodeType(node) || // 5. If either `node` is a Text node and `parent` is a document,
          // the sax parser currently adds top level text nodes, this will be fixed in 0.9.0
          // || (node.nodeType === Node.TEXT_NODE && parent.nodeType === Node.DOCUMENT_NODE)
          // or `node` is a doctype and `parent` is not a document, then throw a "HierarchyRequestError" DOMException.
          isDocTypeNode(node) && parent.nodeType !== Node.DOCUMENT_NODE
        ) {
          throw new DOMException(
            DOMException.HIERARCHY_REQUEST_ERR,
            "Unexpected node type " + node.nodeType + " for parent node type " + parent.nodeType
          );
        }
      }
      function assertPreInsertionValidityInDocument(parent, node, child) {
        var parentChildNodes = parent.childNodes || [];
        var nodeChildNodes = node.childNodes || [];
        if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
          var nodeChildElements = nodeChildNodes.filter(isElementNode);
          if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
          }
          if (nodeChildElements.length === 1 && !isElementInsertionPossible(parent, child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
          }
        }
        if (isElementNode(node)) {
          if (!isElementInsertionPossible(parent, child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
          }
        }
        if (isDocTypeNode(node)) {
          if (find(parentChildNodes, isDocTypeNode)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
          }
          var parentElementChild = find(parentChildNodes, isElementNode);
          if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
          }
          if (!child && parentElementChild) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can not be appended since element is present");
          }
        }
      }
      function assertPreReplacementValidityInDocument(parent, node, child) {
        var parentChildNodes = parent.childNodes || [];
        var nodeChildNodes = node.childNodes || [];
        if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
          var nodeChildElements = nodeChildNodes.filter(isElementNode);
          if (nodeChildElements.length > 1 || find(nodeChildNodes, isTextNode)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "More than one element or text in fragment");
          }
          if (nodeChildElements.length === 1 && !isElementReplacementPossible(parent, child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Element in fragment can not be inserted before doctype");
          }
        }
        if (isElementNode(node)) {
          if (!isElementReplacementPossible(parent, child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one element can be added and only after doctype");
          }
        }
        if (isDocTypeNode(node)) {
          let hasDoctypeChildThatIsNotChild = function(node2) {
            return isDocTypeNode(node2) && node2 !== child;
          };
          if (find(parentChildNodes, hasDoctypeChildThatIsNotChild)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Only one doctype is allowed");
          }
          var parentElementChild = find(parentChildNodes, isElementNode);
          if (child && parentChildNodes.indexOf(parentElementChild) < parentChildNodes.indexOf(child)) {
            throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "Doctype can only be inserted before an element");
          }
        }
      }
      function _insertBefore(parent, node, child, _inDocumentAssertion) {
        assertPreInsertionValidity1to5(parent, node, child);
        if (parent.nodeType === Node.DOCUMENT_NODE) {
          (_inDocumentAssertion || assertPreInsertionValidityInDocument)(parent, node, child);
        }
        var cp = node.parentNode;
        if (cp) {
          cp.removeChild(node);
        }
        if (node.nodeType === DOCUMENT_FRAGMENT_NODE) {
          var newFirst = node.firstChild;
          if (newFirst == null) {
            return node;
          }
          var newLast = node.lastChild;
        } else {
          newFirst = newLast = node;
        }
        var pre = child ? child.previousSibling : parent.lastChild;
        newFirst.previousSibling = pre;
        newLast.nextSibling = child;
        if (pre) {
          pre.nextSibling = newFirst;
        } else {
          parent.firstChild = newFirst;
        }
        if (child == null) {
          parent.lastChild = newLast;
        } else {
          child.previousSibling = newLast;
        }
        do {
          newFirst.parentNode = parent;
        } while (newFirst !== newLast && (newFirst = newFirst.nextSibling));
        _onUpdateChild(parent.ownerDocument || parent, parent, node);
        if (node.nodeType == DOCUMENT_FRAGMENT_NODE) {
          node.firstChild = node.lastChild = null;
        }
        return node;
      }
      Document.prototype = {
        /**
         * The implementation that created this document.
         *
         * @type DOMImplementation
         * @readonly
         */
        implementation: null,
        nodeName: "#document",
        nodeType: DOCUMENT_NODE,
        /**
         * The DocumentType node of the document.
         *
         * @type DocumentType
         * @readonly
         */
        doctype: null,
        documentElement: null,
        _inc: 1,
        insertBefore: function(newChild, refChild) {
          if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE) {
            var child = newChild.firstChild;
            while (child) {
              var next = child.nextSibling;
              this.insertBefore(child, refChild);
              child = next;
            }
            return newChild;
          }
          _insertBefore(this, newChild, refChild);
          newChild.ownerDocument = this;
          if (this.documentElement === null && newChild.nodeType === ELEMENT_NODE) {
            this.documentElement = newChild;
          }
          return newChild;
        },
        removeChild: function(oldChild) {
          var removed = _removeChild(this, oldChild);
          if (removed === this.documentElement) {
            this.documentElement = null;
          }
          return removed;
        },
        replaceChild: function(newChild, oldChild) {
          _insertBefore(this, newChild, oldChild, assertPreReplacementValidityInDocument);
          newChild.ownerDocument = this;
          if (oldChild) {
            this.removeChild(oldChild);
          }
          if (isElementNode(newChild)) {
            this.documentElement = newChild;
          }
        },
        /**
         * Imports a node from another document into this document, creating a new copy owned by this
         * document. The source node and its subtree are not modified.
         *
         * @param {Node} importedNode
         * The node to import.
         * @param {boolean} deep
         * If true, the contents of the node are recursively imported.
         * If false, only the node itself (and its attributes, if it is an element) are imported.
         * @returns {Node}
         * Returns the newly created import of the node.
         * @see {@link importNode}
         * @see {@link https://dom.spec.whatwg.org/#dom-document-importnode}
         */
        importNode: function(importedNode, deep) {
          return importNode(this, importedNode, deep);
        },
        // Introduced in DOM Level 2:
        getElementById: function(id) {
          var rtv = null;
          _visitNode(this.documentElement, function(node) {
            if (node.nodeType == ELEMENT_NODE) {
              if (node.getAttribute("id") == id) {
                rtv = node;
                return true;
              }
            }
          });
          return rtv;
        },
        /**
         * Creates a new `Element` that is owned by this `Document`.
         * In HTML Documents `localName` is the lower cased `tagName`,
         * otherwise no transformation is being applied.
         * When `contentType` implies the HTML namespace, it will be set as `namespaceURI`.
         *
         * __This implementation differs from the specification:__ - The provided name is not checked
         * against the `Name` production,
         * so no related error will be thrown.
         * - There is no interface `HTMLElement`, it is always an `Element`.
         * - There is no support for a second argument to indicate using custom elements.
         *
         * @param {string} tagName
         * @returns {Element}
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
         * @see https://dom.spec.whatwg.org/#dom-document-createelement
         * @see https://dom.spec.whatwg.org/#concept-create-element
         */
        createElement: function(tagName) {
          var node = new Element(PDC);
          node.ownerDocument = this;
          if (this.type === "html") {
            tagName = tagName.toLowerCase();
          }
          if (hasDefaultHTMLNamespace(this.contentType)) {
            node.namespaceURI = NAMESPACE.HTML;
          }
          node.nodeName = tagName;
          node.tagName = tagName;
          node.localName = tagName;
          node.childNodes = new NodeList();
          var attrs = node.attributes = new NamedNodeMap();
          attrs._ownerElement = node;
          return node;
        },
        /**
         * @returns {DocumentFragment}
         */
        createDocumentFragment: function() {
          var node = new DocumentFragment(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          return node;
        },
        /**
         * @param {string} data
         * @returns {Text}
         */
        createTextNode: function(data) {
          var node = new Text(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.appendData(data);
          return node;
        },
        /**
         * @param {string} data
         * @returns {Comment}
         * @see https://dom.spec.whatwg.org/#dom-document-createcomment
         * @see https://www.w3.org/TR/xml/#NT-Comment XML 1.0 production [15]
         * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.3
         *
         *      Note: no validation is performed at creation time. When the resulting document is
         *      serialized with `requireWellFormed: true`, the serializer throws `InvalidStateError`
         *      if the comment data contains `--` anywhere, ends with `-`, or contains characters
         *      outside the XML Char production (W3C DOM Parsing §3.2.1.3). Without that option the
         *      data is emitted verbatim.
         */
        createComment: function(data) {
          var node = new Comment(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.appendData(data);
          return node;
        },
        /**
         * Returns a new CDATASection node whose data is `data`.
         *
         * __This implementation differs from the specification:__ - calling this method on an HTML
         * document does not throw `NotSupportedError`.
         *
         * @param {string} data
         * @returns {CDATASection}
         * @throws {DOMException}
         * With code `INVALID_CHARACTER_ERR` if `data` contains `"]]>"`.
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection
         * @see https://dom.spec.whatwg.org/#dom-document-createcdatasection
         */
        createCDATASection: function(data) {
          if (data.indexOf("]]>") !== -1) {
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'data contains "]]>"');
          }
          var node = new CDATASection(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.appendData(data);
          return node;
        },
        /**
         * Returns a ProcessingInstruction node whose target is target and data is data.
         *
         * __This behavior is slightly different from the in the specs__:
         * - it does not do any input validation on the arguments and doesn't throw
         * "InvalidCharacterError".
         *
         * Note: When the resulting document is serialized with `requireWellFormed: true`, the
         * serializer throws `InvalidStateError` if `.target` contains `:` or is an ASCII
         * case-insensitive match for `"xml"`, or if `.data` contains `?>` or characters outside the
         * XML Char production (W3C DOM Parsing §3.2.1.7). Without that option the data is emitted
         * verbatim.
         *
         * @param {string} target
         * @param {string} data
         * @returns {ProcessingInstruction}
         * @see https://developer.mozilla.org/docs/Web/API/Document/createProcessingInstruction
         * @see https://dom.spec.whatwg.org/#dom-document-createprocessinginstruction
         * @see https://www.w3.org/TR/DOM-Parsing/#dfn-concept-serialize-xml §3.2.1.7
         */
        createProcessingInstruction: function(target, data) {
          var node = new ProcessingInstruction(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.nodeName = node.target = target;
          node.nodeValue = node.data = data;
          return node;
        },
        /**
         * Creates an `Attr` node that is owned by this document.
         * In HTML Documents `localName` is the lower cased `name`,
         * otherwise no transformation is being applied.
         *
         * __This implementation differs from the specification:__ - The provided name is not checked
         * against the `Name` production,
         * so no related error will be thrown.
         *
         * @param {string} name
         * @returns {Attr}
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute
         * @see https://dom.spec.whatwg.org/#dom-document-createattribute
         */
        createAttribute: function(name2) {
          if (!g.QName_exact.test(name2)) {
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'invalid character in name "' + name2 + '"');
          }
          if (this.type === "html") {
            name2 = name2.toLowerCase();
          }
          return this._createAttribute(name2);
        },
        _createAttribute: function(name2) {
          var node = new Attr(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.name = name2;
          node.nodeName = name2;
          node.localName = name2;
          node.specified = true;
          return node;
        },
        /**
         * Creates an EntityReference object.
         * The current implementation does not fill the `childNodes` with those of the corresponding
         * `Entity`
         *
         * @deprecated
         * In DOM Level 4.
         * @param {string} name
         * The name of the entity to reference. No namespace well-formedness checks are performed.
         * @returns {EntityReference}
         * @throws {DOMException}
         * With code `INVALID_CHARACTER_ERR` when `name` is not valid.
         * @throws {DOMException}
         * with code `NOT_SUPPORTED_ERR` when the document is of type `html`
         * @see https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-392B75AE
         */
        createEntityReference: function(name2) {
          if (!g.Name.test(name2)) {
            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, 'not a valid xml name "' + name2 + '"');
          }
          if (this.type === "html") {
            throw new DOMException("document is an html document", DOMExceptionName.NotSupportedError);
          }
          var node = new EntityReference(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.nodeName = name2;
          return node;
        },
        // Introduced in DOM Level 2:
        /**
         * @param {string} namespaceURI
         * @param {string} qualifiedName
         * @returns {Element}
         */
        createElementNS: function(namespaceURI, qualifiedName) {
          var validated = validateAndExtract(namespaceURI, qualifiedName);
          var node = new Element(PDC);
          var attrs = node.attributes = new NamedNodeMap();
          node.childNodes = new NodeList();
          node.ownerDocument = this;
          node.nodeName = qualifiedName;
          node.tagName = qualifiedName;
          node.namespaceURI = validated[0];
          node.prefix = validated[1];
          node.localName = validated[2];
          attrs._ownerElement = node;
          return node;
        },
        // Introduced in DOM Level 2:
        /**
         * @param {string} namespaceURI
         * @param {string} qualifiedName
         * @returns {Attr}
         */
        createAttributeNS: function(namespaceURI, qualifiedName) {
          var validated = validateAndExtract(namespaceURI, qualifiedName);
          var node = new Attr(PDC);
          node.ownerDocument = this;
          node.childNodes = new NodeList();
          node.nodeName = qualifiedName;
          node.name = qualifiedName;
          node.specified = true;
          node.namespaceURI = validated[0];
          node.prefix = validated[1];
          node.localName = validated[2];
          return node;
        }
      };
      _extends(Document, Node);
      function Element(symbol) {
        checkSymbol(symbol);
        this._nsMap = /* @__PURE__ */ Object.create(null);
      }
      Element.prototype = {
        nodeType: ELEMENT_NODE,
        /**
         * The attributes of this element.
         *
         * @type {NamedNodeMap | null}
         */
        attributes: null,
        getQualifiedName: function() {
          return this.prefix ? this.prefix + ":" + this.localName : this.localName;
        },
        _isInHTMLDocumentAndNamespace: function() {
          return this.ownerDocument.type === "html" && this.namespaceURI === NAMESPACE.HTML;
        },
        /**
         * Implementaton of Level2 Core function hasAttributes.
         *
         * @returns {boolean}
         * True if attribute list is not empty.
         * @see https://www.w3.org/TR/DOM-Level-2-Core/#core-ID-NodeHasAttrs
         */
        hasAttributes: function() {
          return !!(this.attributes && this.attributes.length);
        },
        hasAttribute: function(name2) {
          return !!this.getAttributeNode(name2);
        },
        /**
         * Returns element’s first attribute whose qualified name is `name`, and `null`
         * if there is no such attribute.
         *
         * @param {string} name
         * @returns {string | null}
         */
        getAttribute: function(name2) {
          var attr = this.getAttributeNode(name2);
          return attr ? attr.value : null;
        },
        getAttributeNode: function(name2) {
          if (this._isInHTMLDocumentAndNamespace()) {
            name2 = name2.toLowerCase();
          }
          return this.attributes.getNamedItem(name2);
        },
        /**
         * Sets the value of element’s first attribute whose qualified name is qualifiedName to value.
         *
         * @param {string} name
         * @param {string} value
         */
        setAttribute: function(name2, value) {
          if (this._isInHTMLDocumentAndNamespace()) {
            name2 = name2.toLowerCase();
          }
          var attr = this.getAttributeNode(name2);
          if (attr) {
            attr.value = attr.nodeValue = "" + value;
          } else {
            attr = this.ownerDocument._createAttribute(name2);
            attr.value = attr.nodeValue = "" + value;
            this.setAttributeNode(attr);
          }
        },
        removeAttribute: function(name2) {
          var attr = this.getAttributeNode(name2);
          attr && this.removeAttributeNode(attr);
        },
        setAttributeNode: function(newAttr) {
          return this.attributes.setNamedItem(newAttr);
        },
        setAttributeNodeNS: function(newAttr) {
          return this.attributes.setNamedItemNS(newAttr);
        },
        removeAttributeNode: function(oldAttr) {
          return this.attributes.removeNamedItem(oldAttr.nodeName);
        },
        //get real attribute name,and remove it by removeAttributeNode
        removeAttributeNS: function(namespaceURI, localName) {
          var old = this.getAttributeNodeNS(namespaceURI, localName);
          old && this.removeAttributeNode(old);
        },
        hasAttributeNS: function(namespaceURI, localName) {
          return this.getAttributeNodeNS(namespaceURI, localName) != null;
        },
        /**
         * Returns element’s attribute whose namespace is `namespaceURI` and local name is
         * `localName`,
         * or `null` if there is no such attribute.
         *
         * @param {string} namespaceURI
         * @param {string} localName
         * @returns {string | null}
         */
        getAttributeNS: function(namespaceURI, localName) {
          var attr = this.getAttributeNodeNS(namespaceURI, localName);
          return attr ? attr.value : null;
        },
        /**
         * Sets the value of element’s attribute whose namespace is `namespaceURI` and local name is
         * `localName` to value.
         *
         * @param {string} namespaceURI
         * @param {string} qualifiedName
         * @param {string} value
         * @see https://dom.spec.whatwg.org/#dom-element-setattributens
         */
        setAttributeNS: function(namespaceURI, qualifiedName, value) {
          var validated = validateAndExtract(namespaceURI, qualifiedName);
          var localName = validated[2];
          var attr = this.getAttributeNodeNS(namespaceURI, localName);
          if (attr) {
            attr.value = attr.nodeValue = "" + value;
          } else {
            attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
            attr.value = attr.nodeValue = "" + value;
            this.setAttributeNode(attr);
          }
        },
        getAttributeNodeNS: function(namespaceURI, localName) {
          return this.attributes.getNamedItemNS(namespaceURI, localName);
        },
        /**
         * Returns a LiveNodeList of all child elements which have **all** of the given class name(s).
         *
         * Returns an empty list if `classNames` is an empty string or only contains HTML white space
         * characters.
         *
         * Warning: This returns a live LiveNodeList.
         * Changes in the DOM will reflect in the array as the changes occur.
         * If an element selected by this array no longer qualifies for the selector,
         * it will automatically be removed. Be aware of this for iteration purposes.
         *
         * @param {string} classNames
         * Is a string representing the class name(s) to match; multiple class names are separated by
         * (ASCII-)whitespace.
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByClassName
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
         * @see https://dom.spec.whatwg.org/#concept-getelementsbyclassname
         */
        getElementsByClassName: function(classNames) {
          var classNamesSet = toOrderedSet(classNames);
          return new LiveNodeList(this, function(base) {
            var ls = [];
            if (classNamesSet.length > 0) {
              _visitNode(base, function(node) {
                if (node !== base && node.nodeType === ELEMENT_NODE) {
                  var nodeClassNames = node.getAttribute("class");
                  if (nodeClassNames) {
                    var matches = classNames === nodeClassNames;
                    if (!matches) {
                      var nodeClassNamesSet = toOrderedSet(nodeClassNames);
                      matches = classNamesSet.every(arrayIncludes(nodeClassNamesSet));
                    }
                    if (matches) {
                      ls.push(node);
                    }
                  }
                }
              });
            }
            return ls;
          });
        },
        /**
         * Returns a LiveNodeList of elements with the given qualifiedName.
         * Searching for all descendants can be done by passing `*` as `qualifiedName`.
         *
         * All descendants of the specified element are searched, but not the element itself.
         * The returned list is live, which means it updates itself with the DOM tree automatically.
         * Therefore, there is no need to call `Element.getElementsByTagName()`
         * with the same element and arguments repeatedly if the DOM changes in between calls.
         *
         * When called on an HTML element in an HTML document,
         * `getElementsByTagName` lower-cases the argument before searching for it.
         * This is undesirable when trying to match camel-cased SVG elements (such as
         * `<linearGradient>`) in an HTML document.
         * Instead, use `Element.getElementsByTagNameNS()`,
         * which preserves the capitalization of the tag name.
         *
         * `Element.getElementsByTagName` is similar to `Document.getElementsByTagName()`,
         * except that it only searches for elements that are descendants of the specified element.
         *
         * @param {string} qualifiedName
         * @returns {LiveNodeList}
         * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName
         * @see https://dom.spec.whatwg.org/#concept-getelementsbytagname
         */
        getElementsByTagName: function(qualifiedName) {
          var isHTMLDocument = (this.nodeType === DOCUMENT_NODE ? this : this.ownerDocument).type === "html";
          var lowerQualifiedName = qualifiedName.toLowerCase();
          return new LiveNodeList(this, function(base) {
            var ls = [];
            _visitNode(base, function(node) {
              if (node === base || node.nodeType !== ELEMENT_NODE) {
                return;
              }
              if (qualifiedName === "*") {
                ls.push(node);
              } else {
                var nodeQualifiedName = node.getQualifiedName();
                var matchingQName = isHTMLDocument && node.namespaceURI === NAMESPACE.HTML ? lowerQualifiedName : qualifiedName;
                if (nodeQualifiedName === matchingQName) {
                  ls.push(node);
                }
              }
            });
            return ls;
          });
        },
        getElementsByTagNameNS: function(namespaceURI, localName) {
          return new LiveNodeList(this, function(base) {
            var ls = [];
            _visitNode(base, function(node) {
              if (node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === "*" || node.namespaceURI === namespaceURI) && (localName === "*" || node.localName == localName)) {
                ls.push(node);
              }
            });
            return ls;
          });
        }
      };
      Document.prototype.getElementsByClassName = Element.prototype.getElementsByClassName;
      Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
      Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
      _extends(Element, Node);
      function Attr(symbol) {
        checkSymbol(symbol);
        this.namespaceURI = null;
        this.prefix = null;
        this.ownerElement = null;
      }
      Attr.prototype.nodeType = ATTRIBUTE_NODE;
      _extends(Attr, Node);
      function CharacterData(symbol) {
        checkSymbol(symbol);
      }
      CharacterData.prototype = {
        data: "",
        substringData: function(offset, count) {
          return this.data.substring(offset, offset + count);
        },
        appendData: function(text) {
          text = this.data + text;
          this.nodeValue = this.data = text;
          this.length = text.length;
        },
        insertData: function(offset, text) {
          this.replaceData(offset, 0, text);
        },
        deleteData: function(offset, count) {
          this.replaceData(offset, count, "");
        },
        replaceData: function(offset, count, text) {
          var start = this.data.substring(0, offset);
          var end = this.data.substring(offset + count);
          text = start + text + end;
          this.nodeValue = this.data = text;
          this.length = text.length;
        }
      };
      _extends(CharacterData, Node);
      function Text(symbol) {
        checkSymbol(symbol);
      }
      Text.prototype = {
        nodeName: "#text",
        nodeType: TEXT_NODE,
        splitText: function(offset) {
          var text = this.data;
          var newText = text.substring(offset);
          text = text.substring(0, offset);
          this.data = this.nodeValue = text;
          this.length = text.length;
          var newNode = this.ownerDocument.createTextNode(newText);
          if (this.parentNode) {
            this.parentNode.insertBefore(newNode, this.nextSibling);
          }
          return newNode;
        }
      };
      _extends(Text, CharacterData);
      function Comment(symbol) {
        checkSymbol(symbol);
      }
      Comment.prototype = {
        nodeName: "#comment",
        nodeType: COMMENT_NODE
      };
      _extends(Comment, CharacterData);
      function CDATASection(symbol) {
        checkSymbol(symbol);
      }
      CDATASection.prototype = {
        nodeName: "#cdata-section",
        nodeType: CDATA_SECTION_NODE
      };
      _extends(CDATASection, Text);
      function DocumentType(symbol) {
        checkSymbol(symbol);
      }
      DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
      _extends(DocumentType, Node);
      function Notation(symbol) {
        checkSymbol(symbol);
      }
      Notation.prototype.nodeType = NOTATION_NODE;
      _extends(Notation, Node);
      function Entity(symbol) {
        checkSymbol(symbol);
      }
      Entity.prototype.nodeType = ENTITY_NODE;
      _extends(Entity, Node);
      function EntityReference(symbol) {
        checkSymbol(symbol);
      }
      EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
      _extends(EntityReference, Node);
      function DocumentFragment(symbol) {
        checkSymbol(symbol);
      }
      DocumentFragment.prototype.nodeName = "#document-fragment";
      DocumentFragment.prototype.nodeType = DOCUMENT_FRAGMENT_NODE;
      _extends(DocumentFragment, Node);
      function ProcessingInstruction(symbol) {
        checkSymbol(symbol);
      }
      ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
      _extends(ProcessingInstruction, CharacterData);
      function XMLSerializer2() {
      }
      XMLSerializer2.prototype.serializeToString = function(node, options) {
        return nodeSerializeToString.call(node, options);
      };
      Node.prototype.toString = nodeSerializeToString;
      function nodeSerializeToString(options) {
        var opts;
        if (typeof options === "function") {
          opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: options };
        } else if (options != null) {
          opts = {
            requireWellFormed: !!options.requireWellFormed,
            splitCDATASections: options.splitCDATASections !== false,
            nodeFilter: options.nodeFilter || null
          };
        } else {
          opts = { requireWellFormed: false, splitCDATASections: true, nodeFilter: null };
        }
        var buf = [];
        var refNode = this.nodeType === DOCUMENT_NODE && this.documentElement || this;
        var prefix = refNode.prefix;
        var uri = refNode.namespaceURI;
        if (uri && prefix == null) {
          var prefix = refNode.lookupPrefix(uri);
          if (prefix == null) {
            var visibleNamespaces = [
              { namespace: uri, prefix: null }
              //{namespace:uri,prefix:''}
            ];
          }
        }
        serializeToString(this, buf, visibleNamespaces, opts);
        return buf.join("");
      }
      function needNamespaceDefine(node, isHTML, visibleNamespaces) {
        var prefix = node.prefix || "";
        var uri = node.namespaceURI;
        if (!uri) {
          return false;
        }
        if (prefix === "xml" && uri === NAMESPACE.XML || uri === NAMESPACE.XMLNS) {
          return false;
        }
        var i = visibleNamespaces.length;
        while (i--) {
          var ns = visibleNamespaces[i];
          if (ns.prefix === prefix) {
            return ns.namespace !== uri;
          }
        }
        return true;
      }
      function addSerializedAttribute(buf, qualifiedName, value) {
        buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
      }
      function serializeToString(node, buf, visibleNamespaces, opts) {
        if (!visibleNamespaces) {
          visibleNamespaces = [];
        }
        var nodeFilter = opts.nodeFilter;
        var requireWellFormed = opts.requireWellFormed;
        var splitCDATASections = opts.splitCDATASections;
        var doc = node.nodeType === DOCUMENT_NODE ? node : node.ownerDocument;
        var isHTML = doc.type === "html";
        walkDOM(
          node,
          { ns: visibleNamespaces },
          {
            enter: function(n, ctx) {
              var namespaces = ctx.ns;
              if (nodeFilter) {
                n = nodeFilter(n);
                if (n) {
                  if (typeof n == "string") {
                    buf.push(n);
                    return null;
                  }
                } else {
                  return null;
                }
              }
              switch (n.nodeType) {
                case ELEMENT_NODE:
                  var attrs = n.attributes;
                  var len = attrs.length;
                  var nodeName = n.tagName;
                  var prefixedNodeName = nodeName;
                  if (!isHTML && !n.prefix && n.namespaceURI) {
                    var defaultNS;
                    for (var ai = 0; ai < attrs.length; ai++) {
                      if (attrs.item(ai).name === "xmlns") {
                        defaultNS = attrs.item(ai).value;
                        break;
                      }
                    }
                    if (!defaultNS) {
                      for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
                        var nsEntry = namespaces[nsi];
                        if (nsEntry.prefix === "" && nsEntry.namespace === n.namespaceURI) {
                          defaultNS = nsEntry.namespace;
                          break;
                        }
                      }
                    }
                    if (defaultNS !== n.namespaceURI) {
                      for (var nsi = namespaces.length - 1; nsi >= 0; nsi--) {
                        var nsEntry = namespaces[nsi];
                        if (nsEntry.namespace === n.namespaceURI) {
                          if (nsEntry.prefix) {
                            prefixedNodeName = nsEntry.prefix + ":" + nodeName;
                          }
                          break;
                        }
                      }
                    }
                  }
                  buf.push("<", prefixedNodeName);
                  var childNamespaces = namespaces.slice();
                  for (var i = 0; i < len; i++) {
                    var attr = attrs.item(i);
                    if (attr.prefix == "xmlns") {
                      childNamespaces.push({
                        prefix: attr.localName,
                        namespace: attr.value
                      });
                    } else if (attr.nodeName == "xmlns") {
                      childNamespaces.push({ prefix: "", namespace: attr.value });
                    }
                  }
                  for (var i = 0; i < len; i++) {
                    var attr = attrs.item(i);
                    if (needNamespaceDefine(attr, isHTML, childNamespaces)) {
                      var attrPrefix = attr.prefix || "";
                      var uri = attr.namespaceURI;
                      addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri);
                      childNamespaces.push({ prefix: attrPrefix, namespace: uri });
                    }
                    var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
                    if (filteredAttr) {
                      if (typeof filteredAttr === "string") {
                        buf.push(filteredAttr);
                      } else {
                        addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
                      }
                    }
                  }
                  if (nodeName === prefixedNodeName && needNamespaceDefine(n, isHTML, childNamespaces)) {
                    var nodePrefix = n.prefix || "";
                    var uri = n.namespaceURI;
                    addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri);
                    childNamespaces.push({ prefix: nodePrefix, namespace: uri });
                  }
                  var canCloseTag = !n.firstChild;
                  if (canCloseTag && (isHTML || n.namespaceURI === NAMESPACE.HTML)) {
                    canCloseTag = isHTMLVoidElement(nodeName);
                  }
                  if (canCloseTag) {
                    buf.push("/>");
                    return null;
                  }
                  buf.push(">");
                  if (isHTML && isHTMLRawTextElement(nodeName)) {
                    var child = n.firstChild;
                    while (child) {
                      if (child.data) {
                        buf.push(child.data);
                      } else {
                        serializeToString(child, buf, childNamespaces.slice(), opts);
                      }
                      child = child.nextSibling;
                    }
                    buf.push("</", prefixedNodeName, ">");
                    return null;
                  }
                  return { ns: childNamespaces, tag: prefixedNodeName };
                case DOCUMENT_NODE:
                case DOCUMENT_FRAGMENT_NODE:
                  if (requireWellFormed && n.nodeType === DOCUMENT_NODE && n.documentElement == null) {
                    throw new DOMException("The Document has no documentElement", DOMExceptionName.InvalidStateError);
                  }
                  return { ns: namespaces };
                case ATTRIBUTE_NODE:
                  addSerializedAttribute(buf, n.name, n.value);
                  return null;
                case TEXT_NODE:
                  if (requireWellFormed && g.InvalidChar.test(n.data)) {
                    throw new DOMException(
                      "The Text node data contains characters outside the XML Char production",
                      DOMExceptionName.InvalidStateError
                    );
                  }
                  buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
                  return null;
                case CDATA_SECTION_NODE:
                  if (requireWellFormed && n.data.indexOf("]]>") !== -1) {
                    throw new DOMException('The CDATASection data contains "]]>"', DOMExceptionName.InvalidStateError);
                  }
                  if (splitCDATASections) {
                    buf.push(g.CDATA_START, n.data.replace(/]]>/g, "]]]]><![CDATA[>"), g.CDATA_END);
                  } else {
                    buf.push(g.CDATA_START, n.data, g.CDATA_END);
                  }
                  return null;
                case COMMENT_NODE:
                  if (requireWellFormed) {
                    if (g.InvalidChar.test(n.data)) {
                      throw new DOMException(
                        "The comment node data contains characters outside the XML Char production",
                        DOMExceptionName.InvalidStateError
                      );
                    }
                    if (n.data.indexOf("--") !== -1 || n.data[n.data.length - 1] === "-") {
                      throw new DOMException(
                        'The comment node data contains "--" or ends with "-"',
                        DOMExceptionName.InvalidStateError
                      );
                    }
                  }
                  buf.push(g.COMMENT_START, n.data, g.COMMENT_END);
                  return null;
                case DOCUMENT_TYPE_NODE:
                  var pubid = n.publicId;
                  var sysid = n.systemId;
                  if (requireWellFormed) {
                    if (pubid && !g.PubidLiteral_match.test(pubid)) {
                      throw new DOMException("DocumentType publicId is not a valid PubidLiteral", DOMExceptionName.InvalidStateError);
                    }
                    if (sysid && sysid !== "." && !g.SystemLiteral_match.test(sysid)) {
                      throw new DOMException("DocumentType systemId is not a valid SystemLiteral", DOMExceptionName.InvalidStateError);
                    }
                    if (n.internalSubset && n.internalSubset.indexOf("]>") !== -1) {
                      throw new DOMException('DocumentType internalSubset contains "]>"', DOMExceptionName.InvalidStateError);
                    }
                  }
                  buf.push(g.DOCTYPE_DECL_START, " ", n.name);
                  if (pubid) {
                    buf.push(" ", g.PUBLIC, " ", pubid);
                    if (sysid && sysid !== ".") {
                      buf.push(" ", sysid);
                    }
                  } else if (sysid && sysid !== ".") {
                    buf.push(" ", g.SYSTEM, " ", sysid);
                  }
                  if (n.internalSubset) {
                    buf.push(" [", n.internalSubset, "]");
                  }
                  buf.push(">");
                  return null;
                case PROCESSING_INSTRUCTION_NODE:
                  if (requireWellFormed) {
                    if (n.target.indexOf(":") !== -1 || n.target.toLowerCase() === "xml") {
                      throw new DOMException("The ProcessingInstruction target is not well-formed", DOMExceptionName.InvalidStateError);
                    }
                    if (g.InvalidChar.test(n.data)) {
                      throw new DOMException(
                        "The ProcessingInstruction data contains characters outside the XML Char production",
                        DOMExceptionName.InvalidStateError
                      );
                    }
                    if (n.data.indexOf("?>") !== -1) {
                      throw new DOMException('The ProcessingInstruction data contains "?>"', DOMExceptionName.InvalidStateError);
                    }
                  }
                  buf.push("<?", n.target, " ", n.data, "?>");
                  return null;
                case ENTITY_REFERENCE_NODE:
                  buf.push("&", n.nodeName, ";");
                  return null;
                //case ENTITY_NODE:
                //case NOTATION_NODE:
                default:
                  buf.push("??", n.nodeName);
                  return null;
              }
            },
            exit: function(n, childCtx) {
              if (childCtx && childCtx.tag) {
                buf.push("</", childCtx.tag, ">");
              }
            }
          }
        );
      }
      function importNode(doc, node, deep) {
        var destRoot;
        walkDOM(node, null, {
          enter: function(srcNode, destParent) {
            var destNode = srcNode.cloneNode(false);
            destNode.ownerDocument = doc;
            destNode.parentNode = null;
            if (destParent === null) {
              destRoot = destNode;
            } else {
              destParent.appendChild(destNode);
            }
            var shouldDeep = srcNode.nodeType === ATTRIBUTE_NODE || deep;
            return shouldDeep ? destNode : null;
          }
        });
        return destRoot;
      }
      function cloneNode(doc, node, deep) {
        var destRoot;
        walkDOM(node, null, {
          enter: function(srcNode, destParent) {
            var destNode = new srcNode.constructor(PDC);
            for (var n in srcNode) {
              if (hasOwn(srcNode, n)) {
                var v = srcNode[n];
                if (typeof v != "object") {
                  if (v != destNode[n]) {
                    destNode[n] = v;
                  }
                }
              }
            }
            if (srcNode.childNodes) {
              destNode.childNodes = new NodeList();
            }
            destNode.ownerDocument = doc;
            var shouldDeep = deep;
            switch (destNode.nodeType) {
              case ELEMENT_NODE:
                var attrs = srcNode.attributes;
                var attrs2 = destNode.attributes = new NamedNodeMap();
                var len = attrs.length;
                attrs2._ownerElement = destNode;
                for (var i = 0; i < len; i++) {
                  destNode.setAttributeNode(cloneNode(doc, attrs.item(i), true));
                }
                break;
              case ATTRIBUTE_NODE:
                shouldDeep = true;
            }
            if (destParent !== null) {
              destParent.appendChild(destNode);
            } else {
              destRoot = destNode;
            }
            return shouldDeep ? destNode : null;
          }
        });
        return destRoot;
      }
      function __set__(object, key, value) {
        object[key] = value;
      }
      function childrenRefresh(node) {
        var ls = [];
        var child = node.firstChild;
        while (child) {
          if (child.nodeType === ELEMENT_NODE) {
            ls.push(child);
          }
          child = child.nextSibling;
        }
        return ls;
      }
      try {
        if (Object.defineProperty) {
          Object.defineProperty(LiveNodeList.prototype, "length", {
            get: function() {
              _updateLiveList(this);
              return this.$$length;
            }
          });
          Object.defineProperty(Node.prototype, "textContent", {
            get: function() {
              if (this.nodeType === ELEMENT_NODE || this.nodeType === DOCUMENT_FRAGMENT_NODE) {
                var buf = [];
                walkDOM(this, null, {
                  enter: function(n) {
                    if (n.nodeType === ELEMENT_NODE || n.nodeType === DOCUMENT_FRAGMENT_NODE) {
                      return true;
                    }
                    if (n.nodeType === PROCESSING_INSTRUCTION_NODE || n.nodeType === COMMENT_NODE) {
                      return null;
                    }
                    buf.push(n.nodeValue);
                  }
                });
                return buf.join("");
              }
              return this.nodeValue;
            },
            set: function(data) {
              switch (this.nodeType) {
                case ELEMENT_NODE:
                case DOCUMENT_FRAGMENT_NODE:
                  while (this.firstChild) {
                    this.removeChild(this.firstChild);
                  }
                  if (data || String(data)) {
                    this.appendChild(this.ownerDocument.createTextNode(data));
                  }
                  break;
                default:
                  this.data = data;
                  this.value = data;
                  this.nodeValue = data;
              }
            }
          });
          Object.defineProperty(Element.prototype, "children", {
            get: function() {
              return new LiveNodeList(this, childrenRefresh);
            }
          });
          Object.defineProperty(Document.prototype, "children", {
            get: function() {
              return new LiveNodeList(this, childrenRefresh);
            }
          });
          Object.defineProperty(DocumentFragment.prototype, "children", {
            get: function() {
              return new LiveNodeList(this, childrenRefresh);
            }
          });
          __set__ = function(object, key, value) {
            object["$$" + key] = value;
          };
        }
      } catch (e) {
      }
      exports2._updateLiveList = _updateLiveList;
      exports2.Attr = Attr;
      exports2.CDATASection = CDATASection;
      exports2.CharacterData = CharacterData;
      exports2.Comment = Comment;
      exports2.Document = Document;
      exports2.DocumentFragment = DocumentFragment;
      exports2.DocumentType = DocumentType;
      exports2.DOMImplementation = DOMImplementation;
      exports2.Element = Element;
      exports2.Entity = Entity;
      exports2.EntityReference = EntityReference;
      exports2.LiveNodeList = LiveNodeList;
      exports2.NamedNodeMap = NamedNodeMap;
      exports2.Node = Node;
      exports2.NodeList = NodeList;
      exports2.Notation = Notation;
      exports2.Text = Text;
      exports2.ProcessingInstruction = ProcessingInstruction;
      exports2.walkDOM = walkDOM;
      exports2.XMLSerializer = XMLSerializer2;
    }
  });

  // node_modules/@xmldom/xmldom/lib/entities.js
  var require_entities = __commonJS({
    "node_modules/@xmldom/xmldom/lib/entities.js"(exports2) {
      "use strict";
      var freeze = require_conventions().freeze;
      exports2.XML_ENTITIES = freeze({
        amp: "&",
        apos: "'",
        gt: ">",
        lt: "<",
        quot: '"'
      });
      exports2.HTML_ENTITIES = freeze({
        Aacute: "\xC1",
        aacute: "\xE1",
        Abreve: "\u0102",
        abreve: "\u0103",
        ac: "\u223E",
        acd: "\u223F",
        acE: "\u223E\u0333",
        Acirc: "\xC2",
        acirc: "\xE2",
        acute: "\xB4",
        Acy: "\u0410",
        acy: "\u0430",
        AElig: "\xC6",
        aelig: "\xE6",
        af: "\u2061",
        Afr: "\u{1D504}",
        afr: "\u{1D51E}",
        Agrave: "\xC0",
        agrave: "\xE0",
        alefsym: "\u2135",
        aleph: "\u2135",
        Alpha: "\u0391",
        alpha: "\u03B1",
        Amacr: "\u0100",
        amacr: "\u0101",
        amalg: "\u2A3F",
        AMP: "&",
        amp: "&",
        And: "\u2A53",
        and: "\u2227",
        andand: "\u2A55",
        andd: "\u2A5C",
        andslope: "\u2A58",
        andv: "\u2A5A",
        ang: "\u2220",
        ange: "\u29A4",
        angle: "\u2220",
        angmsd: "\u2221",
        angmsdaa: "\u29A8",
        angmsdab: "\u29A9",
        angmsdac: "\u29AA",
        angmsdad: "\u29AB",
        angmsdae: "\u29AC",
        angmsdaf: "\u29AD",
        angmsdag: "\u29AE",
        angmsdah: "\u29AF",
        angrt: "\u221F",
        angrtvb: "\u22BE",
        angrtvbd: "\u299D",
        angsph: "\u2222",
        angst: "\xC5",
        angzarr: "\u237C",
        Aogon: "\u0104",
        aogon: "\u0105",
        Aopf: "\u{1D538}",
        aopf: "\u{1D552}",
        ap: "\u2248",
        apacir: "\u2A6F",
        apE: "\u2A70",
        ape: "\u224A",
        apid: "\u224B",
        apos: "'",
        ApplyFunction: "\u2061",
        approx: "\u2248",
        approxeq: "\u224A",
        Aring: "\xC5",
        aring: "\xE5",
        Ascr: "\u{1D49C}",
        ascr: "\u{1D4B6}",
        Assign: "\u2254",
        ast: "*",
        asymp: "\u2248",
        asympeq: "\u224D",
        Atilde: "\xC3",
        atilde: "\xE3",
        Auml: "\xC4",
        auml: "\xE4",
        awconint: "\u2233",
        awint: "\u2A11",
        backcong: "\u224C",
        backepsilon: "\u03F6",
        backprime: "\u2035",
        backsim: "\u223D",
        backsimeq: "\u22CD",
        Backslash: "\u2216",
        Barv: "\u2AE7",
        barvee: "\u22BD",
        Barwed: "\u2306",
        barwed: "\u2305",
        barwedge: "\u2305",
        bbrk: "\u23B5",
        bbrktbrk: "\u23B6",
        bcong: "\u224C",
        Bcy: "\u0411",
        bcy: "\u0431",
        bdquo: "\u201E",
        becaus: "\u2235",
        Because: "\u2235",
        because: "\u2235",
        bemptyv: "\u29B0",
        bepsi: "\u03F6",
        bernou: "\u212C",
        Bernoullis: "\u212C",
        Beta: "\u0392",
        beta: "\u03B2",
        beth: "\u2136",
        between: "\u226C",
        Bfr: "\u{1D505}",
        bfr: "\u{1D51F}",
        bigcap: "\u22C2",
        bigcirc: "\u25EF",
        bigcup: "\u22C3",
        bigodot: "\u2A00",
        bigoplus: "\u2A01",
        bigotimes: "\u2A02",
        bigsqcup: "\u2A06",
        bigstar: "\u2605",
        bigtriangledown: "\u25BD",
        bigtriangleup: "\u25B3",
        biguplus: "\u2A04",
        bigvee: "\u22C1",
        bigwedge: "\u22C0",
        bkarow: "\u290D",
        blacklozenge: "\u29EB",
        blacksquare: "\u25AA",
        blacktriangle: "\u25B4",
        blacktriangledown: "\u25BE",
        blacktriangleleft: "\u25C2",
        blacktriangleright: "\u25B8",
        blank: "\u2423",
        blk12: "\u2592",
        blk14: "\u2591",
        blk34: "\u2593",
        block: "\u2588",
        bne: "=\u20E5",
        bnequiv: "\u2261\u20E5",
        bNot: "\u2AED",
        bnot: "\u2310",
        Bopf: "\u{1D539}",
        bopf: "\u{1D553}",
        bot: "\u22A5",
        bottom: "\u22A5",
        bowtie: "\u22C8",
        boxbox: "\u29C9",
        boxDL: "\u2557",
        boxDl: "\u2556",
        boxdL: "\u2555",
        boxdl: "\u2510",
        boxDR: "\u2554",
        boxDr: "\u2553",
        boxdR: "\u2552",
        boxdr: "\u250C",
        boxH: "\u2550",
        boxh: "\u2500",
        boxHD: "\u2566",
        boxHd: "\u2564",
        boxhD: "\u2565",
        boxhd: "\u252C",
        boxHU: "\u2569",
        boxHu: "\u2567",
        boxhU: "\u2568",
        boxhu: "\u2534",
        boxminus: "\u229F",
        boxplus: "\u229E",
        boxtimes: "\u22A0",
        boxUL: "\u255D",
        boxUl: "\u255C",
        boxuL: "\u255B",
        boxul: "\u2518",
        boxUR: "\u255A",
        boxUr: "\u2559",
        boxuR: "\u2558",
        boxur: "\u2514",
        boxV: "\u2551",
        boxv: "\u2502",
        boxVH: "\u256C",
        boxVh: "\u256B",
        boxvH: "\u256A",
        boxvh: "\u253C",
        boxVL: "\u2563",
        boxVl: "\u2562",
        boxvL: "\u2561",
        boxvl: "\u2524",
        boxVR: "\u2560",
        boxVr: "\u255F",
        boxvR: "\u255E",
        boxvr: "\u251C",
        bprime: "\u2035",
        Breve: "\u02D8",
        breve: "\u02D8",
        brvbar: "\xA6",
        Bscr: "\u212C",
        bscr: "\u{1D4B7}",
        bsemi: "\u204F",
        bsim: "\u223D",
        bsime: "\u22CD",
        bsol: "\\",
        bsolb: "\u29C5",
        bsolhsub: "\u27C8",
        bull: "\u2022",
        bullet: "\u2022",
        bump: "\u224E",
        bumpE: "\u2AAE",
        bumpe: "\u224F",
        Bumpeq: "\u224E",
        bumpeq: "\u224F",
        Cacute: "\u0106",
        cacute: "\u0107",
        Cap: "\u22D2",
        cap: "\u2229",
        capand: "\u2A44",
        capbrcup: "\u2A49",
        capcap: "\u2A4B",
        capcup: "\u2A47",
        capdot: "\u2A40",
        CapitalDifferentialD: "\u2145",
        caps: "\u2229\uFE00",
        caret: "\u2041",
        caron: "\u02C7",
        Cayleys: "\u212D",
        ccaps: "\u2A4D",
        Ccaron: "\u010C",
        ccaron: "\u010D",
        Ccedil: "\xC7",
        ccedil: "\xE7",
        Ccirc: "\u0108",
        ccirc: "\u0109",
        Cconint: "\u2230",
        ccups: "\u2A4C",
        ccupssm: "\u2A50",
        Cdot: "\u010A",
        cdot: "\u010B",
        cedil: "\xB8",
        Cedilla: "\xB8",
        cemptyv: "\u29B2",
        cent: "\xA2",
        CenterDot: "\xB7",
        centerdot: "\xB7",
        Cfr: "\u212D",
        cfr: "\u{1D520}",
        CHcy: "\u0427",
        chcy: "\u0447",
        check: "\u2713",
        checkmark: "\u2713",
        Chi: "\u03A7",
        chi: "\u03C7",
        cir: "\u25CB",
        circ: "\u02C6",
        circeq: "\u2257",
        circlearrowleft: "\u21BA",
        circlearrowright: "\u21BB",
        circledast: "\u229B",
        circledcirc: "\u229A",
        circleddash: "\u229D",
        CircleDot: "\u2299",
        circledR: "\xAE",
        circledS: "\u24C8",
        CircleMinus: "\u2296",
        CirclePlus: "\u2295",
        CircleTimes: "\u2297",
        cirE: "\u29C3",
        cire: "\u2257",
        cirfnint: "\u2A10",
        cirmid: "\u2AEF",
        cirscir: "\u29C2",
        ClockwiseContourIntegral: "\u2232",
        CloseCurlyDoubleQuote: "\u201D",
        CloseCurlyQuote: "\u2019",
        clubs: "\u2663",
        clubsuit: "\u2663",
        Colon: "\u2237",
        colon: ":",
        Colone: "\u2A74",
        colone: "\u2254",
        coloneq: "\u2254",
        comma: ",",
        commat: "@",
        comp: "\u2201",
        compfn: "\u2218",
        complement: "\u2201",
        complexes: "\u2102",
        cong: "\u2245",
        congdot: "\u2A6D",
        Congruent: "\u2261",
        Conint: "\u222F",
        conint: "\u222E",
        ContourIntegral: "\u222E",
        Copf: "\u2102",
        copf: "\u{1D554}",
        coprod: "\u2210",
        Coproduct: "\u2210",
        COPY: "\xA9",
        copy: "\xA9",
        copysr: "\u2117",
        CounterClockwiseContourIntegral: "\u2233",
        crarr: "\u21B5",
        Cross: "\u2A2F",
        cross: "\u2717",
        Cscr: "\u{1D49E}",
        cscr: "\u{1D4B8}",
        csub: "\u2ACF",
        csube: "\u2AD1",
        csup: "\u2AD0",
        csupe: "\u2AD2",
        ctdot: "\u22EF",
        cudarrl: "\u2938",
        cudarrr: "\u2935",
        cuepr: "\u22DE",
        cuesc: "\u22DF",
        cularr: "\u21B6",
        cularrp: "\u293D",
        Cup: "\u22D3",
        cup: "\u222A",
        cupbrcap: "\u2A48",
        CupCap: "\u224D",
        cupcap: "\u2A46",
        cupcup: "\u2A4A",
        cupdot: "\u228D",
        cupor: "\u2A45",
        cups: "\u222A\uFE00",
        curarr: "\u21B7",
        curarrm: "\u293C",
        curlyeqprec: "\u22DE",
        curlyeqsucc: "\u22DF",
        curlyvee: "\u22CE",
        curlywedge: "\u22CF",
        curren: "\xA4",
        curvearrowleft: "\u21B6",
        curvearrowright: "\u21B7",
        cuvee: "\u22CE",
        cuwed: "\u22CF",
        cwconint: "\u2232",
        cwint: "\u2231",
        cylcty: "\u232D",
        Dagger: "\u2021",
        dagger: "\u2020",
        daleth: "\u2138",
        Darr: "\u21A1",
        dArr: "\u21D3",
        darr: "\u2193",
        dash: "\u2010",
        Dashv: "\u2AE4",
        dashv: "\u22A3",
        dbkarow: "\u290F",
        dblac: "\u02DD",
        Dcaron: "\u010E",
        dcaron: "\u010F",
        Dcy: "\u0414",
        dcy: "\u0434",
        DD: "\u2145",
        dd: "\u2146",
        ddagger: "\u2021",
        ddarr: "\u21CA",
        DDotrahd: "\u2911",
        ddotseq: "\u2A77",
        deg: "\xB0",
        Del: "\u2207",
        Delta: "\u0394",
        delta: "\u03B4",
        demptyv: "\u29B1",
        dfisht: "\u297F",
        Dfr: "\u{1D507}",
        dfr: "\u{1D521}",
        dHar: "\u2965",
        dharl: "\u21C3",
        dharr: "\u21C2",
        DiacriticalAcute: "\xB4",
        DiacriticalDot: "\u02D9",
        DiacriticalDoubleAcute: "\u02DD",
        DiacriticalGrave: "`",
        DiacriticalTilde: "\u02DC",
        diam: "\u22C4",
        Diamond: "\u22C4",
        diamond: "\u22C4",
        diamondsuit: "\u2666",
        diams: "\u2666",
        die: "\xA8",
        DifferentialD: "\u2146",
        digamma: "\u03DD",
        disin: "\u22F2",
        div: "\xF7",
        divide: "\xF7",
        divideontimes: "\u22C7",
        divonx: "\u22C7",
        DJcy: "\u0402",
        djcy: "\u0452",
        dlcorn: "\u231E",
        dlcrop: "\u230D",
        dollar: "$",
        Dopf: "\u{1D53B}",
        dopf: "\u{1D555}",
        Dot: "\xA8",
        dot: "\u02D9",
        DotDot: "\u20DC",
        doteq: "\u2250",
        doteqdot: "\u2251",
        DotEqual: "\u2250",
        dotminus: "\u2238",
        dotplus: "\u2214",
        dotsquare: "\u22A1",
        doublebarwedge: "\u2306",
        DoubleContourIntegral: "\u222F",
        DoubleDot: "\xA8",
        DoubleDownArrow: "\u21D3",
        DoubleLeftArrow: "\u21D0",
        DoubleLeftRightArrow: "\u21D4",
        DoubleLeftTee: "\u2AE4",
        DoubleLongLeftArrow: "\u27F8",
        DoubleLongLeftRightArrow: "\u27FA",
        DoubleLongRightArrow: "\u27F9",
        DoubleRightArrow: "\u21D2",
        DoubleRightTee: "\u22A8",
        DoubleUpArrow: "\u21D1",
        DoubleUpDownArrow: "\u21D5",
        DoubleVerticalBar: "\u2225",
        DownArrow: "\u2193",
        Downarrow: "\u21D3",
        downarrow: "\u2193",
        DownArrowBar: "\u2913",
        DownArrowUpArrow: "\u21F5",
        DownBreve: "\u0311",
        downdownarrows: "\u21CA",
        downharpoonleft: "\u21C3",
        downharpoonright: "\u21C2",
        DownLeftRightVector: "\u2950",
        DownLeftTeeVector: "\u295E",
        DownLeftVector: "\u21BD",
        DownLeftVectorBar: "\u2956",
        DownRightTeeVector: "\u295F",
        DownRightVector: "\u21C1",
        DownRightVectorBar: "\u2957",
        DownTee: "\u22A4",
        DownTeeArrow: "\u21A7",
        drbkarow: "\u2910",
        drcorn: "\u231F",
        drcrop: "\u230C",
        Dscr: "\u{1D49F}",
        dscr: "\u{1D4B9}",
        DScy: "\u0405",
        dscy: "\u0455",
        dsol: "\u29F6",
        Dstrok: "\u0110",
        dstrok: "\u0111",
        dtdot: "\u22F1",
        dtri: "\u25BF",
        dtrif: "\u25BE",
        duarr: "\u21F5",
        duhar: "\u296F",
        dwangle: "\u29A6",
        DZcy: "\u040F",
        dzcy: "\u045F",
        dzigrarr: "\u27FF",
        Eacute: "\xC9",
        eacute: "\xE9",
        easter: "\u2A6E",
        Ecaron: "\u011A",
        ecaron: "\u011B",
        ecir: "\u2256",
        Ecirc: "\xCA",
        ecirc: "\xEA",
        ecolon: "\u2255",
        Ecy: "\u042D",
        ecy: "\u044D",
        eDDot: "\u2A77",
        Edot: "\u0116",
        eDot: "\u2251",
        edot: "\u0117",
        ee: "\u2147",
        efDot: "\u2252",
        Efr: "\u{1D508}",
        efr: "\u{1D522}",
        eg: "\u2A9A",
        Egrave: "\xC8",
        egrave: "\xE8",
        egs: "\u2A96",
        egsdot: "\u2A98",
        el: "\u2A99",
        Element: "\u2208",
        elinters: "\u23E7",
        ell: "\u2113",
        els: "\u2A95",
        elsdot: "\u2A97",
        Emacr: "\u0112",
        emacr: "\u0113",
        empty: "\u2205",
        emptyset: "\u2205",
        EmptySmallSquare: "\u25FB",
        emptyv: "\u2205",
        EmptyVerySmallSquare: "\u25AB",
        emsp: "\u2003",
        emsp13: "\u2004",
        emsp14: "\u2005",
        ENG: "\u014A",
        eng: "\u014B",
        ensp: "\u2002",
        Eogon: "\u0118",
        eogon: "\u0119",
        Eopf: "\u{1D53C}",
        eopf: "\u{1D556}",
        epar: "\u22D5",
        eparsl: "\u29E3",
        eplus: "\u2A71",
        epsi: "\u03B5",
        Epsilon: "\u0395",
        epsilon: "\u03B5",
        epsiv: "\u03F5",
        eqcirc: "\u2256",
        eqcolon: "\u2255",
        eqsim: "\u2242",
        eqslantgtr: "\u2A96",
        eqslantless: "\u2A95",
        Equal: "\u2A75",
        equals: "=",
        EqualTilde: "\u2242",
        equest: "\u225F",
        Equilibrium: "\u21CC",
        equiv: "\u2261",
        equivDD: "\u2A78",
        eqvparsl: "\u29E5",
        erarr: "\u2971",
        erDot: "\u2253",
        Escr: "\u2130",
        escr: "\u212F",
        esdot: "\u2250",
        Esim: "\u2A73",
        esim: "\u2242",
        Eta: "\u0397",
        eta: "\u03B7",
        ETH: "\xD0",
        eth: "\xF0",
        Euml: "\xCB",
        euml: "\xEB",
        euro: "\u20AC",
        excl: "!",
        exist: "\u2203",
        Exists: "\u2203",
        expectation: "\u2130",
        ExponentialE: "\u2147",
        exponentiale: "\u2147",
        fallingdotseq: "\u2252",
        Fcy: "\u0424",
        fcy: "\u0444",
        female: "\u2640",
        ffilig: "\uFB03",
        fflig: "\uFB00",
        ffllig: "\uFB04",
        Ffr: "\u{1D509}",
        ffr: "\u{1D523}",
        filig: "\uFB01",
        FilledSmallSquare: "\u25FC",
        FilledVerySmallSquare: "\u25AA",
        fjlig: "fj",
        flat: "\u266D",
        fllig: "\uFB02",
        fltns: "\u25B1",
        fnof: "\u0192",
        Fopf: "\u{1D53D}",
        fopf: "\u{1D557}",
        ForAll: "\u2200",
        forall: "\u2200",
        fork: "\u22D4",
        forkv: "\u2AD9",
        Fouriertrf: "\u2131",
        fpartint: "\u2A0D",
        frac12: "\xBD",
        frac13: "\u2153",
        frac14: "\xBC",
        frac15: "\u2155",
        frac16: "\u2159",
        frac18: "\u215B",
        frac23: "\u2154",
        frac25: "\u2156",
        frac34: "\xBE",
        frac35: "\u2157",
        frac38: "\u215C",
        frac45: "\u2158",
        frac56: "\u215A",
        frac58: "\u215D",
        frac78: "\u215E",
        frasl: "\u2044",
        frown: "\u2322",
        Fscr: "\u2131",
        fscr: "\u{1D4BB}",
        gacute: "\u01F5",
        Gamma: "\u0393",
        gamma: "\u03B3",
        Gammad: "\u03DC",
        gammad: "\u03DD",
        gap: "\u2A86",
        Gbreve: "\u011E",
        gbreve: "\u011F",
        Gcedil: "\u0122",
        Gcirc: "\u011C",
        gcirc: "\u011D",
        Gcy: "\u0413",
        gcy: "\u0433",
        Gdot: "\u0120",
        gdot: "\u0121",
        gE: "\u2267",
        ge: "\u2265",
        gEl: "\u2A8C",
        gel: "\u22DB",
        geq: "\u2265",
        geqq: "\u2267",
        geqslant: "\u2A7E",
        ges: "\u2A7E",
        gescc: "\u2AA9",
        gesdot: "\u2A80",
        gesdoto: "\u2A82",
        gesdotol: "\u2A84",
        gesl: "\u22DB\uFE00",
        gesles: "\u2A94",
        Gfr: "\u{1D50A}",
        gfr: "\u{1D524}",
        Gg: "\u22D9",
        gg: "\u226B",
        ggg: "\u22D9",
        gimel: "\u2137",
        GJcy: "\u0403",
        gjcy: "\u0453",
        gl: "\u2277",
        gla: "\u2AA5",
        glE: "\u2A92",
        glj: "\u2AA4",
        gnap: "\u2A8A",
        gnapprox: "\u2A8A",
        gnE: "\u2269",
        gne: "\u2A88",
        gneq: "\u2A88",
        gneqq: "\u2269",
        gnsim: "\u22E7",
        Gopf: "\u{1D53E}",
        gopf: "\u{1D558}",
        grave: "`",
        GreaterEqual: "\u2265",
        GreaterEqualLess: "\u22DB",
        GreaterFullEqual: "\u2267",
        GreaterGreater: "\u2AA2",
        GreaterLess: "\u2277",
        GreaterSlantEqual: "\u2A7E",
        GreaterTilde: "\u2273",
        Gscr: "\u{1D4A2}",
        gscr: "\u210A",
        gsim: "\u2273",
        gsime: "\u2A8E",
        gsiml: "\u2A90",
        Gt: "\u226B",
        GT: ">",
        gt: ">",
        gtcc: "\u2AA7",
        gtcir: "\u2A7A",
        gtdot: "\u22D7",
        gtlPar: "\u2995",
        gtquest: "\u2A7C",
        gtrapprox: "\u2A86",
        gtrarr: "\u2978",
        gtrdot: "\u22D7",
        gtreqless: "\u22DB",
        gtreqqless: "\u2A8C",
        gtrless: "\u2277",
        gtrsim: "\u2273",
        gvertneqq: "\u2269\uFE00",
        gvnE: "\u2269\uFE00",
        Hacek: "\u02C7",
        hairsp: "\u200A",
        half: "\xBD",
        hamilt: "\u210B",
        HARDcy: "\u042A",
        hardcy: "\u044A",
        hArr: "\u21D4",
        harr: "\u2194",
        harrcir: "\u2948",
        harrw: "\u21AD",
        Hat: "^",
        hbar: "\u210F",
        Hcirc: "\u0124",
        hcirc: "\u0125",
        hearts: "\u2665",
        heartsuit: "\u2665",
        hellip: "\u2026",
        hercon: "\u22B9",
        Hfr: "\u210C",
        hfr: "\u{1D525}",
        HilbertSpace: "\u210B",
        hksearow: "\u2925",
        hkswarow: "\u2926",
        hoarr: "\u21FF",
        homtht: "\u223B",
        hookleftarrow: "\u21A9",
        hookrightarrow: "\u21AA",
        Hopf: "\u210D",
        hopf: "\u{1D559}",
        horbar: "\u2015",
        HorizontalLine: "\u2500",
        Hscr: "\u210B",
        hscr: "\u{1D4BD}",
        hslash: "\u210F",
        Hstrok: "\u0126",
        hstrok: "\u0127",
        HumpDownHump: "\u224E",
        HumpEqual: "\u224F",
        hybull: "\u2043",
        hyphen: "\u2010",
        Iacute: "\xCD",
        iacute: "\xED",
        ic: "\u2063",
        Icirc: "\xCE",
        icirc: "\xEE",
        Icy: "\u0418",
        icy: "\u0438",
        Idot: "\u0130",
        IEcy: "\u0415",
        iecy: "\u0435",
        iexcl: "\xA1",
        iff: "\u21D4",
        Ifr: "\u2111",
        ifr: "\u{1D526}",
        Igrave: "\xCC",
        igrave: "\xEC",
        ii: "\u2148",
        iiiint: "\u2A0C",
        iiint: "\u222D",
        iinfin: "\u29DC",
        iiota: "\u2129",
        IJlig: "\u0132",
        ijlig: "\u0133",
        Im: "\u2111",
        Imacr: "\u012A",
        imacr: "\u012B",
        image: "\u2111",
        ImaginaryI: "\u2148",
        imagline: "\u2110",
        imagpart: "\u2111",
        imath: "\u0131",
        imof: "\u22B7",
        imped: "\u01B5",
        Implies: "\u21D2",
        in: "\u2208",
        incare: "\u2105",
        infin: "\u221E",
        infintie: "\u29DD",
        inodot: "\u0131",
        Int: "\u222C",
        int: "\u222B",
        intcal: "\u22BA",
        integers: "\u2124",
        Integral: "\u222B",
        intercal: "\u22BA",
        Intersection: "\u22C2",
        intlarhk: "\u2A17",
        intprod: "\u2A3C",
        InvisibleComma: "\u2063",
        InvisibleTimes: "\u2062",
        IOcy: "\u0401",
        iocy: "\u0451",
        Iogon: "\u012E",
        iogon: "\u012F",
        Iopf: "\u{1D540}",
        iopf: "\u{1D55A}",
        Iota: "\u0399",
        iota: "\u03B9",
        iprod: "\u2A3C",
        iquest: "\xBF",
        Iscr: "\u2110",
        iscr: "\u{1D4BE}",
        isin: "\u2208",
        isindot: "\u22F5",
        isinE: "\u22F9",
        isins: "\u22F4",
        isinsv: "\u22F3",
        isinv: "\u2208",
        it: "\u2062",
        Itilde: "\u0128",
        itilde: "\u0129",
        Iukcy: "\u0406",
        iukcy: "\u0456",
        Iuml: "\xCF",
        iuml: "\xEF",
        Jcirc: "\u0134",
        jcirc: "\u0135",
        Jcy: "\u0419",
        jcy: "\u0439",
        Jfr: "\u{1D50D}",
        jfr: "\u{1D527}",
        jmath: "\u0237",
        Jopf: "\u{1D541}",
        jopf: "\u{1D55B}",
        Jscr: "\u{1D4A5}",
        jscr: "\u{1D4BF}",
        Jsercy: "\u0408",
        jsercy: "\u0458",
        Jukcy: "\u0404",
        jukcy: "\u0454",
        Kappa: "\u039A",
        kappa: "\u03BA",
        kappav: "\u03F0",
        Kcedil: "\u0136",
        kcedil: "\u0137",
        Kcy: "\u041A",
        kcy: "\u043A",
        Kfr: "\u{1D50E}",
        kfr: "\u{1D528}",
        kgreen: "\u0138",
        KHcy: "\u0425",
        khcy: "\u0445",
        KJcy: "\u040C",
        kjcy: "\u045C",
        Kopf: "\u{1D542}",
        kopf: "\u{1D55C}",
        Kscr: "\u{1D4A6}",
        kscr: "\u{1D4C0}",
        lAarr: "\u21DA",
        Lacute: "\u0139",
        lacute: "\u013A",
        laemptyv: "\u29B4",
        lagran: "\u2112",
        Lambda: "\u039B",
        lambda: "\u03BB",
        Lang: "\u27EA",
        lang: "\u27E8",
        langd: "\u2991",
        langle: "\u27E8",
        lap: "\u2A85",
        Laplacetrf: "\u2112",
        laquo: "\xAB",
        Larr: "\u219E",
        lArr: "\u21D0",
        larr: "\u2190",
        larrb: "\u21E4",
        larrbfs: "\u291F",
        larrfs: "\u291D",
        larrhk: "\u21A9",
        larrlp: "\u21AB",
        larrpl: "\u2939",
        larrsim: "\u2973",
        larrtl: "\u21A2",
        lat: "\u2AAB",
        lAtail: "\u291B",
        latail: "\u2919",
        late: "\u2AAD",
        lates: "\u2AAD\uFE00",
        lBarr: "\u290E",
        lbarr: "\u290C",
        lbbrk: "\u2772",
        lbrace: "{",
        lbrack: "[",
        lbrke: "\u298B",
        lbrksld: "\u298F",
        lbrkslu: "\u298D",
        Lcaron: "\u013D",
        lcaron: "\u013E",
        Lcedil: "\u013B",
        lcedil: "\u013C",
        lceil: "\u2308",
        lcub: "{",
        Lcy: "\u041B",
        lcy: "\u043B",
        ldca: "\u2936",
        ldquo: "\u201C",
        ldquor: "\u201E",
        ldrdhar: "\u2967",
        ldrushar: "\u294B",
        ldsh: "\u21B2",
        lE: "\u2266",
        le: "\u2264",
        LeftAngleBracket: "\u27E8",
        LeftArrow: "\u2190",
        Leftarrow: "\u21D0",
        leftarrow: "\u2190",
        LeftArrowBar: "\u21E4",
        LeftArrowRightArrow: "\u21C6",
        leftarrowtail: "\u21A2",
        LeftCeiling: "\u2308",
        LeftDoubleBracket: "\u27E6",
        LeftDownTeeVector: "\u2961",
        LeftDownVector: "\u21C3",
        LeftDownVectorBar: "\u2959",
        LeftFloor: "\u230A",
        leftharpoondown: "\u21BD",
        leftharpoonup: "\u21BC",
        leftleftarrows: "\u21C7",
        LeftRightArrow: "\u2194",
        Leftrightarrow: "\u21D4",
        leftrightarrow: "\u2194",
        leftrightarrows: "\u21C6",
        leftrightharpoons: "\u21CB",
        leftrightsquigarrow: "\u21AD",
        LeftRightVector: "\u294E",
        LeftTee: "\u22A3",
        LeftTeeArrow: "\u21A4",
        LeftTeeVector: "\u295A",
        leftthreetimes: "\u22CB",
        LeftTriangle: "\u22B2",
        LeftTriangleBar: "\u29CF",
        LeftTriangleEqual: "\u22B4",
        LeftUpDownVector: "\u2951",
        LeftUpTeeVector: "\u2960",
        LeftUpVector: "\u21BF",
        LeftUpVectorBar: "\u2958",
        LeftVector: "\u21BC",
        LeftVectorBar: "\u2952",
        lEg: "\u2A8B",
        leg: "\u22DA",
        leq: "\u2264",
        leqq: "\u2266",
        leqslant: "\u2A7D",
        les: "\u2A7D",
        lescc: "\u2AA8",
        lesdot: "\u2A7F",
        lesdoto: "\u2A81",
        lesdotor: "\u2A83",
        lesg: "\u22DA\uFE00",
        lesges: "\u2A93",
        lessapprox: "\u2A85",
        lessdot: "\u22D6",
        lesseqgtr: "\u22DA",
        lesseqqgtr: "\u2A8B",
        LessEqualGreater: "\u22DA",
        LessFullEqual: "\u2266",
        LessGreater: "\u2276",
        lessgtr: "\u2276",
        LessLess: "\u2AA1",
        lesssim: "\u2272",
        LessSlantEqual: "\u2A7D",
        LessTilde: "\u2272",
        lfisht: "\u297C",
        lfloor: "\u230A",
        Lfr: "\u{1D50F}",
        lfr: "\u{1D529}",
        lg: "\u2276",
        lgE: "\u2A91",
        lHar: "\u2962",
        lhard: "\u21BD",
        lharu: "\u21BC",
        lharul: "\u296A",
        lhblk: "\u2584",
        LJcy: "\u0409",
        ljcy: "\u0459",
        Ll: "\u22D8",
        ll: "\u226A",
        llarr: "\u21C7",
        llcorner: "\u231E",
        Lleftarrow: "\u21DA",
        llhard: "\u296B",
        lltri: "\u25FA",
        Lmidot: "\u013F",
        lmidot: "\u0140",
        lmoust: "\u23B0",
        lmoustache: "\u23B0",
        lnap: "\u2A89",
        lnapprox: "\u2A89",
        lnE: "\u2268",
        lne: "\u2A87",
        lneq: "\u2A87",
        lneqq: "\u2268",
        lnsim: "\u22E6",
        loang: "\u27EC",
        loarr: "\u21FD",
        lobrk: "\u27E6",
        LongLeftArrow: "\u27F5",
        Longleftarrow: "\u27F8",
        longleftarrow: "\u27F5",
        LongLeftRightArrow: "\u27F7",
        Longleftrightarrow: "\u27FA",
        longleftrightarrow: "\u27F7",
        longmapsto: "\u27FC",
        LongRightArrow: "\u27F6",
        Longrightarrow: "\u27F9",
        longrightarrow: "\u27F6",
        looparrowleft: "\u21AB",
        looparrowright: "\u21AC",
        lopar: "\u2985",
        Lopf: "\u{1D543}",
        lopf: "\u{1D55D}",
        loplus: "\u2A2D",
        lotimes: "\u2A34",
        lowast: "\u2217",
        lowbar: "_",
        LowerLeftArrow: "\u2199",
        LowerRightArrow: "\u2198",
        loz: "\u25CA",
        lozenge: "\u25CA",
        lozf: "\u29EB",
        lpar: "(",
        lparlt: "\u2993",
        lrarr: "\u21C6",
        lrcorner: "\u231F",
        lrhar: "\u21CB",
        lrhard: "\u296D",
        lrm: "\u200E",
        lrtri: "\u22BF",
        lsaquo: "\u2039",
        Lscr: "\u2112",
        lscr: "\u{1D4C1}",
        Lsh: "\u21B0",
        lsh: "\u21B0",
        lsim: "\u2272",
        lsime: "\u2A8D",
        lsimg: "\u2A8F",
        lsqb: "[",
        lsquo: "\u2018",
        lsquor: "\u201A",
        Lstrok: "\u0141",
        lstrok: "\u0142",
        Lt: "\u226A",
        LT: "<",
        lt: "<",
        ltcc: "\u2AA6",
        ltcir: "\u2A79",
        ltdot: "\u22D6",
        lthree: "\u22CB",
        ltimes: "\u22C9",
        ltlarr: "\u2976",
        ltquest: "\u2A7B",
        ltri: "\u25C3",
        ltrie: "\u22B4",
        ltrif: "\u25C2",
        ltrPar: "\u2996",
        lurdshar: "\u294A",
        luruhar: "\u2966",
        lvertneqq: "\u2268\uFE00",
        lvnE: "\u2268\uFE00",
        macr: "\xAF",
        male: "\u2642",
        malt: "\u2720",
        maltese: "\u2720",
        Map: "\u2905",
        map: "\u21A6",
        mapsto: "\u21A6",
        mapstodown: "\u21A7",
        mapstoleft: "\u21A4",
        mapstoup: "\u21A5",
        marker: "\u25AE",
        mcomma: "\u2A29",
        Mcy: "\u041C",
        mcy: "\u043C",
        mdash: "\u2014",
        mDDot: "\u223A",
        measuredangle: "\u2221",
        MediumSpace: "\u205F",
        Mellintrf: "\u2133",
        Mfr: "\u{1D510}",
        mfr: "\u{1D52A}",
        mho: "\u2127",
        micro: "\xB5",
        mid: "\u2223",
        midast: "*",
        midcir: "\u2AF0",
        middot: "\xB7",
        minus: "\u2212",
        minusb: "\u229F",
        minusd: "\u2238",
        minusdu: "\u2A2A",
        MinusPlus: "\u2213",
        mlcp: "\u2ADB",
        mldr: "\u2026",
        mnplus: "\u2213",
        models: "\u22A7",
        Mopf: "\u{1D544}",
        mopf: "\u{1D55E}",
        mp: "\u2213",
        Mscr: "\u2133",
        mscr: "\u{1D4C2}",
        mstpos: "\u223E",
        Mu: "\u039C",
        mu: "\u03BC",
        multimap: "\u22B8",
        mumap: "\u22B8",
        nabla: "\u2207",
        Nacute: "\u0143",
        nacute: "\u0144",
        nang: "\u2220\u20D2",
        nap: "\u2249",
        napE: "\u2A70\u0338",
        napid: "\u224B\u0338",
        napos: "\u0149",
        napprox: "\u2249",
        natur: "\u266E",
        natural: "\u266E",
        naturals: "\u2115",
        nbsp: "\xA0",
        nbump: "\u224E\u0338",
        nbumpe: "\u224F\u0338",
        ncap: "\u2A43",
        Ncaron: "\u0147",
        ncaron: "\u0148",
        Ncedil: "\u0145",
        ncedil: "\u0146",
        ncong: "\u2247",
        ncongdot: "\u2A6D\u0338",
        ncup: "\u2A42",
        Ncy: "\u041D",
        ncy: "\u043D",
        ndash: "\u2013",
        ne: "\u2260",
        nearhk: "\u2924",
        neArr: "\u21D7",
        nearr: "\u2197",
        nearrow: "\u2197",
        nedot: "\u2250\u0338",
        NegativeMediumSpace: "\u200B",
        NegativeThickSpace: "\u200B",
        NegativeThinSpace: "\u200B",
        NegativeVeryThinSpace: "\u200B",
        nequiv: "\u2262",
        nesear: "\u2928",
        nesim: "\u2242\u0338",
        NestedGreaterGreater: "\u226B",
        NestedLessLess: "\u226A",
        NewLine: "\n",
        nexist: "\u2204",
        nexists: "\u2204",
        Nfr: "\u{1D511}",
        nfr: "\u{1D52B}",
        ngE: "\u2267\u0338",
        nge: "\u2271",
        ngeq: "\u2271",
        ngeqq: "\u2267\u0338",
        ngeqslant: "\u2A7E\u0338",
        nges: "\u2A7E\u0338",
        nGg: "\u22D9\u0338",
        ngsim: "\u2275",
        nGt: "\u226B\u20D2",
        ngt: "\u226F",
        ngtr: "\u226F",
        nGtv: "\u226B\u0338",
        nhArr: "\u21CE",
        nharr: "\u21AE",
        nhpar: "\u2AF2",
        ni: "\u220B",
        nis: "\u22FC",
        nisd: "\u22FA",
        niv: "\u220B",
        NJcy: "\u040A",
        njcy: "\u045A",
        nlArr: "\u21CD",
        nlarr: "\u219A",
        nldr: "\u2025",
        nlE: "\u2266\u0338",
        nle: "\u2270",
        nLeftarrow: "\u21CD",
        nleftarrow: "\u219A",
        nLeftrightarrow: "\u21CE",
        nleftrightarrow: "\u21AE",
        nleq: "\u2270",
        nleqq: "\u2266\u0338",
        nleqslant: "\u2A7D\u0338",
        nles: "\u2A7D\u0338",
        nless: "\u226E",
        nLl: "\u22D8\u0338",
        nlsim: "\u2274",
        nLt: "\u226A\u20D2",
        nlt: "\u226E",
        nltri: "\u22EA",
        nltrie: "\u22EC",
        nLtv: "\u226A\u0338",
        nmid: "\u2224",
        NoBreak: "\u2060",
        NonBreakingSpace: "\xA0",
        Nopf: "\u2115",
        nopf: "\u{1D55F}",
        Not: "\u2AEC",
        not: "\xAC",
        NotCongruent: "\u2262",
        NotCupCap: "\u226D",
        NotDoubleVerticalBar: "\u2226",
        NotElement: "\u2209",
        NotEqual: "\u2260",
        NotEqualTilde: "\u2242\u0338",
        NotExists: "\u2204",
        NotGreater: "\u226F",
        NotGreaterEqual: "\u2271",
        NotGreaterFullEqual: "\u2267\u0338",
        NotGreaterGreater: "\u226B\u0338",
        NotGreaterLess: "\u2279",
        NotGreaterSlantEqual: "\u2A7E\u0338",
        NotGreaterTilde: "\u2275",
        NotHumpDownHump: "\u224E\u0338",
        NotHumpEqual: "\u224F\u0338",
        notin: "\u2209",
        notindot: "\u22F5\u0338",
        notinE: "\u22F9\u0338",
        notinva: "\u2209",
        notinvb: "\u22F7",
        notinvc: "\u22F6",
        NotLeftTriangle: "\u22EA",
        NotLeftTriangleBar: "\u29CF\u0338",
        NotLeftTriangleEqual: "\u22EC",
        NotLess: "\u226E",
        NotLessEqual: "\u2270",
        NotLessGreater: "\u2278",
        NotLessLess: "\u226A\u0338",
        NotLessSlantEqual: "\u2A7D\u0338",
        NotLessTilde: "\u2274",
        NotNestedGreaterGreater: "\u2AA2\u0338",
        NotNestedLessLess: "\u2AA1\u0338",
        notni: "\u220C",
        notniva: "\u220C",
        notnivb: "\u22FE",
        notnivc: "\u22FD",
        NotPrecedes: "\u2280",
        NotPrecedesEqual: "\u2AAF\u0338",
        NotPrecedesSlantEqual: "\u22E0",
        NotReverseElement: "\u220C",
        NotRightTriangle: "\u22EB",
        NotRightTriangleBar: "\u29D0\u0338",
        NotRightTriangleEqual: "\u22ED",
        NotSquareSubset: "\u228F\u0338",
        NotSquareSubsetEqual: "\u22E2",
        NotSquareSuperset: "\u2290\u0338",
        NotSquareSupersetEqual: "\u22E3",
        NotSubset: "\u2282\u20D2",
        NotSubsetEqual: "\u2288",
        NotSucceeds: "\u2281",
        NotSucceedsEqual: "\u2AB0\u0338",
        NotSucceedsSlantEqual: "\u22E1",
        NotSucceedsTilde: "\u227F\u0338",
        NotSuperset: "\u2283\u20D2",
        NotSupersetEqual: "\u2289",
        NotTilde: "\u2241",
        NotTildeEqual: "\u2244",
        NotTildeFullEqual: "\u2247",
        NotTildeTilde: "\u2249",
        NotVerticalBar: "\u2224",
        npar: "\u2226",
        nparallel: "\u2226",
        nparsl: "\u2AFD\u20E5",
        npart: "\u2202\u0338",
        npolint: "\u2A14",
        npr: "\u2280",
        nprcue: "\u22E0",
        npre: "\u2AAF\u0338",
        nprec: "\u2280",
        npreceq: "\u2AAF\u0338",
        nrArr: "\u21CF",
        nrarr: "\u219B",
        nrarrc: "\u2933\u0338",
        nrarrw: "\u219D\u0338",
        nRightarrow: "\u21CF",
        nrightarrow: "\u219B",
        nrtri: "\u22EB",
        nrtrie: "\u22ED",
        nsc: "\u2281",
        nsccue: "\u22E1",
        nsce: "\u2AB0\u0338",
        Nscr: "\u{1D4A9}",
        nscr: "\u{1D4C3}",
        nshortmid: "\u2224",
        nshortparallel: "\u2226",
        nsim: "\u2241",
        nsime: "\u2244",
        nsimeq: "\u2244",
        nsmid: "\u2224",
        nspar: "\u2226",
        nsqsube: "\u22E2",
        nsqsupe: "\u22E3",
        nsub: "\u2284",
        nsubE: "\u2AC5\u0338",
        nsube: "\u2288",
        nsubset: "\u2282\u20D2",
        nsubseteq: "\u2288",
        nsubseteqq: "\u2AC5\u0338",
        nsucc: "\u2281",
        nsucceq: "\u2AB0\u0338",
        nsup: "\u2285",
        nsupE: "\u2AC6\u0338",
        nsupe: "\u2289",
        nsupset: "\u2283\u20D2",
        nsupseteq: "\u2289",
        nsupseteqq: "\u2AC6\u0338",
        ntgl: "\u2279",
        Ntilde: "\xD1",
        ntilde: "\xF1",
        ntlg: "\u2278",
        ntriangleleft: "\u22EA",
        ntrianglelefteq: "\u22EC",
        ntriangleright: "\u22EB",
        ntrianglerighteq: "\u22ED",
        Nu: "\u039D",
        nu: "\u03BD",
        num: "#",
        numero: "\u2116",
        numsp: "\u2007",
        nvap: "\u224D\u20D2",
        nVDash: "\u22AF",
        nVdash: "\u22AE",
        nvDash: "\u22AD",
        nvdash: "\u22AC",
        nvge: "\u2265\u20D2",
        nvgt: ">\u20D2",
        nvHarr: "\u2904",
        nvinfin: "\u29DE",
        nvlArr: "\u2902",
        nvle: "\u2264\u20D2",
        nvlt: "<\u20D2",
        nvltrie: "\u22B4\u20D2",
        nvrArr: "\u2903",
        nvrtrie: "\u22B5\u20D2",
        nvsim: "\u223C\u20D2",
        nwarhk: "\u2923",
        nwArr: "\u21D6",
        nwarr: "\u2196",
        nwarrow: "\u2196",
        nwnear: "\u2927",
        Oacute: "\xD3",
        oacute: "\xF3",
        oast: "\u229B",
        ocir: "\u229A",
        Ocirc: "\xD4",
        ocirc: "\xF4",
        Ocy: "\u041E",
        ocy: "\u043E",
        odash: "\u229D",
        Odblac: "\u0150",
        odblac: "\u0151",
        odiv: "\u2A38",
        odot: "\u2299",
        odsold: "\u29BC",
        OElig: "\u0152",
        oelig: "\u0153",
        ofcir: "\u29BF",
        Ofr: "\u{1D512}",
        ofr: "\u{1D52C}",
        ogon: "\u02DB",
        Ograve: "\xD2",
        ograve: "\xF2",
        ogt: "\u29C1",
        ohbar: "\u29B5",
        ohm: "\u03A9",
        oint: "\u222E",
        olarr: "\u21BA",
        olcir: "\u29BE",
        olcross: "\u29BB",
        oline: "\u203E",
        olt: "\u29C0",
        Omacr: "\u014C",
        omacr: "\u014D",
        Omega: "\u03A9",
        omega: "\u03C9",
        Omicron: "\u039F",
        omicron: "\u03BF",
        omid: "\u29B6",
        ominus: "\u2296",
        Oopf: "\u{1D546}",
        oopf: "\u{1D560}",
        opar: "\u29B7",
        OpenCurlyDoubleQuote: "\u201C",
        OpenCurlyQuote: "\u2018",
        operp: "\u29B9",
        oplus: "\u2295",
        Or: "\u2A54",
        or: "\u2228",
        orarr: "\u21BB",
        ord: "\u2A5D",
        order: "\u2134",
        orderof: "\u2134",
        ordf: "\xAA",
        ordm: "\xBA",
        origof: "\u22B6",
        oror: "\u2A56",
        orslope: "\u2A57",
        orv: "\u2A5B",
        oS: "\u24C8",
        Oscr: "\u{1D4AA}",
        oscr: "\u2134",
        Oslash: "\xD8",
        oslash: "\xF8",
        osol: "\u2298",
        Otilde: "\xD5",
        otilde: "\xF5",
        Otimes: "\u2A37",
        otimes: "\u2297",
        otimesas: "\u2A36",
        Ouml: "\xD6",
        ouml: "\xF6",
        ovbar: "\u233D",
        OverBar: "\u203E",
        OverBrace: "\u23DE",
        OverBracket: "\u23B4",
        OverParenthesis: "\u23DC",
        par: "\u2225",
        para: "\xB6",
        parallel: "\u2225",
        parsim: "\u2AF3",
        parsl: "\u2AFD",
        part: "\u2202",
        PartialD: "\u2202",
        Pcy: "\u041F",
        pcy: "\u043F",
        percnt: "%",
        period: ".",
        permil: "\u2030",
        perp: "\u22A5",
        pertenk: "\u2031",
        Pfr: "\u{1D513}",
        pfr: "\u{1D52D}",
        Phi: "\u03A6",
        phi: "\u03C6",
        phiv: "\u03D5",
        phmmat: "\u2133",
        phone: "\u260E",
        Pi: "\u03A0",
        pi: "\u03C0",
        pitchfork: "\u22D4",
        piv: "\u03D6",
        planck: "\u210F",
        planckh: "\u210E",
        plankv: "\u210F",
        plus: "+",
        plusacir: "\u2A23",
        plusb: "\u229E",
        pluscir: "\u2A22",
        plusdo: "\u2214",
        plusdu: "\u2A25",
        pluse: "\u2A72",
        PlusMinus: "\xB1",
        plusmn: "\xB1",
        plussim: "\u2A26",
        plustwo: "\u2A27",
        pm: "\xB1",
        Poincareplane: "\u210C",
        pointint: "\u2A15",
        Popf: "\u2119",
        popf: "\u{1D561}",
        pound: "\xA3",
        Pr: "\u2ABB",
        pr: "\u227A",
        prap: "\u2AB7",
        prcue: "\u227C",
        prE: "\u2AB3",
        pre: "\u2AAF",
        prec: "\u227A",
        precapprox: "\u2AB7",
        preccurlyeq: "\u227C",
        Precedes: "\u227A",
        PrecedesEqual: "\u2AAF",
        PrecedesSlantEqual: "\u227C",
        PrecedesTilde: "\u227E",
        preceq: "\u2AAF",
        precnapprox: "\u2AB9",
        precneqq: "\u2AB5",
        precnsim: "\u22E8",
        precsim: "\u227E",
        Prime: "\u2033",
        prime: "\u2032",
        primes: "\u2119",
        prnap: "\u2AB9",
        prnE: "\u2AB5",
        prnsim: "\u22E8",
        prod: "\u220F",
        Product: "\u220F",
        profalar: "\u232E",
        profline: "\u2312",
        profsurf: "\u2313",
        prop: "\u221D",
        Proportion: "\u2237",
        Proportional: "\u221D",
        propto: "\u221D",
        prsim: "\u227E",
        prurel: "\u22B0",
        Pscr: "\u{1D4AB}",
        pscr: "\u{1D4C5}",
        Psi: "\u03A8",
        psi: "\u03C8",
        puncsp: "\u2008",
        Qfr: "\u{1D514}",
        qfr: "\u{1D52E}",
        qint: "\u2A0C",
        Qopf: "\u211A",
        qopf: "\u{1D562}",
        qprime: "\u2057",
        Qscr: "\u{1D4AC}",
        qscr: "\u{1D4C6}",
        quaternions: "\u210D",
        quatint: "\u2A16",
        quest: "?",
        questeq: "\u225F",
        QUOT: '"',
        quot: '"',
        rAarr: "\u21DB",
        race: "\u223D\u0331",
        Racute: "\u0154",
        racute: "\u0155",
        radic: "\u221A",
        raemptyv: "\u29B3",
        Rang: "\u27EB",
        rang: "\u27E9",
        rangd: "\u2992",
        range: "\u29A5",
        rangle: "\u27E9",
        raquo: "\xBB",
        Rarr: "\u21A0",
        rArr: "\u21D2",
        rarr: "\u2192",
        rarrap: "\u2975",
        rarrb: "\u21E5",
        rarrbfs: "\u2920",
        rarrc: "\u2933",
        rarrfs: "\u291E",
        rarrhk: "\u21AA",
        rarrlp: "\u21AC",
        rarrpl: "\u2945",
        rarrsim: "\u2974",
        Rarrtl: "\u2916",
        rarrtl: "\u21A3",
        rarrw: "\u219D",
        rAtail: "\u291C",
        ratail: "\u291A",
        ratio: "\u2236",
        rationals: "\u211A",
        RBarr: "\u2910",
        rBarr: "\u290F",
        rbarr: "\u290D",
        rbbrk: "\u2773",
        rbrace: "}",
        rbrack: "]",
        rbrke: "\u298C",
        rbrksld: "\u298E",
        rbrkslu: "\u2990",
        Rcaron: "\u0158",
        rcaron: "\u0159",
        Rcedil: "\u0156",
        rcedil: "\u0157",
        rceil: "\u2309",
        rcub: "}",
        Rcy: "\u0420",
        rcy: "\u0440",
        rdca: "\u2937",
        rdldhar: "\u2969",
        rdquo: "\u201D",
        rdquor: "\u201D",
        rdsh: "\u21B3",
        Re: "\u211C",
        real: "\u211C",
        realine: "\u211B",
        realpart: "\u211C",
        reals: "\u211D",
        rect: "\u25AD",
        REG: "\xAE",
        reg: "\xAE",
        ReverseElement: "\u220B",
        ReverseEquilibrium: "\u21CB",
        ReverseUpEquilibrium: "\u296F",
        rfisht: "\u297D",
        rfloor: "\u230B",
        Rfr: "\u211C",
        rfr: "\u{1D52F}",
        rHar: "\u2964",
        rhard: "\u21C1",
        rharu: "\u21C0",
        rharul: "\u296C",
        Rho: "\u03A1",
        rho: "\u03C1",
        rhov: "\u03F1",
        RightAngleBracket: "\u27E9",
        RightArrow: "\u2192",
        Rightarrow: "\u21D2",
        rightarrow: "\u2192",
        RightArrowBar: "\u21E5",
        RightArrowLeftArrow: "\u21C4",
        rightarrowtail: "\u21A3",
        RightCeiling: "\u2309",
        RightDoubleBracket: "\u27E7",
        RightDownTeeVector: "\u295D",
        RightDownVector: "\u21C2",
        RightDownVectorBar: "\u2955",
        RightFloor: "\u230B",
        rightharpoondown: "\u21C1",
        rightharpoonup: "\u21C0",
        rightleftarrows: "\u21C4",
        rightleftharpoons: "\u21CC",
        rightrightarrows: "\u21C9",
        rightsquigarrow: "\u219D",
        RightTee: "\u22A2",
        RightTeeArrow: "\u21A6",
        RightTeeVector: "\u295B",
        rightthreetimes: "\u22CC",
        RightTriangle: "\u22B3",
        RightTriangleBar: "\u29D0",
        RightTriangleEqual: "\u22B5",
        RightUpDownVector: "\u294F",
        RightUpTeeVector: "\u295C",
        RightUpVector: "\u21BE",
        RightUpVectorBar: "\u2954",
        RightVector: "\u21C0",
        RightVectorBar: "\u2953",
        ring: "\u02DA",
        risingdotseq: "\u2253",
        rlarr: "\u21C4",
        rlhar: "\u21CC",
        rlm: "\u200F",
        rmoust: "\u23B1",
        rmoustache: "\u23B1",
        rnmid: "\u2AEE",
        roang: "\u27ED",
        roarr: "\u21FE",
        robrk: "\u27E7",
        ropar: "\u2986",
        Ropf: "\u211D",
        ropf: "\u{1D563}",
        roplus: "\u2A2E",
        rotimes: "\u2A35",
        RoundImplies: "\u2970",
        rpar: ")",
        rpargt: "\u2994",
        rppolint: "\u2A12",
        rrarr: "\u21C9",
        Rrightarrow: "\u21DB",
        rsaquo: "\u203A",
        Rscr: "\u211B",
        rscr: "\u{1D4C7}",
        Rsh: "\u21B1",
        rsh: "\u21B1",
        rsqb: "]",
        rsquo: "\u2019",
        rsquor: "\u2019",
        rthree: "\u22CC",
        rtimes: "\u22CA",
        rtri: "\u25B9",
        rtrie: "\u22B5",
        rtrif: "\u25B8",
        rtriltri: "\u29CE",
        RuleDelayed: "\u29F4",
        ruluhar: "\u2968",
        rx: "\u211E",
        Sacute: "\u015A",
        sacute: "\u015B",
        sbquo: "\u201A",
        Sc: "\u2ABC",
        sc: "\u227B",
        scap: "\u2AB8",
        Scaron: "\u0160",
        scaron: "\u0161",
        sccue: "\u227D",
        scE: "\u2AB4",
        sce: "\u2AB0",
        Scedil: "\u015E",
        scedil: "\u015F",
        Scirc: "\u015C",
        scirc: "\u015D",
        scnap: "\u2ABA",
        scnE: "\u2AB6",
        scnsim: "\u22E9",
        scpolint: "\u2A13",
        scsim: "\u227F",
        Scy: "\u0421",
        scy: "\u0441",
        sdot: "\u22C5",
        sdotb: "\u22A1",
        sdote: "\u2A66",
        searhk: "\u2925",
        seArr: "\u21D8",
        searr: "\u2198",
        searrow: "\u2198",
        sect: "\xA7",
        semi: ";",
        seswar: "\u2929",
        setminus: "\u2216",
        setmn: "\u2216",
        sext: "\u2736",
        Sfr: "\u{1D516}",
        sfr: "\u{1D530}",
        sfrown: "\u2322",
        sharp: "\u266F",
        SHCHcy: "\u0429",
        shchcy: "\u0449",
        SHcy: "\u0428",
        shcy: "\u0448",
        ShortDownArrow: "\u2193",
        ShortLeftArrow: "\u2190",
        shortmid: "\u2223",
        shortparallel: "\u2225",
        ShortRightArrow: "\u2192",
        ShortUpArrow: "\u2191",
        shy: "\xAD",
        Sigma: "\u03A3",
        sigma: "\u03C3",
        sigmaf: "\u03C2",
        sigmav: "\u03C2",
        sim: "\u223C",
        simdot: "\u2A6A",
        sime: "\u2243",
        simeq: "\u2243",
        simg: "\u2A9E",
        simgE: "\u2AA0",
        siml: "\u2A9D",
        simlE: "\u2A9F",
        simne: "\u2246",
        simplus: "\u2A24",
        simrarr: "\u2972",
        slarr: "\u2190",
        SmallCircle: "\u2218",
        smallsetminus: "\u2216",
        smashp: "\u2A33",
        smeparsl: "\u29E4",
        smid: "\u2223",
        smile: "\u2323",
        smt: "\u2AAA",
        smte: "\u2AAC",
        smtes: "\u2AAC\uFE00",
        SOFTcy: "\u042C",
        softcy: "\u044C",
        sol: "/",
        solb: "\u29C4",
        solbar: "\u233F",
        Sopf: "\u{1D54A}",
        sopf: "\u{1D564}",
        spades: "\u2660",
        spadesuit: "\u2660",
        spar: "\u2225",
        sqcap: "\u2293",
        sqcaps: "\u2293\uFE00",
        sqcup: "\u2294",
        sqcups: "\u2294\uFE00",
        Sqrt: "\u221A",
        sqsub: "\u228F",
        sqsube: "\u2291",
        sqsubset: "\u228F",
        sqsubseteq: "\u2291",
        sqsup: "\u2290",
        sqsupe: "\u2292",
        sqsupset: "\u2290",
        sqsupseteq: "\u2292",
        squ: "\u25A1",
        Square: "\u25A1",
        square: "\u25A1",
        SquareIntersection: "\u2293",
        SquareSubset: "\u228F",
        SquareSubsetEqual: "\u2291",
        SquareSuperset: "\u2290",
        SquareSupersetEqual: "\u2292",
        SquareUnion: "\u2294",
        squarf: "\u25AA",
        squf: "\u25AA",
        srarr: "\u2192",
        Sscr: "\u{1D4AE}",
        sscr: "\u{1D4C8}",
        ssetmn: "\u2216",
        ssmile: "\u2323",
        sstarf: "\u22C6",
        Star: "\u22C6",
        star: "\u2606",
        starf: "\u2605",
        straightepsilon: "\u03F5",
        straightphi: "\u03D5",
        strns: "\xAF",
        Sub: "\u22D0",
        sub: "\u2282",
        subdot: "\u2ABD",
        subE: "\u2AC5",
        sube: "\u2286",
        subedot: "\u2AC3",
        submult: "\u2AC1",
        subnE: "\u2ACB",
        subne: "\u228A",
        subplus: "\u2ABF",
        subrarr: "\u2979",
        Subset: "\u22D0",
        subset: "\u2282",
        subseteq: "\u2286",
        subseteqq: "\u2AC5",
        SubsetEqual: "\u2286",
        subsetneq: "\u228A",
        subsetneqq: "\u2ACB",
        subsim: "\u2AC7",
        subsub: "\u2AD5",
        subsup: "\u2AD3",
        succ: "\u227B",
        succapprox: "\u2AB8",
        succcurlyeq: "\u227D",
        Succeeds: "\u227B",
        SucceedsEqual: "\u2AB0",
        SucceedsSlantEqual: "\u227D",
        SucceedsTilde: "\u227F",
        succeq: "\u2AB0",
        succnapprox: "\u2ABA",
        succneqq: "\u2AB6",
        succnsim: "\u22E9",
        succsim: "\u227F",
        SuchThat: "\u220B",
        Sum: "\u2211",
        sum: "\u2211",
        sung: "\u266A",
        Sup: "\u22D1",
        sup: "\u2283",
        sup1: "\xB9",
        sup2: "\xB2",
        sup3: "\xB3",
        supdot: "\u2ABE",
        supdsub: "\u2AD8",
        supE: "\u2AC6",
        supe: "\u2287",
        supedot: "\u2AC4",
        Superset: "\u2283",
        SupersetEqual: "\u2287",
        suphsol: "\u27C9",
        suphsub: "\u2AD7",
        suplarr: "\u297B",
        supmult: "\u2AC2",
        supnE: "\u2ACC",
        supne: "\u228B",
        supplus: "\u2AC0",
        Supset: "\u22D1",
        supset: "\u2283",
        supseteq: "\u2287",
        supseteqq: "\u2AC6",
        supsetneq: "\u228B",
        supsetneqq: "\u2ACC",
        supsim: "\u2AC8",
        supsub: "\u2AD4",
        supsup: "\u2AD6",
        swarhk: "\u2926",
        swArr: "\u21D9",
        swarr: "\u2199",
        swarrow: "\u2199",
        swnwar: "\u292A",
        szlig: "\xDF",
        Tab: "	",
        target: "\u2316",
        Tau: "\u03A4",
        tau: "\u03C4",
        tbrk: "\u23B4",
        Tcaron: "\u0164",
        tcaron: "\u0165",
        Tcedil: "\u0162",
        tcedil: "\u0163",
        Tcy: "\u0422",
        tcy: "\u0442",
        tdot: "\u20DB",
        telrec: "\u2315",
        Tfr: "\u{1D517}",
        tfr: "\u{1D531}",
        there4: "\u2234",
        Therefore: "\u2234",
        therefore: "\u2234",
        Theta: "\u0398",
        theta: "\u03B8",
        thetasym: "\u03D1",
        thetav: "\u03D1",
        thickapprox: "\u2248",
        thicksim: "\u223C",
        ThickSpace: "\u205F\u200A",
        thinsp: "\u2009",
        ThinSpace: "\u2009",
        thkap: "\u2248",
        thksim: "\u223C",
        THORN: "\xDE",
        thorn: "\xFE",
        Tilde: "\u223C",
        tilde: "\u02DC",
        TildeEqual: "\u2243",
        TildeFullEqual: "\u2245",
        TildeTilde: "\u2248",
        times: "\xD7",
        timesb: "\u22A0",
        timesbar: "\u2A31",
        timesd: "\u2A30",
        tint: "\u222D",
        toea: "\u2928",
        top: "\u22A4",
        topbot: "\u2336",
        topcir: "\u2AF1",
        Topf: "\u{1D54B}",
        topf: "\u{1D565}",
        topfork: "\u2ADA",
        tosa: "\u2929",
        tprime: "\u2034",
        TRADE: "\u2122",
        trade: "\u2122",
        triangle: "\u25B5",
        triangledown: "\u25BF",
        triangleleft: "\u25C3",
        trianglelefteq: "\u22B4",
        triangleq: "\u225C",
        triangleright: "\u25B9",
        trianglerighteq: "\u22B5",
        tridot: "\u25EC",
        trie: "\u225C",
        triminus: "\u2A3A",
        TripleDot: "\u20DB",
        triplus: "\u2A39",
        trisb: "\u29CD",
        tritime: "\u2A3B",
        trpezium: "\u23E2",
        Tscr: "\u{1D4AF}",
        tscr: "\u{1D4C9}",
        TScy: "\u0426",
        tscy: "\u0446",
        TSHcy: "\u040B",
        tshcy: "\u045B",
        Tstrok: "\u0166",
        tstrok: "\u0167",
        twixt: "\u226C",
        twoheadleftarrow: "\u219E",
        twoheadrightarrow: "\u21A0",
        Uacute: "\xDA",
        uacute: "\xFA",
        Uarr: "\u219F",
        uArr: "\u21D1",
        uarr: "\u2191",
        Uarrocir: "\u2949",
        Ubrcy: "\u040E",
        ubrcy: "\u045E",
        Ubreve: "\u016C",
        ubreve: "\u016D",
        Ucirc: "\xDB",
        ucirc: "\xFB",
        Ucy: "\u0423",
        ucy: "\u0443",
        udarr: "\u21C5",
        Udblac: "\u0170",
        udblac: "\u0171",
        udhar: "\u296E",
        ufisht: "\u297E",
        Ufr: "\u{1D518}",
        ufr: "\u{1D532}",
        Ugrave: "\xD9",
        ugrave: "\xF9",
        uHar: "\u2963",
        uharl: "\u21BF",
        uharr: "\u21BE",
        uhblk: "\u2580",
        ulcorn: "\u231C",
        ulcorner: "\u231C",
        ulcrop: "\u230F",
        ultri: "\u25F8",
        Umacr: "\u016A",
        umacr: "\u016B",
        uml: "\xA8",
        UnderBar: "_",
        UnderBrace: "\u23DF",
        UnderBracket: "\u23B5",
        UnderParenthesis: "\u23DD",
        Union: "\u22C3",
        UnionPlus: "\u228E",
        Uogon: "\u0172",
        uogon: "\u0173",
        Uopf: "\u{1D54C}",
        uopf: "\u{1D566}",
        UpArrow: "\u2191",
        Uparrow: "\u21D1",
        uparrow: "\u2191",
        UpArrowBar: "\u2912",
        UpArrowDownArrow: "\u21C5",
        UpDownArrow: "\u2195",
        Updownarrow: "\u21D5",
        updownarrow: "\u2195",
        UpEquilibrium: "\u296E",
        upharpoonleft: "\u21BF",
        upharpoonright: "\u21BE",
        uplus: "\u228E",
        UpperLeftArrow: "\u2196",
        UpperRightArrow: "\u2197",
        Upsi: "\u03D2",
        upsi: "\u03C5",
        upsih: "\u03D2",
        Upsilon: "\u03A5",
        upsilon: "\u03C5",
        UpTee: "\u22A5",
        UpTeeArrow: "\u21A5",
        upuparrows: "\u21C8",
        urcorn: "\u231D",
        urcorner: "\u231D",
        urcrop: "\u230E",
        Uring: "\u016E",
        uring: "\u016F",
        urtri: "\u25F9",
        Uscr: "\u{1D4B0}",
        uscr: "\u{1D4CA}",
        utdot: "\u22F0",
        Utilde: "\u0168",
        utilde: "\u0169",
        utri: "\u25B5",
        utrif: "\u25B4",
        uuarr: "\u21C8",
        Uuml: "\xDC",
        uuml: "\xFC",
        uwangle: "\u29A7",
        vangrt: "\u299C",
        varepsilon: "\u03F5",
        varkappa: "\u03F0",
        varnothing: "\u2205",
        varphi: "\u03D5",
        varpi: "\u03D6",
        varpropto: "\u221D",
        vArr: "\u21D5",
        varr: "\u2195",
        varrho: "\u03F1",
        varsigma: "\u03C2",
        varsubsetneq: "\u228A\uFE00",
        varsubsetneqq: "\u2ACB\uFE00",
        varsupsetneq: "\u228B\uFE00",
        varsupsetneqq: "\u2ACC\uFE00",
        vartheta: "\u03D1",
        vartriangleleft: "\u22B2",
        vartriangleright: "\u22B3",
        Vbar: "\u2AEB",
        vBar: "\u2AE8",
        vBarv: "\u2AE9",
        Vcy: "\u0412",
        vcy: "\u0432",
        VDash: "\u22AB",
        Vdash: "\u22A9",
        vDash: "\u22A8",
        vdash: "\u22A2",
        Vdashl: "\u2AE6",
        Vee: "\u22C1",
        vee: "\u2228",
        veebar: "\u22BB",
        veeeq: "\u225A",
        vellip: "\u22EE",
        Verbar: "\u2016",
        verbar: "|",
        Vert: "\u2016",
        vert: "|",
        VerticalBar: "\u2223",
        VerticalLine: "|",
        VerticalSeparator: "\u2758",
        VerticalTilde: "\u2240",
        VeryThinSpace: "\u200A",
        Vfr: "\u{1D519}",
        vfr: "\u{1D533}",
        vltri: "\u22B2",
        vnsub: "\u2282\u20D2",
        vnsup: "\u2283\u20D2",
        Vopf: "\u{1D54D}",
        vopf: "\u{1D567}",
        vprop: "\u221D",
        vrtri: "\u22B3",
        Vscr: "\u{1D4B1}",
        vscr: "\u{1D4CB}",
        vsubnE: "\u2ACB\uFE00",
        vsubne: "\u228A\uFE00",
        vsupnE: "\u2ACC\uFE00",
        vsupne: "\u228B\uFE00",
        Vvdash: "\u22AA",
        vzigzag: "\u299A",
        Wcirc: "\u0174",
        wcirc: "\u0175",
        wedbar: "\u2A5F",
        Wedge: "\u22C0",
        wedge: "\u2227",
        wedgeq: "\u2259",
        weierp: "\u2118",
        Wfr: "\u{1D51A}",
        wfr: "\u{1D534}",
        Wopf: "\u{1D54E}",
        wopf: "\u{1D568}",
        wp: "\u2118",
        wr: "\u2240",
        wreath: "\u2240",
        Wscr: "\u{1D4B2}",
        wscr: "\u{1D4CC}",
        xcap: "\u22C2",
        xcirc: "\u25EF",
        xcup: "\u22C3",
        xdtri: "\u25BD",
        Xfr: "\u{1D51B}",
        xfr: "\u{1D535}",
        xhArr: "\u27FA",
        xharr: "\u27F7",
        Xi: "\u039E",
        xi: "\u03BE",
        xlArr: "\u27F8",
        xlarr: "\u27F5",
        xmap: "\u27FC",
        xnis: "\u22FB",
        xodot: "\u2A00",
        Xopf: "\u{1D54F}",
        xopf: "\u{1D569}",
        xoplus: "\u2A01",
        xotime: "\u2A02",
        xrArr: "\u27F9",
        xrarr: "\u27F6",
        Xscr: "\u{1D4B3}",
        xscr: "\u{1D4CD}",
        xsqcup: "\u2A06",
        xuplus: "\u2A04",
        xutri: "\u25B3",
        xvee: "\u22C1",
        xwedge: "\u22C0",
        Yacute: "\xDD",
        yacute: "\xFD",
        YAcy: "\u042F",
        yacy: "\u044F",
        Ycirc: "\u0176",
        ycirc: "\u0177",
        Ycy: "\u042B",
        ycy: "\u044B",
        yen: "\xA5",
        Yfr: "\u{1D51C}",
        yfr: "\u{1D536}",
        YIcy: "\u0407",
        yicy: "\u0457",
        Yopf: "\u{1D550}",
        yopf: "\u{1D56A}",
        Yscr: "\u{1D4B4}",
        yscr: "\u{1D4CE}",
        YUcy: "\u042E",
        yucy: "\u044E",
        Yuml: "\u0178",
        yuml: "\xFF",
        Zacute: "\u0179",
        zacute: "\u017A",
        Zcaron: "\u017D",
        zcaron: "\u017E",
        Zcy: "\u0417",
        zcy: "\u0437",
        Zdot: "\u017B",
        zdot: "\u017C",
        zeetrf: "\u2128",
        ZeroWidthSpace: "\u200B",
        Zeta: "\u0396",
        zeta: "\u03B6",
        Zfr: "\u2128",
        zfr: "\u{1D537}",
        ZHcy: "\u0416",
        zhcy: "\u0436",
        zigrarr: "\u21DD",
        Zopf: "\u2124",
        zopf: "\u{1D56B}",
        Zscr: "\u{1D4B5}",
        zscr: "\u{1D4CF}",
        zwj: "\u200D",
        zwnj: "\u200C"
      });
      exports2.entityMap = exports2.HTML_ENTITIES;
    }
  });

  // node_modules/@xmldom/xmldom/lib/sax.js
  var require_sax = __commonJS({
    "node_modules/@xmldom/xmldom/lib/sax.js"(exports2) {
      "use strict";
      var conventions = require_conventions();
      var g = require_grammar();
      var errors = require_errors2();
      var isHTMLEscapableRawTextElement = conventions.isHTMLEscapableRawTextElement;
      var isHTMLMimeType = conventions.isHTMLMimeType;
      var isHTMLRawTextElement = conventions.isHTMLRawTextElement;
      var hasOwn = conventions.hasOwn;
      var NAMESPACE = conventions.NAMESPACE;
      var ParseError = errors.ParseError;
      var DOMException = errors.DOMException;
      var S_TAG = 0;
      var S_ATTR = 1;
      var S_ATTR_SPACE = 2;
      var S_EQ = 3;
      var S_ATTR_NOQUOT_VALUE = 4;
      var S_ATTR_END = 5;
      var S_TAG_SPACE = 6;
      var S_TAG_CLOSE = 7;
      function XMLReader() {
      }
      XMLReader.prototype = {
        parse: function(source, defaultNSMap, entityMap) {
          var domBuilder = this.domBuilder;
          domBuilder.startDocument();
          _copy(defaultNSMap, defaultNSMap = /* @__PURE__ */ Object.create(null));
          parse(source, defaultNSMap, entityMap, domBuilder, this.errorHandler);
          domBuilder.endDocument();
        }
      };
      var ENTITY_REG = /&#?\w+;?/g;
      function parse(source, defaultNSMapCopy, entityMap, domBuilder, errorHandler) {
        var isHTML = isHTMLMimeType(domBuilder.mimeType);
        if (source.indexOf(g.UNICODE_REPLACEMENT_CHARACTER) >= 0) {
          errorHandler.warning("Unicode replacement character detected, source encoding issues?");
        }
        function fixedFromCharCode(code) {
          if (code > 65535) {
            code -= 65536;
            var surrogate1 = 55296 + (code >> 10), surrogate2 = 56320 + (code & 1023);
            return String.fromCharCode(surrogate1, surrogate2);
          } else {
            return String.fromCharCode(code);
          }
        }
        function entityReplacer(a2) {
          var complete = a2[a2.length - 1] === ";" ? a2 : a2 + ";";
          if (!isHTML && complete !== a2) {
            errorHandler.error("EntityRef: expecting ;");
            return a2;
          }
          var match = g.Reference.exec(complete);
          if (!match || match[0].length !== complete.length) {
            errorHandler.error("entity not matching Reference production: " + a2);
            return a2;
          }
          var k = complete.slice(1, -1);
          if (hasOwn(entityMap, k)) {
            return entityMap[k];
          } else if (k.charAt(0) === "#") {
            return fixedFromCharCode(parseInt(k.substring(1).replace("x", "0x")));
          } else {
            errorHandler.error("entity not found:" + a2);
            return a2;
          }
        }
        function appendText(end2) {
          if (end2 > start) {
            var xt = source.substring(start, end2).replace(ENTITY_REG, entityReplacer);
            locator && position(start);
            domBuilder.characters(xt, 0, end2 - start);
            start = end2;
          }
        }
        var lineStart = 0;
        var lineEnd = 0;
        var linePattern = /\r\n?|\n|$/g;
        var locator = domBuilder.locator;
        function position(p, m) {
          while (p >= lineEnd && (m = linePattern.exec(source))) {
            lineStart = lineEnd;
            lineEnd = m.index + m[0].length;
            locator.lineNumber++;
          }
          locator.columnNumber = p - lineStart + 1;
        }
        var parseStack = [{ currentNSMap: defaultNSMapCopy }];
        var unclosedTags = [];
        var start = 0;
        while (true) {
          try {
            var tagStart = source.indexOf("<", start);
            if (tagStart < 0) {
              if (!isHTML && unclosedTags.length > 0) {
                return errorHandler.fatalError("unclosed xml tag(s): " + unclosedTags.join(", "));
              }
              if (!source.substring(start).match(/^\s*$/)) {
                var doc = domBuilder.doc;
                var text = doc.createTextNode(source.substring(start));
                if (doc.documentElement) {
                  return errorHandler.error("Extra content at the end of the document");
                }
                doc.appendChild(text);
                domBuilder.currentElement = text;
              }
              return;
            }
            if (tagStart > start) {
              var fromSource = source.substring(start, tagStart);
              if (!isHTML && unclosedTags.length === 0) {
                fromSource = fromSource.replace(new RegExp(g.S_OPT.source, "g"), "");
                fromSource && errorHandler.error("Unexpected content outside root element: '" + fromSource + "'");
              }
              appendText(tagStart);
            }
            switch (source.charAt(tagStart + 1)) {
              case "/":
                var end = source.indexOf(">", tagStart + 2);
                var tagNameRaw = source.substring(tagStart + 2, end > 0 ? end : void 0);
                if (!tagNameRaw) {
                  return errorHandler.fatalError("end tag name missing");
                }
                var tagNameMatch = end > 0 && g.reg("^", g.QName_group, g.S_OPT, "$").exec(tagNameRaw);
                if (!tagNameMatch) {
                  return errorHandler.fatalError('end tag name contains invalid characters: "' + tagNameRaw + '"');
                }
                if (!domBuilder.currentElement && !domBuilder.doc.documentElement) {
                  return;
                }
                var currentTagName = unclosedTags[unclosedTags.length - 1] || domBuilder.currentElement.tagName || domBuilder.doc.documentElement.tagName || "";
                if (currentTagName !== tagNameMatch[1]) {
                  var tagNameLower = tagNameMatch[1].toLowerCase();
                  if (!isHTML || currentTagName.toLowerCase() !== tagNameLower) {
                    return errorHandler.fatalError('Opening and ending tag mismatch: "' + currentTagName + '" != "' + tagNameRaw + '"');
                  }
                }
                var config = parseStack.pop();
                unclosedTags.pop();
                var localNSMap = config.localNSMap;
                domBuilder.endElement(config.uri, config.localName, currentTagName);
                if (localNSMap) {
                  for (var prefix in localNSMap) {
                    if (hasOwn(localNSMap, prefix)) {
                      domBuilder.endPrefixMapping(prefix);
                    }
                  }
                }
                end++;
                break;
              // end element
              case "?":
                locator && position(tagStart);
                end = parseProcessingInstruction(source, tagStart, domBuilder, errorHandler);
                break;
              case "!":
                locator && position(tagStart);
                end = parseDoctypeCommentOrCData(source, tagStart, domBuilder, errorHandler, isHTML);
                break;
              default:
                locator && position(tagStart);
                var el = new ElementAttributes();
                var currentNSMap = parseStack[parseStack.length - 1].currentNSMap;
                var end = parseElementStartPart(source, tagStart, el, currentNSMap, entityReplacer, errorHandler, isHTML);
                var len = el.length;
                if (!el.closed) {
                  if (isHTML && conventions.isHTMLVoidElement(el.tagName)) {
                    el.closed = true;
                  } else {
                    unclosedTags.push(el.tagName);
                  }
                }
                if (locator && len) {
                  var locator2 = copyLocator(locator, {});
                  for (var i = 0; i < len; i++) {
                    var a = el[i];
                    position(a.offset);
                    a.locator = copyLocator(locator, {});
                  }
                  domBuilder.locator = locator2;
                  if (appendElement(el, domBuilder, currentNSMap)) {
                    parseStack.push(el);
                  }
                  domBuilder.locator = locator;
                } else {
                  if (appendElement(el, domBuilder, currentNSMap)) {
                    parseStack.push(el);
                  }
                }
                if (isHTML && !el.closed) {
                  end = parseHtmlSpecialContent(source, end, el.tagName, entityReplacer, domBuilder);
                } else {
                  end++;
                }
            }
          } catch (e) {
            if (e instanceof ParseError) {
              throw e;
            } else if (e instanceof DOMException) {
              throw new ParseError(e.name + ": " + e.message, domBuilder.locator, e);
            }
            errorHandler.error("element parse error: " + e);
            end = -1;
          }
          if (end > start) {
            start = end;
          } else {
            appendText(Math.max(tagStart, start) + 1);
          }
        }
      }
      function copyLocator(f, t) {
        t.lineNumber = f.lineNumber;
        t.columnNumber = f.columnNumber;
        return t;
      }
      function parseElementStartPart(source, start, el, currentNSMap, entityReplacer, errorHandler, isHTML) {
        function addAttribute(qname, value2, startIndex) {
          if (hasOwn(el.attributeNames, qname)) {
            return errorHandler.fatalError("Attribute " + qname + " redefined");
          }
          if (!isHTML && value2.indexOf("<") >= 0) {
            return errorHandler.fatalError("Unescaped '<' not allowed in attributes values");
          }
          el.addValue(
            qname,
            // @see https://www.w3.org/TR/xml/#AVNormalize
            // since the xmldom sax parser does not "interpret" DTD the following is not implemented:
            // - recursive replacement of (DTD) entity references
            // - trimming and collapsing multiple spaces into a single one for attributes that are not of type CDATA
            value2.replace(/[\t\n\r]/g, " ").replace(ENTITY_REG, entityReplacer),
            startIndex
          );
        }
        var attrName;
        var value;
        var p = ++start;
        var s = S_TAG;
        while (true) {
          var c = source.charAt(p);
          switch (c) {
            case "=":
              if (s === S_ATTR) {
                attrName = source.slice(start, p);
                s = S_EQ;
              } else if (s === S_ATTR_SPACE) {
                s = S_EQ;
              } else {
                throw new Error("attribute equal must after attrName");
              }
              break;
            case "'":
            case '"':
              if (s === S_EQ || s === S_ATTR) {
                if (s === S_ATTR) {
                  errorHandler.warning('attribute value must after "="');
                  attrName = source.slice(start, p);
                }
                start = p + 1;
                p = source.indexOf(c, start);
                if (p > 0) {
                  value = source.slice(start, p);
                  addAttribute(attrName, value, start - 1);
                  s = S_ATTR_END;
                } else {
                  throw new Error("attribute value no end '" + c + "' match");
                }
              } else if (s == S_ATTR_NOQUOT_VALUE) {
                value = source.slice(start, p);
                addAttribute(attrName, value, start);
                errorHandler.warning('attribute "' + attrName + '" missed start quot(' + c + ")!!");
                start = p + 1;
                s = S_ATTR_END;
              } else {
                throw new Error('attribute value must after "="');
              }
              break;
            case "/":
              switch (s) {
                case S_TAG:
                  el.setTagName(source.slice(start, p));
                case S_ATTR_END:
                case S_TAG_SPACE:
                case S_TAG_CLOSE:
                  s = S_TAG_CLOSE;
                  el.closed = true;
                case S_ATTR_NOQUOT_VALUE:
                case S_ATTR:
                  break;
                case S_ATTR_SPACE:
                  el.closed = true;
                  break;
                //case S_EQ:
                default:
                  throw new Error("attribute invalid close char('/')");
              }
              break;
            case "":
              errorHandler.error("unexpected end of input");
              if (s == S_TAG) {
                el.setTagName(source.slice(start, p));
              }
              return p;
            case ">":
              switch (s) {
                case S_TAG:
                  el.setTagName(source.slice(start, p));
                case S_ATTR_END:
                case S_TAG_SPACE:
                case S_TAG_CLOSE:
                  break;
                //normal
                case S_ATTR_NOQUOT_VALUE:
                //Compatible state
                case S_ATTR:
                  value = source.slice(start, p);
                  if (value.slice(-1) === "/") {
                    el.closed = true;
                    value = value.slice(0, -1);
                  }
                case S_ATTR_SPACE:
                  if (s === S_ATTR_SPACE) {
                    value = attrName;
                  }
                  if (s == S_ATTR_NOQUOT_VALUE) {
                    errorHandler.warning('attribute "' + value + '" missed quot(")!');
                    addAttribute(attrName, value, start);
                  } else {
                    if (!isHTML) {
                      errorHandler.warning('attribute "' + value + '" missed value!! "' + value + '" instead!!');
                    }
                    addAttribute(value, value, start);
                  }
                  break;
                case S_EQ:
                  if (!isHTML) {
                    return errorHandler.fatalError(`AttValue: ' or " expected`);
                  }
              }
              return p;
            /*xml space '\x20' | #x9 | #xD | #xA; */
            case "\x80":
              c = " ";
            default:
              if (c <= " ") {
                switch (s) {
                  case S_TAG:
                    el.setTagName(source.slice(start, p));
                    s = S_TAG_SPACE;
                    break;
                  case S_ATTR:
                    attrName = source.slice(start, p);
                    s = S_ATTR_SPACE;
                    break;
                  case S_ATTR_NOQUOT_VALUE:
                    var value = source.slice(start, p);
                    errorHandler.warning('attribute "' + value + '" missed quot(")!!');
                    addAttribute(attrName, value, start);
                  case S_ATTR_END:
                    s = S_TAG_SPACE;
                    break;
                }
              } else {
                switch (s) {
                  //case S_TAG:void();break;
                  //case S_ATTR:void();break;
                  //case S_ATTR_NOQUOT_VALUE:void();break;
                  case S_ATTR_SPACE:
                    if (!isHTML) {
                      errorHandler.warning('attribute "' + attrName + '" missed value!! "' + attrName + '" instead2!!');
                    }
                    addAttribute(attrName, attrName, start);
                    start = p;
                    s = S_ATTR;
                    break;
                  case S_ATTR_END:
                    errorHandler.warning('attribute space is required"' + attrName + '"!!');
                  case S_TAG_SPACE:
                    s = S_ATTR;
                    start = p;
                    break;
                  case S_EQ:
                    s = S_ATTR_NOQUOT_VALUE;
                    start = p;
                    break;
                  case S_TAG_CLOSE:
                    throw new Error("elements closed character '/' and '>' must be connected to");
                }
              }
          }
          p++;
        }
      }
      function appendElement(el, domBuilder, currentNSMap) {
        var tagName = el.tagName;
        var localNSMap = null;
        var i = el.length;
        while (i--) {
          var a = el[i];
          var qName = a.qName;
          var value = a.value;
          var nsp = qName.indexOf(":");
          if (nsp > 0) {
            var prefix = a.prefix = qName.slice(0, nsp);
            var localName = qName.slice(nsp + 1);
            var nsPrefix = prefix === "xmlns" && localName;
          } else {
            localName = qName;
            prefix = null;
            nsPrefix = qName === "xmlns" && "";
          }
          a.localName = localName;
          if (nsPrefix !== false) {
            if (localNSMap == null) {
              localNSMap = /* @__PURE__ */ Object.create(null);
              _copy(currentNSMap, currentNSMap = /* @__PURE__ */ Object.create(null));
            }
            currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
            a.uri = NAMESPACE.XMLNS;
            domBuilder.startPrefixMapping(nsPrefix, value);
          }
        }
        var i = el.length;
        while (i--) {
          a = el[i];
          if (a.prefix) {
            if (a.prefix === "xml") {
              a.uri = NAMESPACE.XML;
            }
            if (a.prefix !== "xmlns") {
              a.uri = currentNSMap[a.prefix];
            }
          }
        }
        var nsp = tagName.indexOf(":");
        if (nsp > 0) {
          prefix = el.prefix = tagName.slice(0, nsp);
          localName = el.localName = tagName.slice(nsp + 1);
        } else {
          prefix = null;
          localName = el.localName = tagName;
        }
        var ns = el.uri = currentNSMap[prefix || ""];
        domBuilder.startElement(ns, localName, tagName, el);
        if (el.closed) {
          domBuilder.endElement(ns, localName, tagName);
          if (localNSMap) {
            for (prefix in localNSMap) {
              if (hasOwn(localNSMap, prefix)) {
                domBuilder.endPrefixMapping(prefix);
              }
            }
          }
        } else {
          el.currentNSMap = currentNSMap;
          el.localNSMap = localNSMap;
          return true;
        }
      }
      function parseHtmlSpecialContent(source, elStartEnd, tagName, entityReplacer, domBuilder) {
        var isEscapableRaw = isHTMLEscapableRawTextElement(tagName);
        if (isEscapableRaw || isHTMLRawTextElement(tagName)) {
          var elEndStart = source.indexOf("</" + tagName + ">", elStartEnd);
          var text = source.substring(elStartEnd + 1, elEndStart);
          if (isEscapableRaw) {
            text = text.replace(ENTITY_REG, entityReplacer);
          }
          domBuilder.characters(text, 0, text.length);
          return elEndStart;
        }
        return elStartEnd + 1;
      }
      function _copy(source, target) {
        for (var n in source) {
          if (hasOwn(source, n)) {
            target[n] = source[n];
          }
        }
      }
      function parseUtils(source, start) {
        var index = start;
        function char(n) {
          n = n || 0;
          return source.charAt(index + n);
        }
        function skip(n) {
          n = n || 1;
          index += n;
        }
        function skipBlanks() {
          var blanks = 0;
          while (index < source.length) {
            var c = char();
            if (c !== " " && c !== "\n" && c !== "	" && c !== "\r") {
              return blanks;
            }
            blanks++;
            skip();
          }
          return -1;
        }
        function substringFromIndex() {
          return source.substring(index);
        }
        function substringStartsWith(text) {
          return source.substring(index, index + text.length) === text;
        }
        function substringStartsWithCaseInsensitive(text) {
          return source.substring(index, index + text.length).toUpperCase() === text.toUpperCase();
        }
        function getMatch(args) {
          var expr = g.reg("^", args);
          var match = expr.exec(substringFromIndex());
          if (match) {
            skip(match[0].length);
            return match[0];
          }
          return null;
        }
        return {
          char,
          getIndex: function() {
            return index;
          },
          getMatch,
          getSource: function() {
            return source;
          },
          skip,
          skipBlanks,
          substringFromIndex,
          substringStartsWith,
          substringStartsWithCaseInsensitive
        };
      }
      function parseDoctypeInternalSubset(p, errorHandler) {
        function parsePI(p2, errorHandler2) {
          var match = g.PI.exec(p2.substringFromIndex());
          if (!match) {
            return errorHandler2.fatalError("processing instruction is not well-formed at position " + p2.getIndex());
          }
          if (match[1].toLowerCase() === "xml") {
            return errorHandler2.fatalError(
              "xml declaration is only allowed at the start of the document, but found at position " + p2.getIndex()
            );
          }
          p2.skip(match[0].length);
          return match[0];
        }
        var source = p.getSource();
        if (p.char() === "[") {
          p.skip(1);
          var intSubsetStart = p.getIndex();
          while (p.getIndex() < source.length) {
            p.skipBlanks();
            if (p.char() === "]") {
              var internalSubset = source.substring(intSubsetStart, p.getIndex());
              p.skip(1);
              return internalSubset;
            }
            var current = null;
            if (p.char() === "<" && p.char(1) === "!") {
              switch (p.char(2)) {
                case "E":
                  if (p.char(3) === "L") {
                    current = p.getMatch(g.elementdecl);
                  } else if (p.char(3) === "N") {
                    current = p.getMatch(g.EntityDecl);
                  }
                  break;
                case "A":
                  current = p.getMatch(g.AttlistDecl);
                  break;
                case "N":
                  current = p.getMatch(g.NotationDecl);
                  break;
                case "-":
                  current = p.getMatch(g.Comment);
                  break;
              }
            } else if (p.char() === "<" && p.char(1) === "?") {
              current = parsePI(p, errorHandler);
            } else if (p.char() === "%") {
              current = p.getMatch(g.PEReference);
            } else {
              return errorHandler.fatalError("Error detected in Markup declaration");
            }
            if (!current) {
              return errorHandler.fatalError("Error in internal subset at position " + p.getIndex());
            }
          }
          return errorHandler.fatalError("doctype internal subset is not well-formed, missing ]");
        }
      }
      function parseDoctypeCommentOrCData(source, start, domBuilder, errorHandler, isHTML) {
        var p = parseUtils(source, start);
        switch (isHTML ? p.char(2).toUpperCase() : p.char(2)) {
          case "-":
            var comment = p.getMatch(g.Comment);
            if (comment) {
              domBuilder.comment(comment, g.COMMENT_START.length, comment.length - g.COMMENT_START.length - g.COMMENT_END.length);
              return p.getIndex();
            } else {
              return errorHandler.fatalError("comment is not well-formed at position " + p.getIndex());
            }
          case "[":
            var cdata = p.getMatch(g.CDSect);
            if (cdata) {
              if (!isHTML && !domBuilder.currentElement) {
                return errorHandler.fatalError("CDATA outside of element");
              }
              domBuilder.startCDATA();
              domBuilder.characters(cdata, g.CDATA_START.length, cdata.length - g.CDATA_START.length - g.CDATA_END.length);
              domBuilder.endCDATA();
              return p.getIndex();
            } else {
              return errorHandler.fatalError("Invalid CDATA starting at position " + start);
            }
          case "D": {
            if (domBuilder.doc && domBuilder.doc.documentElement) {
              return errorHandler.fatalError("Doctype not allowed inside or after documentElement at position " + p.getIndex());
            }
            if (isHTML ? !p.substringStartsWithCaseInsensitive(g.DOCTYPE_DECL_START) : !p.substringStartsWith(g.DOCTYPE_DECL_START)) {
              return errorHandler.fatalError("Expected " + g.DOCTYPE_DECL_START + " at position " + p.getIndex());
            }
            p.skip(g.DOCTYPE_DECL_START.length);
            if (p.skipBlanks() < 1) {
              return errorHandler.fatalError("Expected whitespace after " + g.DOCTYPE_DECL_START + " at position " + p.getIndex());
            }
            var doctype = {
              name: void 0,
              publicId: void 0,
              systemId: void 0,
              internalSubset: void 0
            };
            doctype.name = p.getMatch(g.Name);
            if (!doctype.name)
              return errorHandler.fatalError("doctype name missing or contains unexpected characters at position " + p.getIndex());
            if (isHTML && doctype.name.toLowerCase() !== "html") {
              errorHandler.warning("Unexpected DOCTYPE in HTML document at position " + p.getIndex());
            }
            p.skipBlanks();
            if (p.substringStartsWith(g.PUBLIC) || p.substringStartsWith(g.SYSTEM)) {
              var match = g.ExternalID_match.exec(p.substringFromIndex());
              if (!match) {
                return errorHandler.fatalError("doctype external id is not well-formed at position " + p.getIndex());
              }
              if (match.groups.SystemLiteralOnly !== void 0) {
                doctype.systemId = match.groups.SystemLiteralOnly;
              } else {
                doctype.systemId = match.groups.SystemLiteral;
                doctype.publicId = match.groups.PubidLiteral;
              }
              p.skip(match[0].length);
            } else if (isHTML && p.substringStartsWithCaseInsensitive(g.SYSTEM)) {
              p.skip(g.SYSTEM.length);
              if (p.skipBlanks() < 1) {
                return errorHandler.fatalError("Expected whitespace after " + g.SYSTEM + " at position " + p.getIndex());
              }
              doctype.systemId = p.getMatch(g.ABOUT_LEGACY_COMPAT_SystemLiteral);
              if (!doctype.systemId) {
                return errorHandler.fatalError(
                  "Expected " + g.ABOUT_LEGACY_COMPAT + " in single or double quotes after " + g.SYSTEM + " at position " + p.getIndex()
                );
              }
            }
            if (isHTML && doctype.systemId && !g.ABOUT_LEGACY_COMPAT_SystemLiteral.test(doctype.systemId)) {
              errorHandler.warning("Unexpected doctype.systemId in HTML document at position " + p.getIndex());
            }
            if (!isHTML) {
              p.skipBlanks();
              doctype.internalSubset = parseDoctypeInternalSubset(p, errorHandler);
            }
            p.skipBlanks();
            if (p.char() !== ">") {
              return errorHandler.fatalError("doctype not terminated with > at position " + p.getIndex());
            }
            p.skip(1);
            domBuilder.startDTD(doctype.name, doctype.publicId, doctype.systemId, doctype.internalSubset);
            domBuilder.endDTD();
            return p.getIndex();
          }
          default:
            return errorHandler.fatalError('Not well-formed XML starting with "<!" at position ' + start);
        }
      }
      function parseProcessingInstruction(source, start, domBuilder, errorHandler) {
        var match = source.substring(start).match(g.PI);
        if (!match) {
          return errorHandler.fatalError("Invalid processing instruction starting at position " + start);
        }
        if (match[1].toLowerCase() === "xml") {
          if (start > 0) {
            return errorHandler.fatalError(
              "processing instruction at position " + start + " is an xml declaration which is only at the start of the document"
            );
          }
          if (!g.XMLDecl.test(source.substring(start))) {
            return errorHandler.fatalError("xml declaration is not well-formed");
          }
        }
        domBuilder.processingInstruction(match[1], match[2]);
        return start + match[0].length;
      }
      function ElementAttributes() {
        this.attributeNames = /* @__PURE__ */ Object.create(null);
      }
      ElementAttributes.prototype = {
        setTagName: function(tagName) {
          if (!g.QName_exact.test(tagName)) {
            throw new Error("invalid tagName:" + tagName);
          }
          this.tagName = tagName;
        },
        addValue: function(qName, value, offset) {
          if (!g.QName_exact.test(qName)) {
            throw new Error("invalid attribute:" + qName);
          }
          this.attributeNames[qName] = this.length;
          this[this.length++] = { qName, value, offset };
        },
        length: 0,
        getLocalName: function(i) {
          return this[i].localName;
        },
        getLocator: function(i) {
          return this[i].locator;
        },
        getQName: function(i) {
          return this[i].qName;
        },
        getURI: function(i) {
          return this[i].uri;
        },
        getValue: function(i) {
          return this[i].value;
        }
        //	,getIndex:function(uri, localName)){
        //		if(localName){
        //
        //		}else{
        //			var qName = uri
        //		}
        //	},
        //	getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
        //	getType:function(uri,localName){}
        //	getType:function(i){},
      };
      exports2.XMLReader = XMLReader;
      exports2.parseUtils = parseUtils;
      exports2.parseDoctypeCommentOrCData = parseDoctypeCommentOrCData;
    }
  });

  // node_modules/@xmldom/xmldom/lib/dom-parser.js
  var require_dom_parser = __commonJS({
    "node_modules/@xmldom/xmldom/lib/dom-parser.js"(exports2) {
      "use strict";
      var conventions = require_conventions();
      var dom = require_dom();
      var errors = require_errors2();
      var entities = require_entities();
      var sax = require_sax();
      var DOMImplementation = dom.DOMImplementation;
      var hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
      var isHTMLMimeType = conventions.isHTMLMimeType;
      var isValidMimeType = conventions.isValidMimeType;
      var MIME_TYPE = conventions.MIME_TYPE;
      var NAMESPACE = conventions.NAMESPACE;
      var ParseError = errors.ParseError;
      var XMLReader = sax.XMLReader;
      function normalizeLineEndings(input) {
        return input.replace(/\r[\n\u0085]/g, "\n").replace(/[\r\u0085\u2028\u2029]/g, "\n");
      }
      function DOMParser2(options) {
        options = options || {};
        if (options.locator === void 0) {
          options.locator = true;
        }
        this.assign = options.assign || conventions.assign;
        this.domHandler = options.domHandler || DOMHandler;
        this.onError = options.onError || options.errorHandler;
        if (options.errorHandler && typeof options.errorHandler !== "function") {
          throw new TypeError("errorHandler object is no longer supported, switch to onError!");
        } else if (options.errorHandler) {
          options.errorHandler("warning", "The `errorHandler` option has been deprecated, use `onError` instead!", this);
        }
        this.normalizeLineEndings = options.normalizeLineEndings || normalizeLineEndings;
        this.locator = !!options.locator;
        this.xmlns = this.assign(/* @__PURE__ */ Object.create(null), options.xmlns);
      }
      DOMParser2.prototype.parseFromString = function(source, mimeType) {
        if (!isValidMimeType(mimeType)) {
          throw new TypeError('DOMParser.parseFromString: the provided mimeType "' + mimeType + '" is not valid.');
        }
        var defaultNSMap = this.assign(/* @__PURE__ */ Object.create(null), this.xmlns);
        var entityMap = entities.XML_ENTITIES;
        var defaultNamespace = defaultNSMap[""] || null;
        if (hasDefaultHTMLNamespace(mimeType)) {
          entityMap = entities.HTML_ENTITIES;
          defaultNamespace = NAMESPACE.HTML;
        } else if (mimeType === MIME_TYPE.XML_SVG_IMAGE) {
          defaultNamespace = NAMESPACE.SVG;
        }
        defaultNSMap[""] = defaultNamespace;
        defaultNSMap.xml = defaultNSMap.xml || NAMESPACE.XML;
        var domBuilder = new this.domHandler({
          mimeType,
          defaultNamespace,
          onError: this.onError
        });
        var locator = this.locator ? {} : void 0;
        if (this.locator) {
          domBuilder.setDocumentLocator(locator);
        }
        var sax2 = new XMLReader();
        sax2.errorHandler = domBuilder;
        sax2.domBuilder = domBuilder;
        var isXml = !conventions.isHTMLMimeType(mimeType);
        if (isXml && typeof source !== "string") {
          sax2.errorHandler.fatalError("source is not a string");
        }
        sax2.parse(this.normalizeLineEndings(String(source)), defaultNSMap, entityMap);
        if (!domBuilder.doc.documentElement) {
          sax2.errorHandler.fatalError("missing root element");
        }
        return domBuilder.doc;
      };
      function DOMHandler(options) {
        var opt = options || {};
        this.mimeType = opt.mimeType || MIME_TYPE.XML_APPLICATION;
        this.defaultNamespace = opt.defaultNamespace || null;
        this.cdata = false;
        this.currentElement = void 0;
        this.doc = void 0;
        this.locator = void 0;
        this.onError = opt.onError;
      }
      function position(locator, node) {
        node.lineNumber = locator.lineNumber;
        node.columnNumber = locator.columnNumber;
      }
      DOMHandler.prototype = {
        /**
         * Either creates an XML or an HTML document and stores it under `this.doc`.
         * If it is an XML document, `this.defaultNamespace` is used to create it,
         * and it will not contain any `childNodes`.
         * If it is an HTML document, it will be created without any `childNodes`.
         *
         * @see http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
         */
        startDocument: function() {
          var impl = new DOMImplementation();
          this.doc = isHTMLMimeType(this.mimeType) ? impl.createHTMLDocument(false) : impl.createDocument(this.defaultNamespace, "");
        },
        startElement: function(namespaceURI, localName, qName, attrs) {
          var doc = this.doc;
          var el = doc.createElementNS(namespaceURI, qName || localName);
          var len = attrs.length;
          appendElement(this, el);
          this.currentElement = el;
          this.locator && position(this.locator, el);
          for (var i = 0; i < len; i++) {
            var namespaceURI = attrs.getURI(i);
            var value = attrs.getValue(i);
            var qName = attrs.getQName(i);
            var attr = doc.createAttributeNS(namespaceURI, qName);
            this.locator && position(attrs.getLocator(i), attr);
            attr.value = attr.nodeValue = value;
            el.setAttributeNode(attr);
          }
        },
        endElement: function(namespaceURI, localName, qName) {
          this.currentElement = this.currentElement.parentNode;
        },
        startPrefixMapping: function(prefix, uri) {
        },
        endPrefixMapping: function(prefix) {
        },
        processingInstruction: function(target, data) {
          var ins = this.doc.createProcessingInstruction(target, data);
          this.locator && position(this.locator, ins);
          appendElement(this, ins);
        },
        ignorableWhitespace: function(ch, start, length) {
        },
        characters: function(chars, start, length) {
          chars = _toString.apply(this, arguments);
          if (chars) {
            if (this.cdata) {
              var charNode = this.doc.createCDATASection(chars);
            } else {
              var charNode = this.doc.createTextNode(chars);
            }
            if (this.currentElement) {
              this.currentElement.appendChild(charNode);
            } else if (/^\s*$/.test(chars)) {
              this.doc.appendChild(charNode);
            }
            this.locator && position(this.locator, charNode);
          }
        },
        skippedEntity: function(name2) {
        },
        endDocument: function() {
          this.doc.normalize();
        },
        /**
         * Stores the locator to be able to set the `columnNumber` and `lineNumber`
         * on the created DOM nodes.
         *
         * @param {Locator} locator
         */
        setDocumentLocator: function(locator) {
          if (locator) {
            locator.lineNumber = 0;
          }
          this.locator = locator;
        },
        //LexicalHandler
        comment: function(chars, start, length) {
          chars = _toString.apply(this, arguments);
          var comm = this.doc.createComment(chars);
          this.locator && position(this.locator, comm);
          appendElement(this, comm);
        },
        startCDATA: function() {
          this.cdata = true;
        },
        endCDATA: function() {
          this.cdata = false;
        },
        startDTD: function(name2, publicId, systemId, internalSubset) {
          var impl = this.doc.implementation;
          if (impl && impl.createDocumentType) {
            var dt = impl.createDocumentType(name2, publicId, systemId, internalSubset);
            this.locator && position(this.locator, dt);
            appendElement(this, dt);
            this.doc.doctype = dt;
          }
        },
        reportError: function(level, message) {
          if (typeof this.onError === "function") {
            try {
              this.onError(level, message, this);
            } catch (e) {
              throw new ParseError("Reporting " + level + ' "' + message + '" caused ' + e, this.locator);
            }
          } else {
            console.error("[xmldom " + level + "]	" + message, _locator(this.locator));
          }
        },
        /**
         * @see http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
         */
        warning: function(message) {
          this.reportError("warning", message);
        },
        error: function(message) {
          this.reportError("error", message);
        },
        /**
         * This function reports a fatal error and throws a ParseError.
         *
         * @param {string} message
         * - The message to be used for reporting and throwing the error.
         * @returns {never}
         * This function always throws an error and never returns a value.
         * @throws {ParseError}
         * Always throws a ParseError with the provided message.
         */
        fatalError: function(message) {
          this.reportError("fatalError", message);
          throw new ParseError(message, this.locator);
        }
      };
      function _locator(l) {
        if (l) {
          return "\n@#[line:" + l.lineNumber + ",col:" + l.columnNumber + "]";
        }
      }
      function _toString(chars, start, length) {
        if (typeof chars == "string") {
          return chars.substr(start, length);
        } else {
          if (chars.length >= start + length || start) {
            return new java.lang.String(chars, start, length) + "";
          }
          return chars;
        }
      }
      "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(
        /\w+/g,
        function(key) {
          DOMHandler.prototype[key] = function() {
            return null;
          };
        }
      );
      function appendElement(handler, node) {
        if (!handler.currentElement) {
          handler.doc.appendChild(node);
        } else {
          handler.currentElement.appendChild(node);
        }
      }
      function onErrorStopParsing(level) {
        if (level === "error") throw "onErrorStopParsing";
      }
      function onWarningStopParsing() {
        throw "onWarningStopParsing";
      }
      exports2.__DOMHandler = DOMHandler;
      exports2.DOMParser = DOMParser2;
      exports2.normalizeLineEndings = normalizeLineEndings;
      exports2.onErrorStopParsing = onErrorStopParsing;
      exports2.onWarningStopParsing = onWarningStopParsing;
    }
  });

  // node_modules/@xmldom/xmldom/lib/index.js
  var require_lib = __commonJS({
    "node_modules/@xmldom/xmldom/lib/index.js"(exports2) {
      "use strict";
      var conventions = require_conventions();
      exports2.assign = conventions.assign;
      exports2.hasDefaultHTMLNamespace = conventions.hasDefaultHTMLNamespace;
      exports2.isHTMLMimeType = conventions.isHTMLMimeType;
      exports2.isValidMimeType = conventions.isValidMimeType;
      exports2.MIME_TYPE = conventions.MIME_TYPE;
      exports2.NAMESPACE = conventions.NAMESPACE;
      var errors = require_errors2();
      exports2.DOMException = errors.DOMException;
      exports2.DOMExceptionName = errors.DOMExceptionName;
      exports2.ExceptionCode = errors.ExceptionCode;
      exports2.ParseError = errors.ParseError;
      var dom = require_dom();
      exports2.Attr = dom.Attr;
      exports2.CDATASection = dom.CDATASection;
      exports2.CharacterData = dom.CharacterData;
      exports2.Comment = dom.Comment;
      exports2.Document = dom.Document;
      exports2.DocumentFragment = dom.DocumentFragment;
      exports2.DocumentType = dom.DocumentType;
      exports2.DOMImplementation = dom.DOMImplementation;
      exports2.Element = dom.Element;
      exports2.Entity = dom.Entity;
      exports2.EntityReference = dom.EntityReference;
      exports2.LiveNodeList = dom.LiveNodeList;
      exports2.NamedNodeMap = dom.NamedNodeMap;
      exports2.Node = dom.Node;
      exports2.NodeList = dom.NodeList;
      exports2.Notation = dom.Notation;
      exports2.ProcessingInstruction = dom.ProcessingInstruction;
      exports2.Text = dom.Text;
      exports2.XMLSerializer = dom.XMLSerializer;
      var domParser = require_dom_parser();
      exports2.DOMParser = domParser.DOMParser;
      exports2.normalizeLineEndings = domParser.normalizeLineEndings;
      exports2.onErrorStopParsing = domParser.onErrorStopParsing;
      exports2.onWarningStopParsing = domParser.onWarningStopParsing;
    }
  });

  // node_modules/xpath/xpath.js
  var require_xpath = __commonJS({
    "node_modules/xpath/xpath.js"(exports2) {
      var xpath = typeof exports2 === "undefined" ? {} : exports2;
      (function(exports3) {
        "use strict";
        var NAMESPACE_NODE_NODETYPE = "__namespace";
        var isNil = function(x) {
          return x === null || x === void 0;
        };
        var isValidNodeType = function(nodeType) {
          return nodeType === NAMESPACE_NODE_NODETYPE || Number.isInteger(nodeType) && nodeType >= 1 && nodeType <= 11;
        };
        var isNodeLike = function(value) {
          return value && isValidNodeType(value.nodeType) && typeof value.nodeName === "string";
        };
        function curry(func) {
          var slice = Array.prototype.slice, totalargs = func.length, partial = function(args, fn3) {
            return function() {
              return fn3.apply(this, args.concat(slice.call(arguments)));
            };
          }, fn2 = function() {
            var args = slice.call(arguments);
            return args.length < totalargs ? partial(args, fn2) : func.apply(this, slice.apply(arguments, [0, totalargs]));
          };
          return fn2;
        }
        var forEach = function(f, xs) {
          for (var i = 0; i < xs.length; i += 1) {
            f(xs[i], i, xs);
          }
        };
        var reduce = function(f, seed, xs) {
          var acc = seed;
          forEach(function(x, i) {
            acc = f(acc, x, i);
          }, xs);
          return acc;
        };
        var map = function(f, xs) {
          var mapped = new Array(xs.length);
          forEach(function(x, i) {
            mapped[i] = f(x);
          }, xs);
          return mapped;
        };
        var filter = function(f, xs) {
          var filtered = [];
          forEach(function(x, i) {
            if (f(x, i)) {
              filtered.push(x);
            }
          }, xs);
          return filtered;
        };
        var includes = function(values, value) {
          for (var i = 0; i < values.length; i += 1) {
            if (values[i] === value) {
              return true;
            }
          }
          return false;
        };
        function always(value) {
          return function() {
            return value;
          };
        }
        function toString(x) {
          return x.toString();
        }
        var join = function(s, xs) {
          return xs.join(s);
        };
        var wrap = function(pref, suf, str) {
          return pref + str + suf;
        };
        var prototypeConcat = Array.prototype.concat;
        var sortNodes = function(nodes, reverse) {
          var ns = new XNodeSet();
          ns.addArray(nodes);
          var sorted = ns.toArray();
          return reverse ? sorted.reverse() : sorted;
        };
        var MAX_ARGUMENT_LENGTH = 32767;
        function flatten(arr) {
          var result = [];
          for (var start = 0; start < arr.length; start += MAX_ARGUMENT_LENGTH) {
            var chunk = arr.slice(start, start + MAX_ARGUMENT_LENGTH);
            result = prototypeConcat.apply(result, chunk);
          }
          return result;
        }
        function assign(target, varArgs) {
          var to = Object(target);
          for (var index = 1; index < arguments.length; index++) {
            var nextSource = arguments[index];
            if (nextSource != null) {
              for (var nextKey in nextSource) {
                if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
                  to[nextKey] = nextSource[nextKey];
                }
              }
            }
          }
          return to;
        }
        var NodeTypes = {
          ELEMENT_NODE: 1,
          ATTRIBUTE_NODE: 2,
          TEXT_NODE: 3,
          CDATA_SECTION_NODE: 4,
          PROCESSING_INSTRUCTION_NODE: 7,
          COMMENT_NODE: 8,
          DOCUMENT_NODE: 9,
          DOCUMENT_TYPE_NODE: 10,
          DOCUMENT_FRAGMENT_NODE: 11,
          NAMESPACE_NODE: NAMESPACE_NODE_NODETYPE
        };
        XPathParser.prototype = new Object();
        XPathParser.prototype.constructor = XPathParser;
        XPathParser.superclass = Object.prototype;
        function XPathParser() {
          this.init();
        }
        XPathParser.prototype.init = function() {
          this.reduceActions = [];
          this.reduceActions[3] = function(rhs) {
            return new OrOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[5] = function(rhs) {
            return new AndOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[7] = function(rhs) {
            return new EqualsOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[8] = function(rhs) {
            return new NotEqualOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[10] = function(rhs) {
            return new LessThanOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[11] = function(rhs) {
            return new GreaterThanOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[12] = function(rhs) {
            return new LessThanOrEqualOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[13] = function(rhs) {
            return new GreaterThanOrEqualOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[15] = function(rhs) {
            return new PlusOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[16] = function(rhs) {
            return new MinusOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[18] = function(rhs) {
            return new MultiplyOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[19] = function(rhs) {
            return new DivOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[20] = function(rhs) {
            return new ModOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[22] = function(rhs) {
            return new UnaryMinusOperation(rhs[1]);
          };
          this.reduceActions[24] = function(rhs) {
            return new BarOperation(rhs[0], rhs[2]);
          };
          this.reduceActions[25] = function(rhs) {
            return new PathExpr(void 0, void 0, rhs[0]);
          };
          this.reduceActions[27] = function(rhs) {
            rhs[0].locationPath = rhs[2];
            return rhs[0];
          };
          this.reduceActions[28] = function(rhs) {
            rhs[0].locationPath = rhs[2];
            rhs[0].locationPath.steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
            return rhs[0];
          };
          this.reduceActions[29] = function(rhs) {
            return new PathExpr(rhs[0], [], void 0);
          };
          this.reduceActions[30] = function(rhs) {
            if (Utilities.instance_of(rhs[0], PathExpr)) {
              if (rhs[0].filterPredicates == void 0) {
                rhs[0].filterPredicates = [];
              }
              rhs[0].filterPredicates.push(rhs[1]);
              return rhs[0];
            } else {
              return new PathExpr(rhs[0], [rhs[1]], void 0);
            }
          };
          this.reduceActions[32] = function(rhs) {
            return rhs[1];
          };
          this.reduceActions[33] = function(rhs) {
            return new XString(rhs[0]);
          };
          this.reduceActions[34] = function(rhs) {
            return new XNumber(rhs[0]);
          };
          this.reduceActions[36] = function(rhs) {
            return new FunctionCall(rhs[0], []);
          };
          this.reduceActions[37] = function(rhs) {
            return new FunctionCall(rhs[0], rhs[2]);
          };
          this.reduceActions[38] = function(rhs) {
            return [rhs[0]];
          };
          this.reduceActions[39] = function(rhs) {
            rhs[2].unshift(rhs[0]);
            return rhs[2];
          };
          this.reduceActions[43] = function(rhs) {
            return new LocationPath(true, []);
          };
          this.reduceActions[44] = function(rhs) {
            rhs[1].absolute = true;
            return rhs[1];
          };
          this.reduceActions[46] = function(rhs) {
            return new LocationPath(false, [rhs[0]]);
          };
          this.reduceActions[47] = function(rhs) {
            rhs[0].steps.push(rhs[2]);
            return rhs[0];
          };
          this.reduceActions[49] = function(rhs) {
            return new Step(rhs[0], rhs[1], []);
          };
          this.reduceActions[50] = function(rhs) {
            return new Step(Step.CHILD, rhs[0], []);
          };
          this.reduceActions[51] = function(rhs) {
            return new Step(rhs[0], rhs[1], rhs[2]);
          };
          this.reduceActions[52] = function(rhs) {
            return new Step(Step.CHILD, rhs[0], rhs[1]);
          };
          this.reduceActions[54] = function(rhs) {
            return [rhs[0]];
          };
          this.reduceActions[55] = function(rhs) {
            rhs[1].unshift(rhs[0]);
            return rhs[1];
          };
          this.reduceActions[56] = function(rhs) {
            if (rhs[0] == "ancestor") {
              return Step.ANCESTOR;
            } else if (rhs[0] == "ancestor-or-self") {
              return Step.ANCESTORORSELF;
            } else if (rhs[0] == "attribute") {
              return Step.ATTRIBUTE;
            } else if (rhs[0] == "child") {
              return Step.CHILD;
            } else if (rhs[0] == "descendant") {
              return Step.DESCENDANT;
            } else if (rhs[0] == "descendant-or-self") {
              return Step.DESCENDANTORSELF;
            } else if (rhs[0] == "following") {
              return Step.FOLLOWING;
            } else if (rhs[0] == "following-sibling") {
              return Step.FOLLOWINGSIBLING;
            } else if (rhs[0] == "namespace") {
              return Step.NAMESPACE;
            } else if (rhs[0] == "parent") {
              return Step.PARENT;
            } else if (rhs[0] == "preceding") {
              return Step.PRECEDING;
            } else if (rhs[0] == "preceding-sibling") {
              return Step.PRECEDINGSIBLING;
            } else if (rhs[0] == "self") {
              return Step.SELF;
            }
            return -1;
          };
          this.reduceActions[57] = function(rhs) {
            return Step.ATTRIBUTE;
          };
          this.reduceActions[59] = function(rhs) {
            if (rhs[0] == "comment") {
              return NodeTest.commentTest;
            } else if (rhs[0] == "text") {
              return NodeTest.textTest;
            } else if (rhs[0] == "processing-instruction") {
              return NodeTest.anyPiTest;
            } else if (rhs[0] == "node") {
              return NodeTest.nodeTest;
            }
            return new NodeTest(-1, void 0);
          };
          this.reduceActions[60] = function(rhs) {
            return new NodeTest.PITest(rhs[2]);
          };
          this.reduceActions[61] = function(rhs) {
            return rhs[1];
          };
          this.reduceActions[63] = function(rhs) {
            rhs[1].absolute = true;
            rhs[1].steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
            return rhs[1];
          };
          this.reduceActions[64] = function(rhs) {
            rhs[0].steps.push(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
            rhs[0].steps.push(rhs[2]);
            return rhs[0];
          };
          this.reduceActions[65] = function(rhs) {
            return new Step(Step.SELF, NodeTest.nodeTest, []);
          };
          this.reduceActions[66] = function(rhs) {
            return new Step(Step.PARENT, NodeTest.nodeTest, []);
          };
          this.reduceActions[67] = function(rhs) {
            return new VariableReference(rhs[1]);
          };
          this.reduceActions[68] = function(rhs) {
            return NodeTest.nameTestAny;
          };
          this.reduceActions[69] = function(rhs) {
            return new NodeTest.NameTestPrefixAny(rhs[0].split(":")[0]);
          };
          this.reduceActions[70] = function(rhs) {
            return new NodeTest.NameTestQName(rhs[0]);
          };
        };
        XPathParser.actionTable = [
          " s s        sssssssss    s ss  s  ss",
          "                 s                  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "                rrrrr               ",
          " s s        sssssssss    s ss  s  ss",
          "rs  rrrrrrrr s  sssssrrrrrr  rrs rs ",
          " s s        sssssssss    s ss  s  ss",
          "                            s       ",
          "                            s       ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "  s                                 ",
          "                            s       ",
          " s           s  sssss          s  s ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "a                                   ",
          "r       s                    rr  r  ",
          "r      sr                    rr  r  ",
          "r   s  rr            s       rr  r  ",
          "r   rssrr            rss     rr  r  ",
          "r   rrrrr            rrrss   rr  r  ",
          "r   rrrrrsss         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrrs  rr  r  ",
          "r   rrrrrrrr         rrrrrr  rr  r  ",
          "r   rrrrrrrr         rrrrrr  rr  r  ",
          "r  srrrrrrrr         rrrrrrs rr sr  ",
          "r  srrrrrrrr         rrrrrrs rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r   rrrrrrrr         rrrrrr  rr  r  ",
          "r   rrrrrrrr         rrrrrr  rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "                sssss               ",
          "r  rrrrrrrrr         rrrrrrr rr sr  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "                             s      ",
          "r  srrrrrrrr         rrrrrrs rr  r  ",
          "r   rrrrrrrr         rrrrr   rr  r  ",
          "              s                     ",
          "                             s      ",
          "                rrrrr               ",
          " s s        sssssssss    s sss s  ss",
          "r  srrrrrrrr         rrrrrrs rr  r  ",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s s        sssssssss      ss  s  ss",
          " s s        sssssssss    s ss  s  ss",
          " s           s  sssss          s  s ",
          " s           s  sssss          s  s ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          " s           s  sssss          s  s ",
          " s           s  sssss          s  s ",
          "r  rrrrrrrrr         rrrrrrr rr sr  ",
          "r  rrrrrrrrr         rrrrrrr rr sr  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "                             s      ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "                             rr     ",
          "                             s      ",
          "                             rs     ",
          "r      sr                    rr  r  ",
          "r   s  rr            s       rr  r  ",
          "r   rssrr            rss     rr  r  ",
          "r   rssrr            rss     rr  r  ",
          "r   rrrrr            rrrss   rr  r  ",
          "r   rrrrr            rrrss   rr  r  ",
          "r   rrrrr            rrrss   rr  r  ",
          "r   rrrrr            rrrss   rr  r  ",
          "r   rrrrrsss         rrrrr   rr  r  ",
          "r   rrrrrsss         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrr   rr  r  ",
          "r   rrrrrrrr         rrrrrr  rr  r  ",
          "                                 r  ",
          "                                 s  ",
          "r  srrrrrrrr         rrrrrrs rr  r  ",
          "r  srrrrrrrr         rrrrrrs rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr  r  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          " s s        sssssssss    s ss  s  ss",
          "r  rrrrrrrrr         rrrrrrr rr rr  ",
          "                             r      "
        ];
        XPathParser.actionTableNumber = [
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          "                 J                  ",
          "a  aaaaaaaaa         aaaaaaa aa  a  ",
          "                YYYYY               ",
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          `K1  KKKKKKKK .  +*)('KKKKKK  KK# K" `,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          "                            N       ",
          "                            O       ",
          "e  eeeeeeeee         eeeeeee ee ee  ",
          "f  fffffffff         fffffff ff ff  ",
          "d  ddddddddd         ddddddd dd dd  ",
          "B  BBBBBBBBB         BBBBBBB BB BB  ",
          "A  AAAAAAAAA         AAAAAAA AA AA  ",
          "  P                                 ",
          "                            Q       ",
          ` 1           .  +*)('          #  " `,
          "b  bbbbbbbbb         bbbbbbb bb  b  ",
          "                                    ",
          "!       S                    !!  !  ",
          '"      T"                    ""  "  ',
          "$   V  $$            U       $$  $  ",
          "&   &ZY&&            &XW     &&  &  ",
          ")   )))))            )))\\[   ))  )  ",
          ".   ....._^]         .....   ..  .  ",
          "1   11111111         11111   11  1  ",
          "5   55555555         55555`  55  5  ",
          "7   77777777         777777  77  7  ",
          "9   99999999         999999  99  9  ",
          ":  c::::::::         ::::::b :: a:  ",
          "I  fIIIIIIII         IIIIIIe II  I  ",
          "=  =========         ======= == ==  ",
          "?  ?????????         ??????? ?? ??  ",
          "C  CCCCCCCCC         CCCCCCC CC CC  ",
          "J   JJJJJJJJ         JJJJJJ  JJ  J  ",
          "M   MMMMMMMM         MMMMMM  MM  M  ",
          "N  NNNNNNNNN         NNNNNNN NN  N  ",
          "P  PPPPPPPPP         PPPPPPP PP  P  ",
          "                +*)('               ",
          "R  RRRRRRRRR         RRRRRRR RR aR  ",
          "U  UUUUUUUUU         UUUUUUU UU  U  ",
          "Z  ZZZZZZZZZ         ZZZZZZZ ZZ ZZ  ",
          "c  ccccccccc         ccccccc cc cc  ",
          "                             j      ",
          "L  fLLLLLLLL         LLLLLLe LL  L  ",
          "6   66666666         66666   66  6  ",
          "              k                     ",
          "                             l      ",
          "                XXXXX               ",
          ` 1 0        /.-,+*)('    & %$m #  "!`,
          "_  f________         ______e __  _  ",
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1 0        /.-,+*)('      %$  #  "!`,
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          ` 1           .  +*)('          #  " `,
          ` 1           .  +*)('          #  " `,
          ">  >>>>>>>>>         >>>>>>> >> >>  ",
          ` 1           .  +*)('          #  " `,
          ` 1           .  +*)('          #  " `,
          "Q  QQQQQQQQQ         QQQQQQQ QQ aQ  ",
          "V  VVVVVVVVV         VVVVVVV VV aV  ",
          "T  TTTTTTTTT         TTTTTTT TT  T  ",
          "@  @@@@@@@@@         @@@@@@@ @@ @@  ",
          "                             \x87      ",
          "[  [[[[[[[[[         [[[[[[[ [[ [[  ",
          "D  DDDDDDDDD         DDDDDDD DD DD  ",
          "                             HH     ",
          "                             \x88      ",
          "                             F\x89     ",
          "#      T#                    ##  #  ",
          "%   V  %%            U       %%  %  ",
          "'   'ZY''            'XW     ''  '  ",
          "(   (ZY((            (XW     ((  (  ",
          "+   +++++            +++\\[   ++  +  ",
          "*   *****            ***\\[   **  *  ",
          "-   -----            ---\\[   --  -  ",
          ",   ,,,,,            ,,,\\[   ,,  ,  ",
          "0   00000_^]         00000   00  0  ",
          "/   /////_^]         /////   //  /  ",
          "2   22222222         22222   22  2  ",
          "3   33333333         33333   33  3  ",
          "4   44444444         44444   44  4  ",
          "8   88888888         888888  88  8  ",
          "                                 ^  ",
          "                                 \x8A  ",
          ";  f;;;;;;;;         ;;;;;;e ;;  ;  ",
          "<  f<<<<<<<<         <<<<<<e <<  <  ",
          "O  OOOOOOOOO         OOOOOOO OO  O  ",
          "`  `````````         ``````` ``  `  ",
          "S  SSSSSSSSS         SSSSSSS SS  S  ",
          "W  WWWWWWWWW         WWWWWWW WW  W  ",
          "\\  \\\\\\\\\\\\\\\\\\         \\\\\\\\\\\\\\ \\\\ \\\\  ",
          "E  EEEEEEEEE         EEEEEEE EE EE  ",
          ` 1 0        /.-,+*)('    & %$  #  "!`,
          "]  ]]]]]]]]]         ]]]]]]] ]] ]]  ",
          "                             G      "
        ];
        XPathParser.gotoTable = [
          "3456789:;<=>?@ AB  CDEFGH IJ ",
          "                             ",
          "                             ",
          "                             ",
          "L456789:;<=>?@ AB  CDEFGH IJ ",
          "            M        EFGH IJ ",
          "       N;<=>?@ AB  CDEFGH IJ ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "            S        EFGH IJ ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "              e              ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                        h  J ",
          "              i          j   ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "o456789:;<=>?@ ABpqCDEFGH IJ ",
          "                             ",
          "  r6789:;<=>?@ AB  CDEFGH IJ ",
          "   s789:;<=>?@ AB  CDEFGH IJ ",
          "    t89:;<=>?@ AB  CDEFGH IJ ",
          "    u89:;<=>?@ AB  CDEFGH IJ ",
          "     v9:;<=>?@ AB  CDEFGH IJ ",
          "     w9:;<=>?@ AB  CDEFGH IJ ",
          "     x9:;<=>?@ AB  CDEFGH IJ ",
          "     y9:;<=>?@ AB  CDEFGH IJ ",
          "      z:;<=>?@ AB  CDEFGH IJ ",
          "      {:;<=>?@ AB  CDEFGH IJ ",
          "       |;<=>?@ AB  CDEFGH IJ ",
          "       };<=>?@ AB  CDEFGH IJ ",
          "       ~;<=>?@ AB  CDEFGH IJ ",
          "         \x7F=>?@ AB  CDEFGH IJ ",
          "\x80456789:;<=>?@ AB  CDEFGH IJ\x81",
          "            \x82        EFGH IJ ",
          "            \x83        EFGH IJ ",
          "                             ",
          "                     \x84 GH IJ ",
          "                     \x85 GH IJ ",
          "              i          \x86   ",
          "              i          \x87   ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "                             ",
          "o456789:;<=>?@ AB\x8CqCDEFGH IJ ",
          "                             ",
          "                             "
        ];
        XPathParser.productions = [
          [1, 1, 2],
          [2, 1, 3],
          [3, 1, 4],
          [3, 3, 3, -9, 4],
          [4, 1, 5],
          [4, 3, 4, -8, 5],
          [5, 1, 6],
          [5, 3, 5, -22, 6],
          [5, 3, 5, -5, 6],
          [6, 1, 7],
          [6, 3, 6, -23, 7],
          [6, 3, 6, -24, 7],
          [6, 3, 6, -6, 7],
          [6, 3, 6, -7, 7],
          [7, 1, 8],
          [7, 3, 7, -25, 8],
          [7, 3, 7, -26, 8],
          [8, 1, 9],
          [8, 3, 8, -12, 9],
          [8, 3, 8, -11, 9],
          [8, 3, 8, -10, 9],
          [9, 1, 10],
          [9, 2, -26, 9],
          [10, 1, 11],
          [10, 3, 10, -27, 11],
          [11, 1, 12],
          [11, 1, 13],
          [11, 3, 13, -28, 14],
          [11, 3, 13, -4, 14],
          [13, 1, 15],
          [13, 2, 13, 16],
          [15, 1, 17],
          [15, 3, -29, 2, -30],
          [15, 1, -15],
          [15, 1, -16],
          [15, 1, 18],
          [18, 3, -13, -29, -30],
          [18, 4, -13, -29, 19, -30],
          [19, 1, 20],
          [19, 3, 20, -31, 19],
          [20, 1, 2],
          [12, 1, 14],
          [12, 1, 21],
          [21, 1, -28],
          [21, 2, -28, 14],
          [21, 1, 22],
          [14, 1, 23],
          [14, 3, 14, -28, 23],
          [14, 1, 24],
          [23, 2, 25, 26],
          [23, 1, 26],
          [23, 3, 25, 26, 27],
          [23, 2, 26, 27],
          [23, 1, 28],
          [27, 1, 16],
          [27, 2, 16, 27],
          [25, 2, -14, -3],
          [25, 1, -32],
          [26, 1, 29],
          [26, 3, -20, -29, -30],
          [26, 4, -21, -29, -15, -30],
          [16, 3, -33, 30, -34],
          [30, 1, 2],
          [22, 2, -4, 14],
          [24, 3, 14, -4, 23],
          [28, 1, -35],
          [28, 1, -2],
          [17, 2, -36, -18],
          [29, 1, -17],
          [29, 1, -19],
          [29, 1, -18]
        ];
        XPathParser.DOUBLEDOT = 2;
        XPathParser.DOUBLECOLON = 3;
        XPathParser.DOUBLESLASH = 4;
        XPathParser.NOTEQUAL = 5;
        XPathParser.LESSTHANOREQUAL = 6;
        XPathParser.GREATERTHANOREQUAL = 7;
        XPathParser.AND = 8;
        XPathParser.OR = 9;
        XPathParser.MOD = 10;
        XPathParser.DIV = 11;
        XPathParser.MULTIPLYOPERATOR = 12;
        XPathParser.FUNCTIONNAME = 13;
        XPathParser.AXISNAME = 14;
        XPathParser.LITERAL = 15;
        XPathParser.NUMBER = 16;
        XPathParser.ASTERISKNAMETEST = 17;
        XPathParser.QNAME = 18;
        XPathParser.NCNAMECOLONASTERISK = 19;
        XPathParser.NODETYPE = 20;
        XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL = 21;
        XPathParser.EQUALS = 22;
        XPathParser.LESSTHAN = 23;
        XPathParser.GREATERTHAN = 24;
        XPathParser.PLUS = 25;
        XPathParser.MINUS = 26;
        XPathParser.BAR = 27;
        XPathParser.SLASH = 28;
        XPathParser.LEFTPARENTHESIS = 29;
        XPathParser.RIGHTPARENTHESIS = 30;
        XPathParser.COMMA = 31;
        XPathParser.AT = 32;
        XPathParser.LEFTBRACKET = 33;
        XPathParser.RIGHTBRACKET = 34;
        XPathParser.DOT = 35;
        XPathParser.DOLLAR = 36;
        XPathParser.prototype.tokenize = function(s1) {
          var types = [];
          var values = [];
          var s = s1 + "\0";
          var pos = 0;
          var c = s.charAt(pos++);
          while (1) {
            while (c == " " || c == "	" || c == "\r" || c == "\n") {
              c = s.charAt(pos++);
            }
            if (c == "\0" || pos >= s.length) {
              break;
            }
            if (c == "(") {
              types.push(XPathParser.LEFTPARENTHESIS);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == ")") {
              types.push(XPathParser.RIGHTPARENTHESIS);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "[") {
              types.push(XPathParser.LEFTBRACKET);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "]") {
              types.push(XPathParser.RIGHTBRACKET);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "@") {
              types.push(XPathParser.AT);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == ",") {
              types.push(XPathParser.COMMA);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "|") {
              types.push(XPathParser.BAR);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "+") {
              types.push(XPathParser.PLUS);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "-") {
              types.push(XPathParser.MINUS);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "=") {
              types.push(XPathParser.EQUALS);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == "$") {
              types.push(XPathParser.DOLLAR);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == ".") {
              c = s.charAt(pos++);
              if (c == ".") {
                types.push(XPathParser.DOUBLEDOT);
                values.push("..");
                c = s.charAt(pos++);
                continue;
              }
              if (c >= "0" && c <= "9") {
                var number = "." + c;
                c = s.charAt(pos++);
                while (c >= "0" && c <= "9") {
                  number += c;
                  c = s.charAt(pos++);
                }
                types.push(XPathParser.NUMBER);
                values.push(number);
                continue;
              }
              types.push(XPathParser.DOT);
              values.push(".");
              continue;
            }
            if (c == "'" || c == '"') {
              var delimiter = c;
              var literal = "";
              while (pos < s.length && (c = s.charAt(pos)) !== delimiter) {
                literal += c;
                pos += 1;
              }
              if (c !== delimiter) {
                throw XPathException.fromMessage("Unterminated string literal: " + delimiter + literal);
              }
              pos += 1;
              types.push(XPathParser.LITERAL);
              values.push(literal);
              c = s.charAt(pos++);
              continue;
            }
            if (c >= "0" && c <= "9") {
              var number = c;
              c = s.charAt(pos++);
              while (c >= "0" && c <= "9") {
                number += c;
                c = s.charAt(pos++);
              }
              if (c == ".") {
                if (s.charAt(pos) >= "0" && s.charAt(pos) <= "9") {
                  number += c;
                  number += s.charAt(pos++);
                  c = s.charAt(pos++);
                  while (c >= "0" && c <= "9") {
                    number += c;
                    c = s.charAt(pos++);
                  }
                }
              }
              types.push(XPathParser.NUMBER);
              values.push(number);
              continue;
            }
            if (c == "*") {
              if (types.length > 0) {
                var last = types[types.length - 1];
                if (last != XPathParser.AT && last != XPathParser.DOUBLECOLON && last != XPathParser.LEFTPARENTHESIS && last != XPathParser.LEFTBRACKET && last != XPathParser.AND && last != XPathParser.OR && last != XPathParser.MOD && last != XPathParser.DIV && last != XPathParser.MULTIPLYOPERATOR && last != XPathParser.SLASH && last != XPathParser.DOUBLESLASH && last != XPathParser.BAR && last != XPathParser.PLUS && last != XPathParser.MINUS && last != XPathParser.EQUALS && last != XPathParser.NOTEQUAL && last != XPathParser.LESSTHAN && last != XPathParser.LESSTHANOREQUAL && last != XPathParser.GREATERTHAN && last != XPathParser.GREATERTHANOREQUAL) {
                  types.push(XPathParser.MULTIPLYOPERATOR);
                  values.push(c);
                  c = s.charAt(pos++);
                  continue;
                }
              }
              types.push(XPathParser.ASTERISKNAMETEST);
              values.push(c);
              c = s.charAt(pos++);
              continue;
            }
            if (c == ":") {
              if (s.charAt(pos) == ":") {
                types.push(XPathParser.DOUBLECOLON);
                values.push("::");
                pos++;
                c = s.charAt(pos++);
                continue;
              }
            }
            if (c == "/") {
              c = s.charAt(pos++);
              if (c == "/") {
                types.push(XPathParser.DOUBLESLASH);
                values.push("//");
                c = s.charAt(pos++);
                continue;
              }
              types.push(XPathParser.SLASH);
              values.push("/");
              continue;
            }
            if (c == "!") {
              if (s.charAt(pos) == "=") {
                types.push(XPathParser.NOTEQUAL);
                values.push("!=");
                pos++;
                c = s.charAt(pos++);
                continue;
              }
            }
            if (c == "<") {
              if (s.charAt(pos) == "=") {
                types.push(XPathParser.LESSTHANOREQUAL);
                values.push("<=");
                pos++;
                c = s.charAt(pos++);
                continue;
              }
              types.push(XPathParser.LESSTHAN);
              values.push("<");
              c = s.charAt(pos++);
              continue;
            }
            if (c == ">") {
              if (s.charAt(pos) == "=") {
                types.push(XPathParser.GREATERTHANOREQUAL);
                values.push(">=");
                pos++;
                c = s.charAt(pos++);
                continue;
              }
              types.push(XPathParser.GREATERTHAN);
              values.push(">");
              c = s.charAt(pos++);
              continue;
            }
            if (c == "_" || Utilities.isLetter(c.charCodeAt(0))) {
              var name2 = c;
              c = s.charAt(pos++);
              while (Utilities.isNCNameChar(c.charCodeAt(0))) {
                name2 += c;
                c = s.charAt(pos++);
              }
              if (types.length > 0) {
                var last = types[types.length - 1];
                if (last != XPathParser.AT && last != XPathParser.DOUBLECOLON && last != XPathParser.LEFTPARENTHESIS && last != XPathParser.LEFTBRACKET && last != XPathParser.AND && last != XPathParser.OR && last != XPathParser.MOD && last != XPathParser.DIV && last != XPathParser.MULTIPLYOPERATOR && last != XPathParser.SLASH && last != XPathParser.DOUBLESLASH && last != XPathParser.BAR && last != XPathParser.PLUS && last != XPathParser.MINUS && last != XPathParser.EQUALS && last != XPathParser.NOTEQUAL && last != XPathParser.LESSTHAN && last != XPathParser.LESSTHANOREQUAL && last != XPathParser.GREATERTHAN && last != XPathParser.GREATERTHANOREQUAL) {
                  if (name2 == "and") {
                    types.push(XPathParser.AND);
                    values.push(name2);
                    continue;
                  }
                  if (name2 == "or") {
                    types.push(XPathParser.OR);
                    values.push(name2);
                    continue;
                  }
                  if (name2 == "mod") {
                    types.push(XPathParser.MOD);
                    values.push(name2);
                    continue;
                  }
                  if (name2 == "div") {
                    types.push(XPathParser.DIV);
                    values.push(name2);
                    continue;
                  }
                }
              }
              if (c == ":") {
                if (s.charAt(pos) == "*") {
                  types.push(XPathParser.NCNAMECOLONASTERISK);
                  values.push(name2 + ":*");
                  pos++;
                  c = s.charAt(pos++);
                  continue;
                }
                if (s.charAt(pos) == "_" || Utilities.isLetter(s.charCodeAt(pos))) {
                  name2 += ":";
                  c = s.charAt(pos++);
                  while (Utilities.isNCNameChar(c.charCodeAt(0))) {
                    name2 += c;
                    c = s.charAt(pos++);
                  }
                  if (c == "(") {
                    types.push(XPathParser.FUNCTIONNAME);
                    values.push(name2);
                    continue;
                  }
                  types.push(XPathParser.QNAME);
                  values.push(name2);
                  continue;
                }
                if (s.charAt(pos) == ":") {
                  types.push(XPathParser.AXISNAME);
                  values.push(name2);
                  continue;
                }
              }
              if (c == "(") {
                if (name2 == "comment" || name2 == "text" || name2 == "node") {
                  types.push(XPathParser.NODETYPE);
                  values.push(name2);
                  continue;
                }
                if (name2 == "processing-instruction") {
                  if (s.charAt(pos) == ")") {
                    types.push(XPathParser.NODETYPE);
                  } else {
                    types.push(XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL);
                  }
                  values.push(name2);
                  continue;
                }
                types.push(XPathParser.FUNCTIONNAME);
                values.push(name2);
                continue;
              }
              types.push(XPathParser.QNAME);
              values.push(name2);
              continue;
            }
            throw new Error("Unexpected character " + c);
          }
          types.push(1);
          values.push("[EOF]");
          return [types, values];
        };
        XPathParser.SHIFT = "s";
        XPathParser.REDUCE = "r";
        XPathParser.ACCEPT = "a";
        XPathParser.prototype.parse = function(s) {
          if (!s) {
            throw new Error("XPath expression unspecified.");
          }
          if (typeof s !== "string") {
            throw new Error("XPath expression must be a string.");
          }
          var types;
          var values;
          var res = this.tokenize(s);
          if (res == void 0) {
            return void 0;
          }
          types = res[0];
          values = res[1];
          var tokenPos = 0;
          var state = [];
          var tokenType = [];
          var tokenValue = [];
          var s;
          var a;
          var t;
          state.push(0);
          tokenType.push(1);
          tokenValue.push("_S");
          a = types[tokenPos];
          t = values[tokenPos++];
          while (1) {
            s = state[state.length - 1];
            switch (XPathParser.actionTable[s].charAt(a - 1)) {
              case XPathParser.SHIFT:
                tokenType.push(-a);
                tokenValue.push(t);
                state.push(XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32);
                a = types[tokenPos];
                t = values[tokenPos++];
                break;
              case XPathParser.REDUCE:
                var num = XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][1];
                var rhs = [];
                for (var i = 0; i < num; i++) {
                  tokenType.pop();
                  rhs.unshift(tokenValue.pop());
                  state.pop();
                }
                var s_ = state[state.length - 1];
                tokenType.push(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0]);
                if (this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32] == void 0) {
                  tokenValue.push(rhs[0]);
                } else {
                  tokenValue.push(this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32](rhs));
                }
                state.push(XPathParser.gotoTable[s_].charCodeAt(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0] - 2) - 33);
                break;
              case XPathParser.ACCEPT:
                return new XPath(tokenValue.pop());
              default:
                throw new Error("XPath parse error");
            }
          }
        };
        XPath.prototype = new Object();
        XPath.prototype.constructor = XPath;
        XPath.superclass = Object.prototype;
        function XPath(e) {
          this.expression = e;
        }
        XPath.prototype.toString = function() {
          return this.expression.toString();
        };
        function setIfUnset(obj, prop, value) {
          if (!(prop in obj)) {
            obj[prop] = value;
          }
        }
        XPath.prototype.evaluate = function(c) {
          var node = c.expressionContextNode;
          if (!(isNil(node) || isNodeLike(node))) {
            throw new Error("Context node does not appear to be a valid DOM node.");
          }
          c.contextNode = c.expressionContextNode;
          c.contextSize = 1;
          c.contextPosition = 1;
          if (c.isHtml) {
            setIfUnset(c, "caseInsensitive", true);
            setIfUnset(c, "allowAnyNamespaceForNoPrefix", true);
          }
          setIfUnset(c, "caseInsensitive", false);
          return this.expression.evaluate(c);
        };
        XPath.XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
        XPath.XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
        Expression.prototype = new Object();
        Expression.prototype.constructor = Expression;
        Expression.superclass = Object.prototype;
        function Expression() {
        }
        Expression.prototype.init = function() {
        };
        Expression.prototype.toString = function() {
          return "<Expression>";
        };
        Expression.prototype.evaluate = function(c) {
          throw new Error("Could not evaluate expression.");
        };
        UnaryOperation.prototype = new Expression();
        UnaryOperation.prototype.constructor = UnaryOperation;
        UnaryOperation.superclass = Expression.prototype;
        function UnaryOperation(rhs) {
          if (arguments.length > 0) {
            this.init(rhs);
          }
        }
        UnaryOperation.prototype.init = function(rhs) {
          this.rhs = rhs;
        };
        UnaryMinusOperation.prototype = new UnaryOperation();
        UnaryMinusOperation.prototype.constructor = UnaryMinusOperation;
        UnaryMinusOperation.superclass = UnaryOperation.prototype;
        function UnaryMinusOperation(rhs) {
          if (arguments.length > 0) {
            this.init(rhs);
          }
        }
        UnaryMinusOperation.prototype.init = function(rhs) {
          UnaryMinusOperation.superclass.init.call(this, rhs);
        };
        UnaryMinusOperation.prototype.evaluate = function(c) {
          return this.rhs.evaluate(c).number().negate();
        };
        UnaryMinusOperation.prototype.toString = function() {
          return "-" + this.rhs.toString();
        };
        BinaryOperation.prototype = new Expression();
        BinaryOperation.prototype.constructor = BinaryOperation;
        BinaryOperation.superclass = Expression.prototype;
        function BinaryOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        BinaryOperation.prototype.init = function(lhs, rhs) {
          this.lhs = lhs;
          this.rhs = rhs;
        };
        OrOperation.prototype = new BinaryOperation();
        OrOperation.prototype.constructor = OrOperation;
        OrOperation.superclass = BinaryOperation.prototype;
        function OrOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        OrOperation.prototype.init = function(lhs, rhs) {
          OrOperation.superclass.init.call(this, lhs, rhs);
        };
        OrOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " or " + this.rhs.toString() + ")";
        };
        OrOperation.prototype.evaluate = function(c) {
          var b = this.lhs.evaluate(c).bool();
          if (b.booleanValue()) {
            return b;
          }
          return this.rhs.evaluate(c).bool();
        };
        AndOperation.prototype = new BinaryOperation();
        AndOperation.prototype.constructor = AndOperation;
        AndOperation.superclass = BinaryOperation.prototype;
        function AndOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        AndOperation.prototype.init = function(lhs, rhs) {
          AndOperation.superclass.init.call(this, lhs, rhs);
        };
        AndOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " and " + this.rhs.toString() + ")";
        };
        AndOperation.prototype.evaluate = function(c) {
          var b = this.lhs.evaluate(c).bool();
          if (!b.booleanValue()) {
            return b;
          }
          return this.rhs.evaluate(c).bool();
        };
        EqualsOperation.prototype = new BinaryOperation();
        EqualsOperation.prototype.constructor = EqualsOperation;
        EqualsOperation.superclass = BinaryOperation.prototype;
        function EqualsOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        EqualsOperation.prototype.init = function(lhs, rhs) {
          EqualsOperation.superclass.init.call(this, lhs, rhs);
        };
        EqualsOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " = " + this.rhs.toString() + ")";
        };
        EqualsOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).equals(this.rhs.evaluate(c));
        };
        NotEqualOperation.prototype = new BinaryOperation();
        NotEqualOperation.prototype.constructor = NotEqualOperation;
        NotEqualOperation.superclass = BinaryOperation.prototype;
        function NotEqualOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        NotEqualOperation.prototype.init = function(lhs, rhs) {
          NotEqualOperation.superclass.init.call(this, lhs, rhs);
        };
        NotEqualOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " != " + this.rhs.toString() + ")";
        };
        NotEqualOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).notequal(this.rhs.evaluate(c));
        };
        LessThanOperation.prototype = new BinaryOperation();
        LessThanOperation.prototype.constructor = LessThanOperation;
        LessThanOperation.superclass = BinaryOperation.prototype;
        function LessThanOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        LessThanOperation.prototype.init = function(lhs, rhs) {
          LessThanOperation.superclass.init.call(this, lhs, rhs);
        };
        LessThanOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).lessthan(this.rhs.evaluate(c));
        };
        LessThanOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " < " + this.rhs.toString() + ")";
        };
        GreaterThanOperation.prototype = new BinaryOperation();
        GreaterThanOperation.prototype.constructor = GreaterThanOperation;
        GreaterThanOperation.superclass = BinaryOperation.prototype;
        function GreaterThanOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        GreaterThanOperation.prototype.init = function(lhs, rhs) {
          GreaterThanOperation.superclass.init.call(this, lhs, rhs);
        };
        GreaterThanOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).greaterthan(this.rhs.evaluate(c));
        };
        GreaterThanOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " > " + this.rhs.toString() + ")";
        };
        LessThanOrEqualOperation.prototype = new BinaryOperation();
        LessThanOrEqualOperation.prototype.constructor = LessThanOrEqualOperation;
        LessThanOrEqualOperation.superclass = BinaryOperation.prototype;
        function LessThanOrEqualOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        LessThanOrEqualOperation.prototype.init = function(lhs, rhs) {
          LessThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
        };
        LessThanOrEqualOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).lessthanorequal(this.rhs.evaluate(c));
        };
        LessThanOrEqualOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " <= " + this.rhs.toString() + ")";
        };
        GreaterThanOrEqualOperation.prototype = new BinaryOperation();
        GreaterThanOrEqualOperation.prototype.constructor = GreaterThanOrEqualOperation;
        GreaterThanOrEqualOperation.superclass = BinaryOperation.prototype;
        function GreaterThanOrEqualOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        GreaterThanOrEqualOperation.prototype.init = function(lhs, rhs) {
          GreaterThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
        };
        GreaterThanOrEqualOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).greaterthanorequal(this.rhs.evaluate(c));
        };
        GreaterThanOrEqualOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " >= " + this.rhs.toString() + ")";
        };
        PlusOperation.prototype = new BinaryOperation();
        PlusOperation.prototype.constructor = PlusOperation;
        PlusOperation.superclass = BinaryOperation.prototype;
        function PlusOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        PlusOperation.prototype.init = function(lhs, rhs) {
          PlusOperation.superclass.init.call(this, lhs, rhs);
        };
        PlusOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).number().plus(this.rhs.evaluate(c).number());
        };
        PlusOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " + " + this.rhs.toString() + ")";
        };
        MinusOperation.prototype = new BinaryOperation();
        MinusOperation.prototype.constructor = MinusOperation;
        MinusOperation.superclass = BinaryOperation.prototype;
        function MinusOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        MinusOperation.prototype.init = function(lhs, rhs) {
          MinusOperation.superclass.init.call(this, lhs, rhs);
        };
        MinusOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).number().minus(this.rhs.evaluate(c).number());
        };
        MinusOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " - " + this.rhs.toString() + ")";
        };
        MultiplyOperation.prototype = new BinaryOperation();
        MultiplyOperation.prototype.constructor = MultiplyOperation;
        MultiplyOperation.superclass = BinaryOperation.prototype;
        function MultiplyOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        MultiplyOperation.prototype.init = function(lhs, rhs) {
          MultiplyOperation.superclass.init.call(this, lhs, rhs);
        };
        MultiplyOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).number().multiply(this.rhs.evaluate(c).number());
        };
        MultiplyOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " * " + this.rhs.toString() + ")";
        };
        DivOperation.prototype = new BinaryOperation();
        DivOperation.prototype.constructor = DivOperation;
        DivOperation.superclass = BinaryOperation.prototype;
        function DivOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        DivOperation.prototype.init = function(lhs, rhs) {
          DivOperation.superclass.init.call(this, lhs, rhs);
        };
        DivOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).number().div(this.rhs.evaluate(c).number());
        };
        DivOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " div " + this.rhs.toString() + ")";
        };
        ModOperation.prototype = new BinaryOperation();
        ModOperation.prototype.constructor = ModOperation;
        ModOperation.superclass = BinaryOperation.prototype;
        function ModOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        ModOperation.prototype.init = function(lhs, rhs) {
          ModOperation.superclass.init.call(this, lhs, rhs);
        };
        ModOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).number().mod(this.rhs.evaluate(c).number());
        };
        ModOperation.prototype.toString = function() {
          return "(" + this.lhs.toString() + " mod " + this.rhs.toString() + ")";
        };
        BarOperation.prototype = new BinaryOperation();
        BarOperation.prototype.constructor = BarOperation;
        BarOperation.superclass = BinaryOperation.prototype;
        function BarOperation(lhs, rhs) {
          if (arguments.length > 0) {
            this.init(lhs, rhs);
          }
        }
        BarOperation.prototype.init = function(lhs, rhs) {
          BarOperation.superclass.init.call(this, lhs, rhs);
        };
        BarOperation.prototype.evaluate = function(c) {
          return this.lhs.evaluate(c).nodeset().union(this.rhs.evaluate(c).nodeset());
        };
        BarOperation.prototype.toString = function() {
          return map(toString, [this.lhs, this.rhs]).join(" | ");
        };
        PathExpr.prototype = new Expression();
        PathExpr.prototype.constructor = PathExpr;
        PathExpr.superclass = Expression.prototype;
        function PathExpr(filter2, filterPreds, locpath) {
          if (arguments.length > 0) {
            this.init(filter2, filterPreds, locpath);
          }
        }
        PathExpr.prototype.init = function(filter2, filterPreds, locpath) {
          PathExpr.superclass.init.call(this);
          this.filter = filter2;
          this.filterPredicates = filterPreds;
          this.locationPath = locpath;
        };
        function findRoot(node) {
          while (node && node.parentNode) {
            node = node.parentNode;
          }
          return node;
        }
        var applyPredicates = function(predicates, c, nodes, reverse) {
          if (predicates.length === 0) {
            return nodes;
          }
          var ctx = c.extend({});
          return reduce(
            function(inNodes, pred) {
              ctx.contextSize = inNodes.length;
              return filter(
                function(node, i) {
                  ctx.contextNode = node;
                  ctx.contextPosition = i + 1;
                  return PathExpr.predicateMatches(pred, ctx);
                },
                inNodes
              );
            },
            sortNodes(nodes, reverse),
            predicates
          );
        };
        PathExpr.getRoot = function(xpc, nodes) {
          var firstNode = nodes[0];
          if (firstNode && firstNode.nodeType === NodeTypes.DOCUMENT_NODE) {
            return firstNode;
          }
          if (xpc.virtualRoot) {
            return xpc.virtualRoot;
          }
          if (!firstNode) {
            throw new Error("Context node not found when determining document root.");
          }
          var ownerDoc = firstNode.ownerDocument;
          if (ownerDoc) {
            return ownerDoc;
          }
          var n = firstNode;
          while (n.parentNode != null) {
            n = n.parentNode;
          }
          return n;
        };
        var getPrefixForNamespaceNode = function(attrNode) {
          var nm = String(attrNode.name);
          if (nm === "xmlns") {
            return "";
          }
          if (nm.substring(0, 6) === "xmlns:") {
            return nm.substring(6, nm.length);
          }
          return null;
        };
        PathExpr.applyStep = function(step, xpc, node) {
          if (!node) {
            throw new Error("Context node not found when evaluating XPath step: " + step);
          }
          var newNodes = [];
          xpc.contextNode = node;
          switch (step.axis) {
            case Step.ANCESTOR:
              if (xpc.contextNode === xpc.virtualRoot) {
                break;
              }
              var m;
              if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) {
                m = PathExpr.getOwnerElement(xpc.contextNode);
              } else {
                m = xpc.contextNode.parentNode;
              }
              while (m != null) {
                if (step.nodeTest.matches(m, xpc)) {
                  newNodes.push(m);
                }
                if (m === xpc.virtualRoot) {
                  break;
                }
                m = m.parentNode;
              }
              break;
            case Step.ANCESTORORSELF:
              for (var m = xpc.contextNode; m != null; m = m.nodeType == NodeTypes.ATTRIBUTE_NODE ? PathExpr.getOwnerElement(m) : m.parentNode) {
                if (step.nodeTest.matches(m, xpc)) {
                  newNodes.push(m);
                }
                if (m === xpc.virtualRoot) {
                  break;
                }
              }
              break;
            case Step.ATTRIBUTE:
              var nnm = xpc.contextNode.attributes;
              if (nnm != null) {
                for (var k = 0; k < nnm.length; k++) {
                  var m = nnm.item(k);
                  if (step.nodeTest.matches(m, xpc)) {
                    newNodes.push(m);
                  }
                }
              }
              break;
            case Step.CHILD:
              for (var m = xpc.contextNode.firstChild; m != null; m = m.nextSibling) {
                if (step.nodeTest.matches(m, xpc)) {
                  newNodes.push(m);
                }
              }
              break;
            case Step.DESCENDANT:
              var st = [xpc.contextNode.firstChild];
              while (st.length > 0) {
                for (var m = st.pop(); m != null; ) {
                  if (step.nodeTest.matches(m, xpc)) {
                    newNodes.push(m);
                  }
                  if (m.firstChild != null) {
                    st.push(m.nextSibling);
                    m = m.firstChild;
                  } else {
                    m = m.nextSibling;
                  }
                }
              }
              break;
            case Step.DESCENDANTORSELF:
              if (step.nodeTest.matches(xpc.contextNode, xpc)) {
                newNodes.push(xpc.contextNode);
              }
              var st = [xpc.contextNode.firstChild];
              while (st.length > 0) {
                for (var m = st.pop(); m != null; ) {
                  if (step.nodeTest.matches(m, xpc)) {
                    newNodes.push(m);
                  }
                  if (m.firstChild != null) {
                    st.push(m.nextSibling);
                    m = m.firstChild;
                  } else {
                    m = m.nextSibling;
                  }
                }
              }
              break;
            case Step.FOLLOWING:
              if (xpc.contextNode === xpc.virtualRoot) {
                break;
              }
              var st = [];
              if (xpc.contextNode.firstChild != null) {
                st.unshift(xpc.contextNode.firstChild);
              } else {
                st.unshift(xpc.contextNode.nextSibling);
              }
              for (var m = xpc.contextNode.parentNode; m != null && m.nodeType != NodeTypes.DOCUMENT_NODE && m !== xpc.virtualRoot; m = m.parentNode) {
                st.unshift(m.nextSibling);
              }
              do {
                for (var m = st.pop(); m != null; ) {
                  if (step.nodeTest.matches(m, xpc)) {
                    newNodes.push(m);
                  }
                  if (m.firstChild != null) {
                    st.push(m.nextSibling);
                    m = m.firstChild;
                  } else {
                    m = m.nextSibling;
                  }
                }
              } while (st.length > 0);
              break;
            case Step.FOLLOWINGSIBLING:
              if (xpc.contextNode === xpc.virtualRoot) {
                break;
              }
              for (var m = xpc.contextNode.nextSibling; m != null; m = m.nextSibling) {
                if (step.nodeTest.matches(m, xpc)) {
                  newNodes.push(m);
                }
              }
              break;
            case Step.NAMESPACE:
              var nodes = {};
              if (xpc.contextNode.nodeType == NodeTypes.ELEMENT_NODE) {
                nodes["xml"] = new XPathNamespace("xml", null, XPath.XML_NAMESPACE_URI, xpc.contextNode);
                for (var m = xpc.contextNode; m != null && m.nodeType == NodeTypes.ELEMENT_NODE; m = m.parentNode) {
                  for (var k = 0; k < m.attributes.length; k++) {
                    var attr = m.attributes.item(k);
                    var pre = getPrefixForNamespaceNode(attr);
                    if (pre != null && nodes[pre] == void 0) {
                      nodes[pre] = new XPathNamespace(pre, attr, attr.value, xpc.contextNode);
                    }
                  }
                }
                for (var pre in nodes) {
                  var node = nodes[pre];
                  if (step.nodeTest.matches(node, xpc)) {
                    newNodes.push(node);
                  }
                }
              }
              break;
            case Step.PARENT:
              m = null;
              if (xpc.contextNode !== xpc.virtualRoot) {
                if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) {
                  m = PathExpr.getOwnerElement(xpc.contextNode);
                } else {
                  m = xpc.contextNode.parentNode;
                }
              }
              if (m != null && step.nodeTest.matches(m, xpc)) {
                newNodes.push(m);
              }
              break;
            case Step.PRECEDING:
              var st;
              if (xpc.virtualRoot != null) {
                st = [xpc.virtualRoot];
              } else {
                st = [findRoot(xpc.contextNode)];
              }
              outer: while (st.length > 0) {
                for (var m = st.pop(); m != null; ) {
                  if (m == xpc.contextNode) {
                    break outer;
                  }
                  if (step.nodeTest.matches(m, xpc)) {
                    newNodes.unshift(m);
                  }
                  if (m.firstChild != null) {
                    st.push(m.nextSibling);
                    m = m.firstChild;
                  } else {
                    m = m.nextSibling;
                  }
                }
              }
              break;
            case Step.PRECEDINGSIBLING:
              if (xpc.contextNode === xpc.virtualRoot) {
                break;
              }
              for (var m = xpc.contextNode.previousSibling; m != null; m = m.previousSibling) {
                if (step.nodeTest.matches(m, xpc)) {
                  newNodes.push(m);
                }
              }
              break;
            case Step.SELF:
              if (step.nodeTest.matches(xpc.contextNode, xpc)) {
                newNodes.push(xpc.contextNode);
              }
              break;
            default:
          }
          return newNodes;
        };
        function applyStepWithPredicates(step, xpc, node) {
          return applyPredicates(
            step.predicates,
            xpc,
            PathExpr.applyStep(step, xpc, node),
            includes(REVERSE_AXES, step.axis)
          );
        }
        function applyStepToNodes(context, nodes, step) {
          return flatten(
            map(
              applyStepWithPredicates.bind(null, step, context),
              nodes
            )
          );
        }
        PathExpr.applySteps = function(steps, xpc, nodes) {
          return reduce(
            applyStepToNodes.bind(null, xpc),
            nodes,
            steps
          );
        };
        PathExpr.prototype.applyFilter = function(c, xpc) {
          if (!this.filter) {
            return { nodes: [c.contextNode] };
          }
          var ns = this.filter.evaluate(c);
          if (!Utilities.instance_of(ns, XNodeSet)) {
            if (this.filterPredicates != null && this.filterPredicates.length > 0 || this.locationPath != null) {
              throw new Error("Path expression filter must evaluate to a nodeset if predicates or location path are used");
            }
            return { nonNodes: ns };
          }
          return {
            nodes: applyPredicates(
              this.filterPredicates || [],
              xpc,
              ns.toUnsortedArray(),
              false
              // reverse
            )
          };
        };
        PathExpr.applyLocationPath = function(locationPath, xpc, nodes) {
          if (!locationPath) {
            return nodes;
          }
          var startNodes = locationPath.absolute ? [PathExpr.getRoot(xpc, nodes)] : nodes;
          return PathExpr.applySteps(locationPath.steps, xpc, startNodes);
        };
        PathExpr.prototype.evaluate = function(c) {
          var xpc = assign(new XPathContext(), c);
          var filterResult = this.applyFilter(c, xpc);
          if ("nonNodes" in filterResult) {
            return filterResult.nonNodes;
          }
          var ns = new XNodeSet();
          ns.addArray(PathExpr.applyLocationPath(this.locationPath, xpc, filterResult.nodes));
          return ns;
        };
        PathExpr.predicateMatches = function(pred, c) {
          var res = pred.evaluate(c);
          return Utilities.instance_of(res, XNumber) ? c.contextPosition === res.numberValue() : res.booleanValue();
        };
        PathExpr.predicateString = function(predicate) {
          return wrap("[", "]", predicate.toString());
        };
        PathExpr.predicatesString = function(predicates) {
          return join(
            "",
            map(PathExpr.predicateString, predicates)
          );
        };
        PathExpr.prototype.toString = function() {
          if (this.filter != void 0) {
            var filterStr = toString(this.filter);
            if (Utilities.instance_of(this.filter, XString)) {
              return wrap("'", "'", filterStr);
            }
            if (this.filterPredicates != void 0 && this.filterPredicates.length) {
              return wrap("(", ")", filterStr) + PathExpr.predicatesString(this.filterPredicates);
            }
            if (this.locationPath != void 0) {
              return filterStr + (this.locationPath.absolute ? "" : "/") + toString(this.locationPath);
            }
            return filterStr;
          }
          return toString(this.locationPath);
        };
        PathExpr.getOwnerElement = function(n) {
          if (n.ownerElement) {
            return n.ownerElement;
          }
          try {
            if (n.selectSingleNode) {
              return n.selectSingleNode("..");
            }
          } catch (e) {
          }
          var doc = n.nodeType == NodeTypes.DOCUMENT_NODE ? n : n.ownerDocument;
          var elts = doc.getElementsByTagName("*");
          for (var i = 0; i < elts.length; i++) {
            var elt = elts.item(i);
            var nnm = elt.attributes;
            for (var j = 0; j < nnm.length; j++) {
              var an = nnm.item(j);
              if (an === n) {
                return elt;
              }
            }
          }
          return null;
        };
        LocationPath.prototype = new Object();
        LocationPath.prototype.constructor = LocationPath;
        LocationPath.superclass = Object.prototype;
        function LocationPath(abs, steps) {
          if (arguments.length > 0) {
            this.init(abs, steps);
          }
        }
        LocationPath.prototype.init = function(abs, steps) {
          this.absolute = abs;
          this.steps = steps;
        };
        LocationPath.prototype.toString = function() {
          return (this.absolute ? "/" : "") + map(toString, this.steps).join("/");
        };
        Step.prototype = new Object();
        Step.prototype.constructor = Step;
        Step.superclass = Object.prototype;
        function Step(axis, nodetest, preds) {
          if (arguments.length > 0) {
            this.init(axis, nodetest, preds);
          }
        }
        Step.prototype.init = function(axis, nodetest, preds) {
          this.axis = axis;
          this.nodeTest = nodetest;
          this.predicates = preds;
        };
        Step.prototype.toString = function() {
          return Step.STEPNAMES[this.axis] + "::" + this.nodeTest.toString() + PathExpr.predicatesString(this.predicates);
        };
        Step.ANCESTOR = 0;
        Step.ANCESTORORSELF = 1;
        Step.ATTRIBUTE = 2;
        Step.CHILD = 3;
        Step.DESCENDANT = 4;
        Step.DESCENDANTORSELF = 5;
        Step.FOLLOWING = 6;
        Step.FOLLOWINGSIBLING = 7;
        Step.NAMESPACE = 8;
        Step.PARENT = 9;
        Step.PRECEDING = 10;
        Step.PRECEDINGSIBLING = 11;
        Step.SELF = 12;
        Step.STEPNAMES = reduce(function(acc, x) {
          return acc[x[0]] = x[1], acc;
        }, {}, [
          [Step.ANCESTOR, "ancestor"],
          [Step.ANCESTORORSELF, "ancestor-or-self"],
          [Step.ATTRIBUTE, "attribute"],
          [Step.CHILD, "child"],
          [Step.DESCENDANT, "descendant"],
          [Step.DESCENDANTORSELF, "descendant-or-self"],
          [Step.FOLLOWING, "following"],
          [Step.FOLLOWINGSIBLING, "following-sibling"],
          [Step.NAMESPACE, "namespace"],
          [Step.PARENT, "parent"],
          [Step.PRECEDING, "preceding"],
          [Step.PRECEDINGSIBLING, "preceding-sibling"],
          [Step.SELF, "self"]
        ]);
        var REVERSE_AXES = [
          Step.ANCESTOR,
          Step.ANCESTORORSELF,
          Step.PARENT,
          Step.PRECEDING,
          Step.PRECEDINGSIBLING
        ];
        NodeTest.prototype = new Object();
        NodeTest.prototype.constructor = NodeTest;
        NodeTest.superclass = Object.prototype;
        function NodeTest(type, value) {
          if (arguments.length > 0) {
            this.init(type, value);
          }
        }
        NodeTest.prototype.init = function(type, value) {
          this.type = type;
          this.value = value;
        };
        NodeTest.prototype.toString = function() {
          return "<unknown nodetest type>";
        };
        NodeTest.prototype.matches = function(n, xpc) {
          console.warn("unknown node test type");
        };
        NodeTest.NAMETESTANY = 0;
        NodeTest.NAMETESTPREFIXANY = 1;
        NodeTest.NAMETESTQNAME = 2;
        NodeTest.COMMENT = 3;
        NodeTest.TEXT = 4;
        NodeTest.PI = 5;
        NodeTest.NODE = 6;
        NodeTest.isNodeType = function(types) {
          return function(node) {
            return includes(types, node.nodeType);
          };
        };
        NodeTest.makeNodeTestType = function(type, members, ctor) {
          var newType = ctor || function() {
          };
          newType.prototype = new NodeTest(type);
          newType.prototype.constructor = newType;
          assign(newType.prototype, members);
          return newType;
        };
        NodeTest.makeNodeTypeTest = function(type, nodeTypes, stringVal) {
          return new (NodeTest.makeNodeTestType(type, {
            matches: NodeTest.isNodeType(nodeTypes),
            toString: always(stringVal)
          }))();
        };
        NodeTest.hasPrefix = function(node) {
          return node.prefix || (node.nodeName || node.tagName).indexOf(":") !== -1;
        };
        NodeTest.isElementOrAttribute = NodeTest.isNodeType([1, 2]);
        NodeTest.nameSpaceMatches = function(prefix, xpc, n) {
          var nNamespace = n.namespaceURI || "";
          if (!prefix) {
            return !nNamespace || xpc.allowAnyNamespaceForNoPrefix && !NodeTest.hasPrefix(n);
          }
          var ns = xpc.namespaceResolver.getNamespace(prefix, xpc.expressionContextNode);
          if (ns == null) {
            throw new Error("Cannot resolve QName " + prefix);
          }
          return ns === nNamespace;
        };
        NodeTest.localNameMatches = function(localName, xpc, n) {
          var nLocalName = n.localName || n.nodeName;
          return xpc.caseInsensitive ? localName.toLowerCase() === nLocalName.toLowerCase() : localName === nLocalName;
        };
        NodeTest.NameTestPrefixAny = NodeTest.makeNodeTestType(
          NodeTest.NAMETESTPREFIXANY,
          {
            matches: function(n, xpc) {
              return NodeTest.isElementOrAttribute(n) && NodeTest.nameSpaceMatches(this.prefix, xpc, n);
            },
            toString: function() {
              return this.prefix + ":*";
            }
          },
          function NameTestPrefixAny(prefix) {
            this.prefix = prefix;
          }
        );
        NodeTest.NameTestQName = NodeTest.makeNodeTestType(
          NodeTest.NAMETESTQNAME,
          {
            matches: function(n, xpc) {
              return NodeTest.isNodeType(
                [
                  NodeTypes.ELEMENT_NODE,
                  NodeTypes.ATTRIBUTE_NODE,
                  NodeTypes.NAMESPACE_NODE
                ]
              )(n) && NodeTest.nameSpaceMatches(this.prefix, xpc, n) && NodeTest.localNameMatches(this.localName, xpc, n);
            },
            toString: function() {
              return this.name;
            }
          },
          function NameTestQName(name2) {
            var nameParts = name2.split(":");
            this.name = name2;
            this.prefix = nameParts.length > 1 ? nameParts[0] : null;
            this.localName = nameParts[nameParts.length > 1 ? 1 : 0];
          }
        );
        NodeTest.PITest = NodeTest.makeNodeTestType(NodeTest.PI, {
          matches: function(n, xpc) {
            return NodeTest.isNodeType(
              [NodeTypes.PROCESSING_INSTRUCTION_NODE]
            )(n) && (n.target || n.nodeName) === this.name;
          },
          toString: function() {
            return wrap('processing-instruction("', '")', this.name);
          }
        }, function(name2) {
          this.name = name2;
        });
        NodeTest.nameTestAny = NodeTest.makeNodeTypeTest(
          NodeTest.NAMETESTANY,
          [
            NodeTypes.ELEMENT_NODE,
            NodeTypes.ATTRIBUTE_NODE,
            NodeTypes.NAMESPACE_NODE
          ],
          "*"
        );
        NodeTest.textTest = NodeTest.makeNodeTypeTest(
          NodeTest.TEXT,
          [
            NodeTypes.TEXT_NODE,
            NodeTypes.CDATA_SECTION_NODE
          ],
          "text()"
        );
        NodeTest.commentTest = NodeTest.makeNodeTypeTest(
          NodeTest.COMMENT,
          [NodeTypes.COMMENT_NODE],
          "comment()"
        );
        NodeTest.nodeTest = NodeTest.makeNodeTypeTest(
          NodeTest.NODE,
          [
            NodeTypes.ELEMENT_NODE,
            NodeTypes.ATTRIBUTE_NODE,
            NodeTypes.TEXT_NODE,
            NodeTypes.CDATA_SECTION_NODE,
            NodeTypes.PROCESSING_INSTRUCTION_NODE,
            NodeTypes.COMMENT_NODE,
            NodeTypes.DOCUMENT_NODE
          ],
          "node()"
        );
        NodeTest.anyPiTest = NodeTest.makeNodeTypeTest(
          NodeTest.PI,
          [NodeTypes.PROCESSING_INSTRUCTION_NODE],
          "processing-instruction()"
        );
        VariableReference.prototype = new Expression();
        VariableReference.prototype.constructor = VariableReference;
        VariableReference.superclass = Expression.prototype;
        function VariableReference(v) {
          if (arguments.length > 0) {
            this.init(v);
          }
        }
        VariableReference.prototype.init = function(v) {
          this.variable = v;
        };
        VariableReference.prototype.toString = function() {
          return "$" + this.variable;
        };
        VariableReference.prototype.evaluate = function(c) {
          var parts = Utilities.resolveQName(this.variable, c.namespaceResolver, c.contextNode, false);
          if (parts[0] == null) {
            throw new Error("Cannot resolve QName " + fn);
          }
          var result = c.variableResolver.getVariable(parts[1], parts[0]);
          if (!result) {
            throw XPathException.fromMessage("Undeclared variable: " + this.toString());
          }
          return result;
        };
        FunctionCall.prototype = new Expression();
        FunctionCall.prototype.constructor = FunctionCall;
        FunctionCall.superclass = Expression.prototype;
        function FunctionCall(fn2, args) {
          if (arguments.length > 0) {
            this.init(fn2, args);
          }
        }
        FunctionCall.prototype.init = function(fn2, args) {
          this.functionName = fn2;
          this.arguments = args;
        };
        FunctionCall.prototype.toString = function() {
          var s = this.functionName + "(";
          for (var i = 0; i < this.arguments.length; i++) {
            if (i > 0) {
              s += ", ";
            }
            s += this.arguments[i].toString();
          }
          return s + ")";
        };
        FunctionCall.prototype.evaluate = function(c) {
          var f = FunctionResolver.getFunctionFromContext(this.functionName, c);
          if (!f) {
            throw new Error("Unknown function " + this.functionName);
          }
          var a = [c].concat(this.arguments);
          return f.apply(c.functionResolver.thisArg, a);
        };
        var Operators = new Object();
        Operators.equals = function(l, r) {
          return l.equals(r);
        };
        Operators.notequal = function(l, r) {
          return l.notequal(r);
        };
        Operators.lessthan = function(l, r) {
          return l.lessthan(r);
        };
        Operators.greaterthan = function(l, r) {
          return l.greaterthan(r);
        };
        Operators.lessthanorequal = function(l, r) {
          return l.lessthanorequal(r);
        };
        Operators.greaterthanorequal = function(l, r) {
          return l.greaterthanorequal(r);
        };
        XString.prototype = new Expression();
        XString.prototype.constructor = XString;
        XString.superclass = Expression.prototype;
        function XString(s) {
          if (arguments.length > 0) {
            this.init(s);
          }
        }
        XString.prototype.init = function(s) {
          this.str = String(s);
        };
        XString.prototype.toString = function() {
          return this.str;
        };
        XString.prototype.evaluate = function(c) {
          return this;
        };
        XString.prototype.string = function() {
          return this;
        };
        XString.prototype.number = function() {
          return new XNumber(this.str);
        };
        XString.prototype.bool = function() {
          return new XBoolean(this.str);
        };
        XString.prototype.nodeset = function() {
          throw new Error("Cannot convert string to nodeset");
        };
        XString.prototype.stringValue = function() {
          return this.str;
        };
        XString.prototype.numberValue = function() {
          return this.number().numberValue();
        };
        XString.prototype.booleanValue = function() {
          return this.bool().booleanValue();
        };
        XString.prototype.equals = function(r) {
          if (Utilities.instance_of(r, XBoolean)) {
            return this.bool().equals(r);
          }
          if (Utilities.instance_of(r, XNumber)) {
            return this.number().equals(r);
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithString(this, Operators.equals);
          }
          return new XBoolean(this.str == r.str);
        };
        XString.prototype.notequal = function(r) {
          if (Utilities.instance_of(r, XBoolean)) {
            return this.bool().notequal(r);
          }
          if (Utilities.instance_of(r, XNumber)) {
            return this.number().notequal(r);
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithString(this, Operators.notequal);
          }
          return new XBoolean(this.str != r.str);
        };
        XString.prototype.lessthan = function(r) {
          return this.number().lessthan(r);
        };
        XString.prototype.greaterthan = function(r) {
          return this.number().greaterthan(r);
        };
        XString.prototype.lessthanorequal = function(r) {
          return this.number().lessthanorequal(r);
        };
        XString.prototype.greaterthanorequal = function(r) {
          return this.number().greaterthanorequal(r);
        };
        XNumber.prototype = new Expression();
        XNumber.prototype.constructor = XNumber;
        XNumber.superclass = Expression.prototype;
        function XNumber(n) {
          if (arguments.length > 0) {
            this.init(n);
          }
        }
        XNumber.prototype.init = function(n) {
          this.num = typeof n === "string" ? this.parse(n) : Number(n);
        };
        XNumber.prototype.numberFormat = /^\s*-?[0-9]*\.?[0-9]+\s*$/;
        XNumber.prototype.parse = function(s) {
          return this.numberFormat.test(s) ? parseFloat(s) : Number.NaN;
        };
        function padSmallNumber(numberStr) {
          var parts = numberStr.split("e-");
          var base = parts[0].replace(".", "");
          var exponent = Number(parts[1]);
          for (var i = 0; i < exponent - 1; i += 1) {
            base = "0" + base;
          }
          return "0." + base;
        }
        function padLargeNumber(numberStr) {
          var parts = numberStr.split("e");
          var base = parts[0].replace(".", "");
          var exponent = Number(parts[1]);
          var zerosToAppend = exponent + 1 - base.length;
          for (var i = 0; i < zerosToAppend; i += 1) {
            base += "0";
          }
          return base;
        }
        XNumber.prototype.toString = function() {
          var strValue = this.num.toString();
          if (strValue.indexOf("e-") !== -1) {
            return padSmallNumber(strValue);
          }
          if (strValue.indexOf("e") !== -1) {
            return padLargeNumber(strValue);
          }
          return strValue;
        };
        XNumber.prototype.evaluate = function(c) {
          return this;
        };
        XNumber.prototype.string = function() {
          return new XString(this.toString());
        };
        XNumber.prototype.number = function() {
          return this;
        };
        XNumber.prototype.bool = function() {
          return new XBoolean(this.num);
        };
        XNumber.prototype.nodeset = function() {
          throw new Error("Cannot convert number to nodeset");
        };
        XNumber.prototype.stringValue = function() {
          return this.string().stringValue();
        };
        XNumber.prototype.numberValue = function() {
          return this.num;
        };
        XNumber.prototype.booleanValue = function() {
          return this.bool().booleanValue();
        };
        XNumber.prototype.negate = function() {
          return new XNumber(-this.num);
        };
        XNumber.prototype.equals = function(r) {
          if (Utilities.instance_of(r, XBoolean)) {
            return this.bool().equals(r);
          }
          if (Utilities.instance_of(r, XString)) {
            return this.equals(r.number());
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.equals);
          }
          return new XBoolean(this.num == r.num);
        };
        XNumber.prototype.notequal = function(r) {
          if (Utilities.instance_of(r, XBoolean)) {
            return this.bool().notequal(r);
          }
          if (Utilities.instance_of(r, XString)) {
            return this.notequal(r.number());
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.notequal);
          }
          return new XBoolean(this.num != r.num);
        };
        XNumber.prototype.lessthan = function(r) {
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.greaterthan);
          }
          if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
            return this.lessthan(r.number());
          }
          return new XBoolean(this.num < r.num);
        };
        XNumber.prototype.greaterthan = function(r) {
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.lessthan);
          }
          if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
            return this.greaterthan(r.number());
          }
          return new XBoolean(this.num > r.num);
        };
        XNumber.prototype.lessthanorequal = function(r) {
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.greaterthanorequal);
          }
          if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
            return this.lessthanorequal(r.number());
          }
          return new XBoolean(this.num <= r.num);
        };
        XNumber.prototype.greaterthanorequal = function(r) {
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithNumber(this, Operators.lessthanorequal);
          }
          if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
            return this.greaterthanorequal(r.number());
          }
          return new XBoolean(this.num >= r.num);
        };
        XNumber.prototype.plus = function(r) {
          return new XNumber(this.num + r.num);
        };
        XNumber.prototype.minus = function(r) {
          return new XNumber(this.num - r.num);
        };
        XNumber.prototype.multiply = function(r) {
          return new XNumber(this.num * r.num);
        };
        XNumber.prototype.div = function(r) {
          return new XNumber(this.num / r.num);
        };
        XNumber.prototype.mod = function(r) {
          return new XNumber(this.num % r.num);
        };
        XBoolean.prototype = new Expression();
        XBoolean.prototype.constructor = XBoolean;
        XBoolean.superclass = Expression.prototype;
        function XBoolean(b) {
          if (arguments.length > 0) {
            this.init(b);
          }
        }
        XBoolean.prototype.init = function(b) {
          this.b = Boolean(b);
        };
        XBoolean.prototype.toString = function() {
          return this.b.toString();
        };
        XBoolean.prototype.evaluate = function(c) {
          return this;
        };
        XBoolean.prototype.string = function() {
          return new XString(this.b);
        };
        XBoolean.prototype.number = function() {
          return new XNumber(this.b);
        };
        XBoolean.prototype.bool = function() {
          return this;
        };
        XBoolean.prototype.nodeset = function() {
          throw new Error("Cannot convert boolean to nodeset");
        };
        XBoolean.prototype.stringValue = function() {
          return this.string().stringValue();
        };
        XBoolean.prototype.numberValue = function() {
          return this.number().numberValue();
        };
        XBoolean.prototype.booleanValue = function() {
          return this.b;
        };
        XBoolean.prototype.not = function() {
          return new XBoolean(!this.b);
        };
        XBoolean.prototype.equals = function(r) {
          if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
            return this.equals(r.bool());
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithBoolean(this, Operators.equals);
          }
          return new XBoolean(this.b == r.b);
        };
        XBoolean.prototype.notequal = function(r) {
          if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
            return this.notequal(r.bool());
          }
          if (Utilities.instance_of(r, XNodeSet)) {
            return r.compareWithBoolean(this, Operators.notequal);
          }
          return new XBoolean(this.b != r.b);
        };
        XBoolean.prototype.lessthan = function(r) {
          return this.number().lessthan(r);
        };
        XBoolean.prototype.greaterthan = function(r) {
          return this.number().greaterthan(r);
        };
        XBoolean.prototype.lessthanorequal = function(r) {
          return this.number().lessthanorequal(r);
        };
        XBoolean.prototype.greaterthanorequal = function(r) {
          return this.number().greaterthanorequal(r);
        };
        XBoolean.true_ = new XBoolean(true);
        XBoolean.false_ = new XBoolean(false);
        AVLTree.prototype = new Object();
        AVLTree.prototype.constructor = AVLTree;
        AVLTree.superclass = Object.prototype;
        function AVLTree(n) {
          this.init(n);
        }
        AVLTree.prototype.init = function(n) {
          this.left = null;
          this.right = null;
          this.node = n;
          this.depth = 1;
        };
        AVLTree.prototype.balance = function() {
          var ldepth = this.left == null ? 0 : this.left.depth;
          var rdepth = this.right == null ? 0 : this.right.depth;
          if (ldepth > rdepth + 1) {
            var lldepth = this.left.left == null ? 0 : this.left.left.depth;
            var lrdepth = this.left.right == null ? 0 : this.left.right.depth;
            if (lldepth < lrdepth) {
              this.left.rotateRR();
            }
            this.rotateLL();
          } else if (ldepth + 1 < rdepth) {
            var rrdepth = this.right.right == null ? 0 : this.right.right.depth;
            var rldepth = this.right.left == null ? 0 : this.right.left.depth;
            if (rldepth > rrdepth) {
              this.right.rotateLL();
            }
            this.rotateRR();
          }
        };
        AVLTree.prototype.rotateLL = function() {
          var nodeBefore = this.node;
          var rightBefore = this.right;
          this.node = this.left.node;
          this.right = this.left;
          this.left = this.left.left;
          this.right.left = this.right.right;
          this.right.right = rightBefore;
          this.right.node = nodeBefore;
          this.right.updateInNewLocation();
          this.updateInNewLocation();
        };
        AVLTree.prototype.rotateRR = function() {
          var nodeBefore = this.node;
          var leftBefore = this.left;
          this.node = this.right.node;
          this.left = this.right;
          this.right = this.right.right;
          this.left.right = this.left.left;
          this.left.left = leftBefore;
          this.left.node = nodeBefore;
          this.left.updateInNewLocation();
          this.updateInNewLocation();
        };
        AVLTree.prototype.updateInNewLocation = function() {
          this.getDepthFromChildren();
        };
        AVLTree.prototype.getDepthFromChildren = function() {
          this.depth = this.node == null ? 0 : 1;
          if (this.left != null) {
            this.depth = this.left.depth + 1;
          }
          if (this.right != null && this.depth <= this.right.depth) {
            this.depth = this.right.depth + 1;
          }
        };
        function nodeOrder(n1, n2) {
          if (n1 === n2) {
            return 0;
          }
          if (n1.compareDocumentPosition) {
            var cpos = n1.compareDocumentPosition(n2);
            if (cpos & 1) {
              return 1;
            }
            if (cpos & 10) {
              return 1;
            }
            if (cpos & 20) {
              return -1;
            }
            return 0;
          }
          var d1 = 0, d2 = 0;
          for (var m1 = n1; m1 != null; m1 = m1.parentNode || m1.ownerElement) {
            d1++;
          }
          for (var m2 = n2; m2 != null; m2 = m2.parentNode || m2.ownerElement) {
            d2++;
          }
          if (d1 > d2) {
            while (d1 > d2) {
              n1 = n1.parentNode || n1.ownerElement;
              d1--;
            }
            if (n1 === n2) {
              return 1;
            }
          } else if (d2 > d1) {
            while (d2 > d1) {
              n2 = n2.parentNode || n2.ownerElement;
              d2--;
            }
            if (n1 === n2) {
              return -1;
            }
          }
          var n1Par = n1.parentNode || n1.ownerElement, n2Par = n2.parentNode || n2.ownerElement;
          while (n1Par !== n2Par) {
            n1 = n1Par;
            n2 = n2Par;
            n1Par = n1.parentNode || n1.ownerElement;
            n2Par = n2.parentNode || n2.ownerElement;
          }
          var n1isAttr = isAttributeLike(n1);
          var n2isAttr = isAttributeLike(n2);
          if (n1isAttr && !n2isAttr) {
            return -1;
          }
          if (!n1isAttr && n2isAttr) {
            return 1;
          }
          if (n1.isXPathNamespace) {
            if (n1.nodeValue === XPath.XML_NAMESPACE_URI) {
              return -1;
            }
            if (!n2.isXPathNamespace) {
              return -1;
            }
            if (n2.nodeValue === XPath.XML_NAMESPACE_URI) {
              return 1;
            }
          } else if (n2.isXPathNamespace) {
            return 1;
          }
          if (n1Par) {
            var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes;
            var len = cn.length;
            var n1Compare = n1.baseNode || n1;
            var n2Compare = n2.baseNode || n2;
            for (var i = 0; i < len; i += 1) {
              var n = cn[i];
              if (n === n1Compare) {
                return -1;
              }
              if (n === n2Compare) {
                return 1;
              }
            }
          }
          throw new Error("Unexpected: could not determine node order");
        }
        AVLTree.prototype.add = function(n) {
          if (n === this.node) {
            return false;
          }
          var o = nodeOrder(n, this.node);
          var ret = false;
          if (o == -1) {
            if (this.left == null) {
              this.left = new AVLTree(n);
              ret = true;
            } else {
              ret = this.left.add(n);
              if (ret) {
                this.balance();
              }
            }
          } else if (o == 1) {
            if (this.right == null) {
              this.right = new AVLTree(n);
              ret = true;
            } else {
              ret = this.right.add(n);
              if (ret) {
                this.balance();
              }
            }
          }
          if (ret) {
            this.getDepthFromChildren();
          }
          return ret;
        };
        XNodeSet.prototype = new Expression();
        XNodeSet.prototype.constructor = XNodeSet;
        XNodeSet.superclass = Expression.prototype;
        function XNodeSet() {
          this.init();
        }
        XNodeSet.prototype.init = function() {
          this.tree = null;
          this.nodes = [];
          this.size = 0;
        };
        XNodeSet.prototype.toString = function() {
          var p = this.first();
          if (p == null) {
            return "";
          }
          return this.stringForNode(p);
        };
        XNodeSet.prototype.evaluate = function(c) {
          return this;
        };
        XNodeSet.prototype.string = function() {
          return new XString(this.toString());
        };
        XNodeSet.prototype.stringValue = function() {
          return this.toString();
        };
        XNodeSet.prototype.number = function() {
          return new XNumber(this.string());
        };
        XNodeSet.prototype.numberValue = function() {
          return Number(this.string());
        };
        XNodeSet.prototype.bool = function() {
          return new XBoolean(this.booleanValue());
        };
        XNodeSet.prototype.booleanValue = function() {
          return !!this.size;
        };
        XNodeSet.prototype.nodeset = function() {
          return this;
        };
        XNodeSet.prototype.stringForNode = function(n) {
          if (n.nodeType == NodeTypes.DOCUMENT_NODE || n.nodeType == NodeTypes.ELEMENT_NODE || n.nodeType === NodeTypes.DOCUMENT_FRAGMENT_NODE) {
            return this.stringForContainerNode(n);
          }
          if (n.nodeType === NodeTypes.ATTRIBUTE_NODE) {
            return n.value || n.nodeValue;
          }
          if (n.isNamespaceNode) {
            return n.namespace;
          }
          return n.nodeValue;
        };
        XNodeSet.prototype.stringForContainerNode = function(n) {
          var s = "";
          for (var n2 = n.firstChild; n2 != null; n2 = n2.nextSibling) {
            var nt = n2.nodeType;
            if (nt === 1 || nt === 3 || nt === 4 || nt === 9 || nt === 11) {
              s += this.stringForNode(n2);
            }
          }
          return s;
        };
        XNodeSet.prototype.buildTree = function() {
          if (!this.tree && this.nodes.length) {
            this.tree = new AVLTree(this.nodes[0]);
            for (var i = 1; i < this.nodes.length; i += 1) {
              this.tree.add(this.nodes[i]);
            }
          }
          return this.tree;
        };
        XNodeSet.prototype.first = function() {
          var p = this.buildTree();
          if (p == null) {
            return null;
          }
          while (p.left != null) {
            p = p.left;
          }
          return p.node;
        };
        XNodeSet.prototype.add = function(n) {
          for (var i = 0; i < this.nodes.length; i += 1) {
            if (n === this.nodes[i]) {
              return;
            }
          }
          this.tree = null;
          this.nodes.push(n);
          this.size += 1;
        };
        XNodeSet.prototype.addArray = function(ns) {
          var self = this;
          forEach(function(x) {
            self.add(x);
          }, ns);
        };
        XNodeSet.prototype.toArray = function() {
          var a = [];
          this.toArrayRec(this.buildTree(), a);
          return a;
        };
        XNodeSet.prototype.toArrayRec = function(t, a) {
          if (t != null) {
            this.toArrayRec(t.left, a);
            a.push(t.node);
            this.toArrayRec(t.right, a);
          }
        };
        XNodeSet.prototype.toUnsortedArray = function() {
          return this.nodes.slice();
        };
        XNodeSet.prototype.compareWithString = function(r, o) {
          var a = this.toUnsortedArray();
          for (var i = 0; i < a.length; i++) {
            var n = a[i];
            var l = new XString(this.stringForNode(n));
            var res = o(l, r);
            if (res.booleanValue()) {
              return res;
            }
          }
          return new XBoolean(false);
        };
        XNodeSet.prototype.compareWithNumber = function(r, o) {
          var a = this.toUnsortedArray();
          for (var i = 0; i < a.length; i++) {
            var n = a[i];
            var l = new XNumber(this.stringForNode(n));
            var res = o(l, r);
            if (res.booleanValue()) {
              return res;
            }
          }
          return new XBoolean(false);
        };
        XNodeSet.prototype.compareWithBoolean = function(r, o) {
          return o(this.bool(), r);
        };
        XNodeSet.prototype.compareWithNodeSet = function(r, o) {
          var arr = this.toUnsortedArray();
          var oInvert = function(lop, rop) {
            return o(rop, lop);
          };
          for (var i = 0; i < arr.length; i++) {
            var l = new XString(this.stringForNode(arr[i]));
            var res = r.compareWithString(l, oInvert);
            if (res.booleanValue()) {
              return res;
            }
          }
          return new XBoolean(false);
        };
        XNodeSet.compareWith = curry(function(o, r) {
          if (Utilities.instance_of(r, XString)) {
            return this.compareWithString(r, o);
          }
          if (Utilities.instance_of(r, XNumber)) {
            return this.compareWithNumber(r, o);
          }
          if (Utilities.instance_of(r, XBoolean)) {
            return this.compareWithBoolean(r, o);
          }
          return this.compareWithNodeSet(r, o);
        });
        XNodeSet.prototype.equals = XNodeSet.compareWith(Operators.equals);
        XNodeSet.prototype.notequal = XNodeSet.compareWith(Operators.notequal);
        XNodeSet.prototype.lessthan = XNodeSet.compareWith(Operators.lessthan);
        XNodeSet.prototype.greaterthan = XNodeSet.compareWith(Operators.greaterthan);
        XNodeSet.prototype.lessthanorequal = XNodeSet.compareWith(Operators.lessthanorequal);
        XNodeSet.prototype.greaterthanorequal = XNodeSet.compareWith(Operators.greaterthanorequal);
        XNodeSet.prototype.union = function(r) {
          var ns = new XNodeSet();
          ns.addArray(this.toUnsortedArray());
          ns.addArray(r.toUnsortedArray());
          return ns;
        };
        XPathNamespace.prototype = new Object();
        XPathNamespace.prototype.constructor = XPathNamespace;
        XPathNamespace.superclass = Object.prototype;
        function XPathNamespace(pre, node, uri, p) {
          this.isXPathNamespace = true;
          this.baseNode = node;
          this.ownerDocument = p.ownerDocument;
          this.nodeName = pre;
          this.prefix = pre;
          this.localName = pre;
          this.namespaceURI = null;
          this.nodeValue = uri;
          this.ownerElement = p;
          this.nodeType = NodeTypes.NAMESPACE_NODE;
        }
        XPathNamespace.prototype.toString = function() {
          return '{ "' + this.prefix + '", "' + this.namespaceURI + '" }';
        };
        XPathContext.prototype = new Object();
        XPathContext.prototype.constructor = XPathContext;
        XPathContext.superclass = Object.prototype;
        function XPathContext(vr, nr, fr) {
          this.variableResolver = vr != null ? vr : new VariableResolver();
          this.namespaceResolver = nr != null ? nr : new NamespaceResolver();
          this.functionResolver = fr != null ? fr : new FunctionResolver();
        }
        XPathContext.prototype.extend = function(newProps) {
          return assign(new XPathContext(), this, newProps);
        };
        VariableResolver.prototype = new Object();
        VariableResolver.prototype.constructor = VariableResolver;
        VariableResolver.superclass = Object.prototype;
        function VariableResolver() {
        }
        VariableResolver.prototype.getVariable = function(ln, ns) {
          return null;
        };
        FunctionResolver.prototype = new Object();
        FunctionResolver.prototype.constructor = FunctionResolver;
        FunctionResolver.superclass = Object.prototype;
        function FunctionResolver(thisArg) {
          this.thisArg = thisArg != null ? thisArg : Functions;
          this.functions = new Object();
          this.addStandardFunctions();
        }
        FunctionResolver.prototype.addStandardFunctions = function() {
          this.functions["{}last"] = Functions.last;
          this.functions["{}position"] = Functions.position;
          this.functions["{}count"] = Functions.count;
          this.functions["{}id"] = Functions.id;
          this.functions["{}local-name"] = Functions.localName;
          this.functions["{}namespace-uri"] = Functions.namespaceURI;
          this.functions["{}name"] = Functions.name;
          this.functions["{}string"] = Functions.string;
          this.functions["{}concat"] = Functions.concat;
          this.functions["{}starts-with"] = Functions.startsWith;
          this.functions["{}contains"] = Functions.contains;
          this.functions["{}substring-before"] = Functions.substringBefore;
          this.functions["{}substring-after"] = Functions.substringAfter;
          this.functions["{}substring"] = Functions.substring;
          this.functions["{}string-length"] = Functions.stringLength;
          this.functions["{}normalize-space"] = Functions.normalizeSpace;
          this.functions["{}translate"] = Functions.translate;
          this.functions["{}boolean"] = Functions.boolean_;
          this.functions["{}not"] = Functions.not;
          this.functions["{}true"] = Functions.true_;
          this.functions["{}false"] = Functions.false_;
          this.functions["{}lang"] = Functions.lang;
          this.functions["{}number"] = Functions.number;
          this.functions["{}sum"] = Functions.sum;
          this.functions["{}floor"] = Functions.floor;
          this.functions["{}ceiling"] = Functions.ceiling;
          this.functions["{}round"] = Functions.round;
        };
        FunctionResolver.prototype.addFunction = function(ns, ln, f) {
          this.functions["{" + ns + "}" + ln] = f;
        };
        FunctionResolver.getFunctionFromContext = function(qName, context) {
          var parts = Utilities.resolveQName(qName, context.namespaceResolver, context.contextNode, false);
          if (parts[0] === null) {
            throw new Error("Cannot resolve QName " + name);
          }
          return context.functionResolver.getFunction(parts[1], parts[0]);
        };
        FunctionResolver.prototype.getFunction = function(localName, namespace) {
          return this.functions["{" + namespace + "}" + localName];
        };
        NamespaceResolver.prototype = new Object();
        NamespaceResolver.prototype.constructor = NamespaceResolver;
        NamespaceResolver.superclass = Object.prototype;
        function NamespaceResolver() {
        }
        NamespaceResolver.prototype.getNamespace = function(prefix, n) {
          if (prefix == "xml") {
            return XPath.XML_NAMESPACE_URI;
          } else if (prefix == "xmlns") {
            return XPath.XMLNS_NAMESPACE_URI;
          }
          if (n.nodeType == NodeTypes.DOCUMENT_NODE) {
            n = n.documentElement;
          } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) {
            n = PathExpr.getOwnerElement(n);
          } else if (n.nodeType != NodeTypes.ELEMENT_NODE) {
            n = n.parentNode;
          }
          while (n != null && n.nodeType == NodeTypes.ELEMENT_NODE) {
            var nnm = n.attributes;
            for (var i = 0; i < nnm.length; i++) {
              var a = nnm.item(i);
              var aname = a.name || a.nodeName;
              if (aname === "xmlns" && prefix === "" || aname === "xmlns:" + prefix) {
                return String(a.value || a.nodeValue);
              }
            }
            n = n.parentNode;
          }
          return null;
        };
        var Functions = new Object();
        Functions.last = function(c) {
          if (arguments.length != 1) {
            throw new Error("Function last expects ()");
          }
          return new XNumber(c.contextSize);
        };
        Functions.position = function(c) {
          if (arguments.length != 1) {
            throw new Error("Function position expects ()");
          }
          return new XNumber(c.contextPosition);
        };
        Functions.count = function() {
          var c = arguments[0];
          var ns;
          if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) {
            throw new Error("Function count expects (node-set)");
          }
          return new XNumber(ns.size);
        };
        Functions.id = function() {
          var c = arguments[0];
          var id;
          if (arguments.length != 2) {
            throw new Error("Function id expects (object)");
          }
          id = arguments[1].evaluate(c);
          if (Utilities.instance_of(id, XNodeSet)) {
            id = id.toArray().join(" ");
          } else {
            id = id.stringValue();
          }
          var ids = id.split(/[\x0d\x0a\x09\x20]+/);
          var count = 0;
          var ns = new XNodeSet();
          var doc = c.contextNode.nodeType == NodeTypes.DOCUMENT_NODE ? c.contextNode : c.contextNode.ownerDocument;
          for (var i = 0; i < ids.length; i++) {
            var n;
            if (doc.getElementById) {
              n = doc.getElementById(ids[i]);
            } else {
              n = Utilities.getElementById(doc, ids[i]);
            }
            if (n != null) {
              ns.add(n);
              count++;
            }
          }
          return ns;
        };
        Functions.localName = function(c, eNode) {
          var n;
          if (arguments.length == 1) {
            n = c.contextNode;
          } else if (arguments.length == 2) {
            n = eNode.evaluate(c).first();
          } else {
            throw new Error("Function local-name expects (node-set?)");
          }
          if (n == null) {
            return new XString("");
          }
          return new XString(
            n.localName || //  standard elements and attributes
            n.baseName || //  IE
            n.target || //  processing instructions
            n.nodeName || //  DOM1 elements
            ""
            //  fallback
          );
        };
        Functions.namespaceURI = function() {
          var c = arguments[0];
          var n;
          if (arguments.length == 1) {
            n = c.contextNode;
          } else if (arguments.length == 2) {
            n = arguments[1].evaluate(c).first();
          } else {
            throw new Error("Function namespace-uri expects (node-set?)");
          }
          if (n == null) {
            return new XString("");
          }
          return new XString(n.namespaceURI || "");
        };
        Functions.name = function() {
          var c = arguments[0];
          var n;
          if (arguments.length == 1) {
            n = c.contextNode;
          } else if (arguments.length == 2) {
            n = arguments[1].evaluate(c).first();
          } else {
            throw new Error("Function name expects (node-set?)");
          }
          if (n == null) {
            return new XString("");
          }
          if (n.nodeType == NodeTypes.ELEMENT_NODE) {
            return new XString(n.nodeName);
          } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) {
            return new XString(n.name || n.nodeName);
          } else if (n.nodeType === NodeTypes.PROCESSING_INSTRUCTION_NODE) {
            return new XString(n.target || n.nodeName);
          } else if (n.localName == null) {
            return new XString("");
          } else {
            return new XString(n.localName);
          }
        };
        Functions.string = function() {
          var c = arguments[0];
          if (arguments.length == 1) {
            return new XString(XNodeSet.prototype.stringForNode(c.contextNode));
          } else if (arguments.length == 2) {
            return arguments[1].evaluate(c).string();
          }
          throw new Error("Function string expects (object?)");
        };
        Functions.concat = function(c) {
          if (arguments.length < 3) {
            throw new Error("Function concat expects (string, string[, string]*)");
          }
          var s = "";
          for (var i = 1; i < arguments.length; i++) {
            s += arguments[i].evaluate(c).stringValue();
          }
          return new XString(s);
        };
        Functions.startsWith = function() {
          var c = arguments[0];
          if (arguments.length != 3) {
            throw new Error("Function startsWith expects (string, string)");
          }
          var s1 = arguments[1].evaluate(c).stringValue();
          var s2 = arguments[2].evaluate(c).stringValue();
          return new XBoolean(s1.substring(0, s2.length) == s2);
        };
        Functions.contains = function() {
          var c = arguments[0];
          if (arguments.length != 3) {
            throw new Error("Function contains expects (string, string)");
          }
          var s1 = arguments[1].evaluate(c).stringValue();
          var s2 = arguments[2].evaluate(c).stringValue();
          return new XBoolean(s1.indexOf(s2) !== -1);
        };
        Functions.substringBefore = function() {
          var c = arguments[0];
          if (arguments.length != 3) {
            throw new Error("Function substring-before expects (string, string)");
          }
          var s1 = arguments[1].evaluate(c).stringValue();
          var s2 = arguments[2].evaluate(c).stringValue();
          return new XString(s1.substring(0, s1.indexOf(s2)));
        };
        Functions.substringAfter = function() {
          var c = arguments[0];
          if (arguments.length != 3) {
            throw new Error("Function substring-after expects (string, string)");
          }
          var s1 = arguments[1].evaluate(c).stringValue();
          var s2 = arguments[2].evaluate(c).stringValue();
          if (s2.length == 0) {
            return new XString(s1);
          }
          var i = s1.indexOf(s2);
          if (i == -1) {
            return new XString("");
          }
          return new XString(s1.substring(i + s2.length));
        };
        Functions.substring = function() {
          var c = arguments[0];
          if (!(arguments.length == 3 || arguments.length == 4)) {
            throw new Error("Function substring expects (string, number, number?)");
          }
          var s = arguments[1].evaluate(c).stringValue();
          var n1 = Math.round(arguments[2].evaluate(c).numberValue()) - 1;
          var n2 = arguments.length == 4 ? n1 + Math.round(arguments[3].evaluate(c).numberValue()) : void 0;
          return new XString(s.substring(n1, n2));
        };
        Functions.stringLength = function() {
          var c = arguments[0];
          var s;
          if (arguments.length == 1) {
            s = XNodeSet.prototype.stringForNode(c.contextNode);
          } else if (arguments.length == 2) {
            s = arguments[1].evaluate(c).stringValue();
          } else {
            throw new Error("Function string-length expects (string?)");
          }
          return new XNumber(s.length);
        };
        Functions.normalizeSpace = function() {
          var c = arguments[0];
          var s;
          if (arguments.length == 1) {
            s = XNodeSet.prototype.stringForNode(c.contextNode);
          } else if (arguments.length == 2) {
            s = arguments[1].evaluate(c).stringValue();
          } else {
            throw new Error("Function normalize-space expects (string?)");
          }
          var i = 0;
          var j = s.length - 1;
          while (Utilities.isSpace(s.charCodeAt(j))) {
            j--;
          }
          var t = "";
          while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
            i++;
          }
          while (i <= j) {
            if (Utilities.isSpace(s.charCodeAt(i))) {
              t += " ";
              while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
                i++;
              }
            } else {
              t += s.charAt(i);
              i++;
            }
          }
          return new XString(t);
        };
        Functions.translate = function(c, eValue, eFrom, eTo) {
          if (arguments.length != 4) {
            throw new Error("Function translate expects (string, string, string)");
          }
          var value = eValue.evaluate(c).stringValue();
          var from = eFrom.evaluate(c).stringValue();
          var to = eTo.evaluate(c).stringValue();
          var cMap = reduce(function(acc, ch, i) {
            if (!(ch in acc)) {
              acc[ch] = i > to.length ? "" : to[i];
            }
            return acc;
          }, {}, from);
          var t = join(
            "",
            map(function(ch) {
              return ch in cMap ? cMap[ch] : ch;
            }, value)
          );
          return new XString(t);
        };
        Functions.boolean_ = function() {
          var c = arguments[0];
          if (arguments.length != 2) {
            throw new Error("Function boolean expects (object)");
          }
          return arguments[1].evaluate(c).bool();
        };
        Functions.not = function(c, eValue) {
          if (arguments.length != 2) {
            throw new Error("Function not expects (object)");
          }
          return eValue.evaluate(c).bool().not();
        };
        Functions.true_ = function() {
          if (arguments.length != 1) {
            throw new Error("Function true expects ()");
          }
          return XBoolean.true_;
        };
        Functions.false_ = function() {
          if (arguments.length != 1) {
            throw new Error("Function false expects ()");
          }
          return XBoolean.false_;
        };
        Functions.lang = function() {
          var c = arguments[0];
          if (arguments.length != 2) {
            throw new Error("Function lang expects (string)");
          }
          var lang;
          for (var n = c.contextNode; n != null && n.nodeType != NodeTypes.DOCUMENT_NODE; n = n.parentNode) {
            var a = n.getAttributeNS(XPath.XML_NAMESPACE_URI, "lang");
            if (a != null) {
              lang = String(a);
              break;
            }
          }
          if (lang == null) {
            return XBoolean.false_;
          }
          var s = arguments[1].evaluate(c).stringValue();
          return new XBoolean(lang.substring(0, s.length) == s && (lang.length == s.length || lang.charAt(s.length) == "-"));
        };
        Functions.number = function() {
          var c = arguments[0];
          if (!(arguments.length == 1 || arguments.length == 2)) {
            throw new Error("Function number expects (object?)");
          }
          if (arguments.length == 1) {
            return new XNumber(XNodeSet.prototype.stringForNode(c.contextNode));
          }
          return arguments[1].evaluate(c).number();
        };
        Functions.sum = function() {
          var c = arguments[0];
          var ns;
          if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) {
            throw new Error("Function sum expects (node-set)");
          }
          ns = ns.toUnsortedArray();
          var n = 0;
          for (var i = 0; i < ns.length; i++) {
            n += new XNumber(XNodeSet.prototype.stringForNode(ns[i])).numberValue();
          }
          return new XNumber(n);
        };
        Functions.floor = function() {
          var c = arguments[0];
          if (arguments.length != 2) {
            throw new Error("Function floor expects (number)");
          }
          return new XNumber(Math.floor(arguments[1].evaluate(c).numberValue()));
        };
        Functions.ceiling = function() {
          var c = arguments[0];
          if (arguments.length != 2) {
            throw new Error("Function ceiling expects (number)");
          }
          return new XNumber(Math.ceil(arguments[1].evaluate(c).numberValue()));
        };
        Functions.round = function() {
          var c = arguments[0];
          if (arguments.length != 2) {
            throw new Error("Function round expects (number)");
          }
          return new XNumber(Math.round(arguments[1].evaluate(c).numberValue()));
        };
        var Utilities = new Object();
        var isAttributeLike = function(val) {
          return val && (val.nodeType === NodeTypes.ATTRIBUTE_NODE || val.ownerElement || val.isXPathNamespace);
        };
        Utilities.splitQName = function(qn) {
          var i = qn.indexOf(":");
          if (i == -1) {
            return [null, qn];
          }
          return [qn.substring(0, i), qn.substring(i + 1)];
        };
        Utilities.resolveQName = function(qn, nr, n, useDefault) {
          var parts = Utilities.splitQName(qn);
          if (parts[0] != null) {
            parts[0] = nr.getNamespace(parts[0], n);
          } else {
            if (useDefault) {
              parts[0] = nr.getNamespace("", n);
              if (parts[0] == null) {
                parts[0] = "";
              }
            } else {
              parts[0] = "";
            }
          }
          return parts;
        };
        Utilities.isSpace = function(c) {
          return c == 9 || c == 13 || c == 10 || c == 32;
        };
        Utilities.isLetter = function(c) {
          return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 255 || c >= 256 && c <= 305 || c >= 308 && c <= 318 || c >= 321 && c <= 328 || c >= 330 && c <= 382 || c >= 384 && c <= 451 || c >= 461 && c <= 496 || c >= 500 && c <= 501 || c >= 506 && c <= 535 || c >= 592 && c <= 680 || c >= 699 && c <= 705 || c == 902 || c >= 904 && c <= 906 || c == 908 || c >= 910 && c <= 929 || c >= 931 && c <= 974 || c >= 976 && c <= 982 || c == 986 || c == 988 || c == 990 || c == 992 || c >= 994 && c <= 1011 || c >= 1025 && c <= 1036 || c >= 1038 && c <= 1103 || c >= 1105 && c <= 1116 || c >= 1118 && c <= 1153 || c >= 1168 && c <= 1220 || c >= 1223 && c <= 1224 || c >= 1227 && c <= 1228 || c >= 1232 && c <= 1259 || c >= 1262 && c <= 1269 || c >= 1272 && c <= 1273 || c >= 1329 && c <= 1366 || c == 1369 || c >= 1377 && c <= 1414 || c >= 1488 && c <= 1514 || c >= 1520 && c <= 1522 || c >= 1569 && c <= 1594 || c >= 1601 && c <= 1610 || c >= 1649 && c <= 1719 || c >= 1722 && c <= 1726 || c >= 1728 && c <= 1742 || c >= 1744 && c <= 1747 || c == 1749 || c >= 1765 && c <= 1766 || c >= 2309 && c <= 2361 || c == 2365 || c >= 2392 && c <= 2401 || c >= 2437 && c <= 2444 || c >= 2447 && c <= 2448 || c >= 2451 && c <= 2472 || c >= 2474 && c <= 2480 || c == 2482 || c >= 2486 && c <= 2489 || c >= 2524 && c <= 2525 || c >= 2527 && c <= 2529 || c >= 2544 && c <= 2545 || c >= 2565 && c <= 2570 || c >= 2575 && c <= 2576 || c >= 2579 && c <= 2600 || c >= 2602 && c <= 2608 || c >= 2610 && c <= 2611 || c >= 2613 && c <= 2614 || c >= 2616 && c <= 2617 || c >= 2649 && c <= 2652 || c == 2654 || c >= 2674 && c <= 2676 || c >= 2693 && c <= 2699 || c == 2701 || c >= 2703 && c <= 2705 || c >= 2707 && c <= 2728 || c >= 2730 && c <= 2736 || c >= 2738 && c <= 2739 || c >= 2741 && c <= 2745 || c == 2749 || c == 2784 || c >= 2821 && c <= 2828 || c >= 2831 && c <= 2832 || c >= 2835 && c <= 2856 || c >= 2858 && c <= 2864 || c >= 2866 && c <= 2867 || c >= 2870 && c <= 2873 || c == 2877 || c >= 2908 && c <= 2909 || c >= 2911 && c <= 2913 || c >= 2949 && c <= 2954 || c >= 2958 && c <= 2960 || c >= 2962 && c <= 2965 || c >= 2969 && c <= 2970 || c == 2972 || c >= 2974 && c <= 2975 || c >= 2979 && c <= 2980 || c >= 2984 && c <= 2986 || c >= 2990 && c <= 2997 || c >= 2999 && c <= 3001 || c >= 3077 && c <= 3084 || c >= 3086 && c <= 3088 || c >= 3090 && c <= 3112 || c >= 3114 && c <= 3123 || c >= 3125 && c <= 3129 || c >= 3168 && c <= 3169 || c >= 3205 && c <= 3212 || c >= 3214 && c <= 3216 || c >= 3218 && c <= 3240 || c >= 3242 && c <= 3251 || c >= 3253 && c <= 3257 || c == 3294 || c >= 3296 && c <= 3297 || c >= 3333 && c <= 3340 || c >= 3342 && c <= 3344 || c >= 3346 && c <= 3368 || c >= 3370 && c <= 3385 || c >= 3424 && c <= 3425 || c >= 3585 && c <= 3630 || c == 3632 || c >= 3634 && c <= 3635 || c >= 3648 && c <= 3653 || c >= 3713 && c <= 3714 || c == 3716 || c >= 3719 && c <= 3720 || c == 3722 || c == 3725 || c >= 3732 && c <= 3735 || c >= 3737 && c <= 3743 || c >= 3745 && c <= 3747 || c == 3749 || c == 3751 || c >= 3754 && c <= 3755 || c >= 3757 && c <= 3758 || c == 3760 || c >= 3762 && c <= 3763 || c == 3773 || c >= 3776 && c <= 3780 || c >= 3904 && c <= 3911 || c >= 3913 && c <= 3945 || c >= 4256 && c <= 4293 || c >= 4304 && c <= 4342 || c == 4352 || c >= 4354 && c <= 4355 || c >= 4357 && c <= 4359 || c == 4361 || c >= 4363 && c <= 4364 || c >= 4366 && c <= 4370 || c == 4412 || c == 4414 || c == 4416 || c == 4428 || c == 4430 || c == 4432 || c >= 4436 && c <= 4437 || c == 4441 || c >= 4447 && c <= 4449 || c == 4451 || c == 4453 || c == 4455 || c == 4457 || c >= 4461 && c <= 4462 || c >= 4466 && c <= 4467 || c == 4469 || c == 4510 || c == 4520 || c == 4523 || c >= 4526 && c <= 4527 || c >= 4535 && c <= 4536 || c == 4538 || c >= 4540 && c <= 4546 || c == 4587 || c == 4592 || c == 4601 || c >= 7680 && c <= 7835 || c >= 7840 && c <= 7929 || c >= 7936 && c <= 7957 || c >= 7960 && c <= 7965 || c >= 7968 && c <= 8005 || c >= 8008 && c <= 8013 || c >= 8016 && c <= 8023 || c == 8025 || c == 8027 || c == 8029 || c >= 8031 && c <= 8061 || c >= 8064 && c <= 8116 || c >= 8118 && c <= 8124 || c == 8126 || c >= 8130 && c <= 8132 || c >= 8134 && c <= 8140 || c >= 8144 && c <= 8147 || c >= 8150 && c <= 8155 || c >= 8160 && c <= 8172 || c >= 8178 && c <= 8180 || c >= 8182 && c <= 8188 || c == 8486 || c >= 8490 && c <= 8491 || c == 8494 || c >= 8576 && c <= 8578 || c >= 12353 && c <= 12436 || c >= 12449 && c <= 12538 || c >= 12549 && c <= 12588 || c >= 44032 && c <= 55203 || c >= 19968 && c <= 40869 || c == 12295 || c >= 12321 && c <= 12329;
        };
        Utilities.isNCNameChar = function(c) {
          return c >= 48 && c <= 57 || c >= 1632 && c <= 1641 || c >= 1776 && c <= 1785 || c >= 2406 && c <= 2415 || c >= 2534 && c <= 2543 || c >= 2662 && c <= 2671 || c >= 2790 && c <= 2799 || c >= 2918 && c <= 2927 || c >= 3047 && c <= 3055 || c >= 3174 && c <= 3183 || c >= 3302 && c <= 3311 || c >= 3430 && c <= 3439 || c >= 3664 && c <= 3673 || c >= 3792 && c <= 3801 || c >= 3872 && c <= 3881 || c == 46 || c == 45 || c == 95 || Utilities.isLetter(c) || c >= 768 && c <= 837 || c >= 864 && c <= 865 || c >= 1155 && c <= 1158 || c >= 1425 && c <= 1441 || c >= 1443 && c <= 1465 || c >= 1467 && c <= 1469 || c == 1471 || c >= 1473 && c <= 1474 || c == 1476 || c >= 1611 && c <= 1618 || c == 1648 || c >= 1750 && c <= 1756 || c >= 1757 && c <= 1759 || c >= 1760 && c <= 1764 || c >= 1767 && c <= 1768 || c >= 1770 && c <= 1773 || c >= 2305 && c <= 2307 || c == 2364 || c >= 2366 && c <= 2380 || c == 2381 || c >= 2385 && c <= 2388 || c >= 2402 && c <= 2403 || c >= 2433 && c <= 2435 || c == 2492 || c == 2494 || c == 2495 || c >= 2496 && c <= 2500 || c >= 2503 && c <= 2504 || c >= 2507 && c <= 2509 || c == 2519 || c >= 2530 && c <= 2531 || c == 2562 || c == 2620 || c == 2622 || c == 2623 || c >= 2624 && c <= 2626 || c >= 2631 && c <= 2632 || c >= 2635 && c <= 2637 || c >= 2672 && c <= 2673 || c >= 2689 && c <= 2691 || c == 2748 || c >= 2750 && c <= 2757 || c >= 2759 && c <= 2761 || c >= 2763 && c <= 2765 || c >= 2817 && c <= 2819 || c == 2876 || c >= 2878 && c <= 2883 || c >= 2887 && c <= 2888 || c >= 2891 && c <= 2893 || c >= 2902 && c <= 2903 || c >= 2946 && c <= 2947 || c >= 3006 && c <= 3010 || c >= 3014 && c <= 3016 || c >= 3018 && c <= 3021 || c == 3031 || c >= 3073 && c <= 3075 || c >= 3134 && c <= 3140 || c >= 3142 && c <= 3144 || c >= 3146 && c <= 3149 || c >= 3157 && c <= 3158 || c >= 3202 && c <= 3203 || c >= 3262 && c <= 3268 || c >= 3270 && c <= 3272 || c >= 3274 && c <= 3277 || c >= 3285 && c <= 3286 || c >= 3330 && c <= 3331 || c >= 3390 && c <= 3395 || c >= 3398 && c <= 3400 || c >= 3402 && c <= 3405 || c == 3415 || c == 3633 || c >= 3636 && c <= 3642 || c >= 3655 && c <= 3662 || c == 3761 || c >= 3764 && c <= 3769 || c >= 3771 && c <= 3772 || c >= 3784 && c <= 3789 || c >= 3864 && c <= 3865 || c == 3893 || c == 3895 || c == 3897 || c == 3902 || c == 3903 || c >= 3953 && c <= 3972 || c >= 3974 && c <= 3979 || c >= 3984 && c <= 3989 || c == 3991 || c >= 3993 && c <= 4013 || c >= 4017 && c <= 4023 || c == 4025 || c >= 8400 && c <= 8412 || c == 8417 || c >= 12330 && c <= 12335 || c == 12441 || c == 12442 || c == 183 || c == 720 || c == 721 || c == 903 || c == 1600 || c == 3654 || c == 3782 || c == 12293 || c >= 12337 && c <= 12341 || c >= 12445 && c <= 12446 || c >= 12540 && c <= 12542;
        };
        Utilities.coalesceText = function(n) {
          for (var m = n.firstChild; m != null; m = m.nextSibling) {
            if (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.CDATA_SECTION_NODE) {
              var s = m.nodeValue;
              var first = m;
              m = m.nextSibling;
              while (m != null && (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.CDATA_SECTION_NODE)) {
                s += m.nodeValue;
                var del = m;
                m = m.nextSibling;
                del.parentNode.removeChild(del);
              }
              if (first.nodeType == NodeTypes.CDATA_SECTION_NODE) {
                var p = first.parentNode;
                if (first.nextSibling == null) {
                  p.removeChild(first);
                  p.appendChild(p.ownerDocument.createTextNode(s));
                } else {
                  var next = first.nextSibling;
                  p.removeChild(first);
                  p.insertBefore(p.ownerDocument.createTextNode(s), next);
                }
              } else {
                first.nodeValue = s;
              }
              if (m == null) {
                break;
              }
            } else if (m.nodeType == NodeTypes.ELEMENT_NODE) {
              Utilities.coalesceText(m);
            }
          }
        };
        Utilities.instance_of = function(o, c) {
          while (o != null) {
            if (o.constructor === c) {
              return true;
            }
            if (o === Object) {
              return false;
            }
            o = o.constructor.superclass;
          }
          return false;
        };
        Utilities.getElementById = function(n, id) {
          if (n.nodeType == NodeTypes.ELEMENT_NODE) {
            if (n.getAttribute("id") == id || n.getAttributeNS(null, "id") == id) {
              return n;
            }
          }
          for (var m = n.firstChild; m != null; m = m.nextSibling) {
            var res = Utilities.getElementById(m, id);
            if (res != null) {
              return res;
            }
          }
          return null;
        };
        var XPathException = (function() {
          function getMessage(code, exception) {
            var msg = exception ? ": " + exception.toString() : "";
            switch (code) {
              case XPathException2.INVALID_EXPRESSION_ERR:
                return "Invalid expression" + msg;
              case XPathException2.TYPE_ERR:
                return "Type error" + msg;
            }
            return null;
          }
          function XPathException2(code, error, message) {
            var err = Error.call(this, getMessage(code, error) || message);
            err.code = code;
            err.exception = error;
            return err;
          }
          XPathException2.prototype = Object.create(Error.prototype);
          XPathException2.prototype.constructor = XPathException2;
          XPathException2.superclass = Error;
          XPathException2.prototype.toString = function() {
            return this.message;
          };
          XPathException2.fromMessage = function(message, error) {
            return new XPathException2(null, error, message);
          };
          XPathException2.INVALID_EXPRESSION_ERR = 51;
          XPathException2.TYPE_ERR = 52;
          return XPathException2;
        })();
        XPathExpression.prototype = {};
        XPathExpression.prototype.constructor = XPathExpression;
        XPathExpression.superclass = Object.prototype;
        function XPathExpression(e, r, p) {
          this.xpath = p.parse(e);
          this.context = new XPathContext();
          this.context.namespaceResolver = new XPathNSResolverWrapper(r);
        }
        XPathExpression.getOwnerDocument = function(n) {
          return n.nodeType === NodeTypes.DOCUMENT_NODE ? n : n.ownerDocument;
        };
        XPathExpression.detectHtmlDom = function(n) {
          if (!n) {
            return false;
          }
          var doc = XPathExpression.getOwnerDocument(n);
          try {
            return doc.implementation.hasFeature("HTML", "2.0");
          } catch (e) {
            return true;
          }
        };
        XPathExpression.prototype.evaluate = function(n, t, res) {
          this.context.expressionContextNode = n;
          this.context.caseInsensitive = XPathExpression.detectHtmlDom(n);
          var result = this.xpath.evaluate(this.context);
          return new XPathResult2(result, t);
        };
        XPathNSResolverWrapper.prototype = {};
        XPathNSResolverWrapper.prototype.constructor = XPathNSResolverWrapper;
        XPathNSResolverWrapper.superclass = Object.prototype;
        function XPathNSResolverWrapper(r) {
          this.xpathNSResolver = r;
        }
        XPathNSResolverWrapper.prototype.getNamespace = function(prefix, n) {
          if (this.xpathNSResolver == null) {
            return null;
          }
          return this.xpathNSResolver.lookupNamespaceURI(prefix);
        };
        NodeXPathNSResolver.prototype = {};
        NodeXPathNSResolver.prototype.constructor = NodeXPathNSResolver;
        NodeXPathNSResolver.superclass = Object.prototype;
        function NodeXPathNSResolver(n) {
          this.node = n;
          this.namespaceResolver = new NamespaceResolver();
        }
        NodeXPathNSResolver.prototype.lookupNamespaceURI = function(prefix) {
          return this.namespaceResolver.getNamespace(prefix, this.node);
        };
        XPathResult2.prototype = {};
        XPathResult2.prototype.constructor = XPathResult2;
        XPathResult2.superclass = Object.prototype;
        function XPathResult2(v, t) {
          if (t == XPathResult2.ANY_TYPE) {
            if (v.constructor === XString) {
              t = XPathResult2.STRING_TYPE;
            } else if (v.constructor === XNumber) {
              t = XPathResult2.NUMBER_TYPE;
            } else if (v.constructor === XBoolean) {
              t = XPathResult2.BOOLEAN_TYPE;
            } else if (v.constructor === XNodeSet) {
              t = XPathResult2.UNORDERED_NODE_ITERATOR_TYPE;
            }
          }
          this.resultType = t;
          switch (t) {
            case XPathResult2.NUMBER_TYPE:
              this.numberValue = v.numberValue();
              return;
            case XPathResult2.STRING_TYPE:
              this.stringValue = v.stringValue();
              return;
            case XPathResult2.BOOLEAN_TYPE:
              this.booleanValue = v.booleanValue();
              return;
            case XPathResult2.ANY_UNORDERED_NODE_TYPE:
            case XPathResult2.FIRST_ORDERED_NODE_TYPE:
              if (v.constructor === XNodeSet) {
                this.singleNodeValue = v.first();
                return;
              }
              break;
            case XPathResult2.UNORDERED_NODE_ITERATOR_TYPE:
            case XPathResult2.ORDERED_NODE_ITERATOR_TYPE:
              if (v.constructor === XNodeSet) {
                this.invalidIteratorState = false;
                this.nodes = v.toArray();
                this.iteratorIndex = 0;
                return;
              }
              break;
            case XPathResult2.UNORDERED_NODE_SNAPSHOT_TYPE:
            case XPathResult2.ORDERED_NODE_SNAPSHOT_TYPE:
              if (v.constructor === XNodeSet) {
                this.nodes = v.toArray();
                this.snapshotLength = this.nodes.length;
                return;
              }
              break;
          }
          throw new XPathException(XPathException.TYPE_ERR);
        }
        ;
        XPathResult2.prototype.iterateNext = function() {
          if (this.resultType != XPathResult2.UNORDERED_NODE_ITERATOR_TYPE && this.resultType != XPathResult2.ORDERED_NODE_ITERATOR_TYPE) {
            throw new XPathException(XPathException.TYPE_ERR);
          }
          return this.nodes[this.iteratorIndex++];
        };
        XPathResult2.prototype.snapshotItem = function(i) {
          if (this.resultType != XPathResult2.UNORDERED_NODE_SNAPSHOT_TYPE && this.resultType != XPathResult2.ORDERED_NODE_SNAPSHOT_TYPE) {
            throw new XPathException(XPathException.TYPE_ERR);
          }
          return this.nodes[i];
        };
        XPathResult2.ANY_TYPE = 0;
        XPathResult2.NUMBER_TYPE = 1;
        XPathResult2.STRING_TYPE = 2;
        XPathResult2.BOOLEAN_TYPE = 3;
        XPathResult2.UNORDERED_NODE_ITERATOR_TYPE = 4;
        XPathResult2.ORDERED_NODE_ITERATOR_TYPE = 5;
        XPathResult2.UNORDERED_NODE_SNAPSHOT_TYPE = 6;
        XPathResult2.ORDERED_NODE_SNAPSHOT_TYPE = 7;
        XPathResult2.ANY_UNORDERED_NODE_TYPE = 8;
        XPathResult2.FIRST_ORDERED_NODE_TYPE = 9;
        function installDOM3XPathSupport(doc, p) {
          doc.createExpression = function(e, r) {
            try {
              return new XPathExpression(e, r, p);
            } catch (e2) {
              throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, e2);
            }
          };
          doc.createNSResolver = function(n) {
            return new NodeXPathNSResolver(n);
          };
          doc.evaluate = function(e, cn, r, t, res) {
            if (t < 0 || t > 9) {
              throw { code: 0, toString: function() {
                return "Request type not supported";
              } };
            }
            return doc.createExpression(e, r, p).evaluate(cn, t, res);
          };
        }
        ;
        try {
          var shouldInstall = true;
          try {
            if (document.implementation && document.implementation.hasFeature && document.implementation.hasFeature("XPath", null)) {
              shouldInstall = false;
            }
          } catch (e) {
          }
          if (shouldInstall) {
            installDOM3XPathSupport(document, new XPathParser());
          }
        } catch (e) {
        }
        installDOM3XPathSupport(exports3, new XPathParser());
        (function() {
          var parser = new XPathParser();
          var defaultNSResolver = new NamespaceResolver();
          var defaultFunctionResolver = new FunctionResolver();
          var defaultVariableResolver = new VariableResolver();
          function makeNSResolverFromFunction(func) {
            return {
              getNamespace: function(prefix, node) {
                var ns = func(prefix, node);
                return ns || defaultNSResolver.getNamespace(prefix, node);
              }
            };
          }
          function makeNSResolverFromObject(obj) {
            return makeNSResolverFromFunction(obj.getNamespace.bind(obj));
          }
          function makeNSResolverFromMap(map2) {
            return makeNSResolverFromFunction(function(prefix) {
              return map2[prefix];
            });
          }
          function makeNSResolver(resolver) {
            if (resolver && typeof resolver.getNamespace === "function") {
              return makeNSResolverFromObject(resolver);
            }
            if (typeof resolver === "function") {
              return makeNSResolverFromFunction(resolver);
            }
            if (typeof resolver === "object") {
              return makeNSResolverFromMap(resolver);
            }
            return defaultNSResolver;
          }
          function convertValue(value) {
            if (value === null || typeof value === "undefined" || value instanceof XString || value instanceof XBoolean || value instanceof XNumber || value instanceof XNodeSet) {
              return value;
            }
            switch (typeof value) {
              case "string":
                return new XString(value);
              case "boolean":
                return new XBoolean(value);
              case "number":
                return new XNumber(value);
            }
            var ns = new XNodeSet();
            ns.addArray([].concat(value));
            return ns;
          }
          function makeEvaluator(func) {
            return function(context) {
              var args = Array.prototype.slice.call(arguments, 1).map(function(arg) {
                return arg.evaluate(context);
              });
              var result = func.apply(this, [].concat(context, args));
              return convertValue(result);
            };
          }
          function makeFunctionResolverFromFunction(func) {
            return {
              getFunction: function(name2, namespace) {
                var found = func(name2, namespace);
                if (found) {
                  return makeEvaluator(found);
                }
                return defaultFunctionResolver.getFunction(name2, namespace);
              }
            };
          }
          function makeFunctionResolverFromObject(obj) {
            return makeFunctionResolverFromFunction(obj.getFunction.bind(obj));
          }
          function makeFunctionResolverFromMap(map2) {
            return makeFunctionResolverFromFunction(function(name2) {
              return map2[name2];
            });
          }
          function makeFunctionResolver(resolver) {
            if (resolver && typeof resolver.getFunction === "function") {
              return makeFunctionResolverFromObject(resolver);
            }
            if (typeof resolver === "function") {
              return makeFunctionResolverFromFunction(resolver);
            }
            if (typeof resolver === "object") {
              return makeFunctionResolverFromMap(resolver);
            }
            return defaultFunctionResolver;
          }
          function makeVariableResolverFromFunction(func) {
            return {
              getVariable: function(name2, namespace) {
                var value = func(name2, namespace);
                return convertValue(value);
              }
            };
          }
          function makeVariableResolver(resolver) {
            if (resolver) {
              if (typeof resolver.getVariable === "function") {
                return makeVariableResolverFromFunction(resolver.getVariable.bind(resolver));
              }
              if (typeof resolver === "function") {
                return makeVariableResolverFromFunction(resolver);
              }
              if (typeof resolver === "object") {
                return makeVariableResolverFromFunction(function(name2) {
                  return resolver[name2];
                });
              }
            }
            return defaultVariableResolver;
          }
          function copyIfPresent(prop, dest, source) {
            if (prop in source) {
              dest[prop] = source[prop];
            }
          }
          function makeContext(options) {
            var context = new XPathContext();
            if (options) {
              context.namespaceResolver = makeNSResolver(options.namespaces);
              context.functionResolver = makeFunctionResolver(options.functions);
              context.variableResolver = makeVariableResolver(options.variables);
              context.expressionContextNode = options.node;
              copyIfPresent("allowAnyNamespaceForNoPrefix", context, options);
              copyIfPresent("isHtml", context, options);
            } else {
              context.namespaceResolver = defaultNSResolver;
            }
            return context;
          }
          function evaluate(parsedExpression, options) {
            var context = makeContext(options);
            return parsedExpression.evaluate(context);
          }
          var evaluatorPrototype = {
            evaluate: function(options) {
              return evaluate(this.expression, options);
            },
            evaluateNumber: function(options) {
              return this.evaluate(options).numberValue();
            },
            evaluateString: function(options) {
              return this.evaluate(options).stringValue();
            },
            evaluateBoolean: function(options) {
              return this.evaluate(options).booleanValue();
            },
            evaluateNodeSet: function(options) {
              return this.evaluate(options).nodeset();
            },
            select: function(options) {
              return this.evaluateNodeSet(options).toArray();
            },
            select1: function(options) {
              return this.select(options)[0];
            }
          };
          function parse(xpath2) {
            var parsed = parser.parse(xpath2);
            return Object.create(evaluatorPrototype, {
              expression: {
                value: parsed
              }
            });
          }
          exports3.parse = parse;
        })();
        assign(
          exports3,
          {
            XPath,
            XPathParser,
            XPathResult: XPathResult2,
            Step,
            PathExpr,
            NodeTest,
            LocationPath,
            OrOperation,
            AndOperation,
            BarOperation,
            EqualsOperation,
            NotEqualOperation,
            LessThanOperation,
            GreaterThanOperation,
            LessThanOrEqualOperation,
            GreaterThanOrEqualOperation,
            PlusOperation,
            MinusOperation,
            MultiplyOperation,
            DivOperation,
            ModOperation,
            UnaryMinusOperation,
            FunctionCall,
            VariableReference,
            XPathContext,
            XNodeSet,
            XBoolean,
            XString,
            XNumber,
            NamespaceResolver,
            FunctionResolver,
            VariableResolver,
            Utilities
          }
        );
        exports3.select = function(e, doc, single) {
          return exports3.selectWithResolver(e, doc, null, single);
        };
        exports3.useNamespaces = function(mappings) {
          var resolver = {
            mappings: mappings || {},
            lookupNamespaceURI: function(prefix) {
              return this.mappings[prefix];
            }
          };
          return function(e, doc, single) {
            return exports3.selectWithResolver(e, doc, resolver, single);
          };
        };
        exports3.selectWithResolver = function(e, doc, resolver, single) {
          var expression = new XPathExpression(e, resolver, new XPathParser());
          var type = XPathResult2.ANY_TYPE;
          var result = expression.evaluate(doc, type, null);
          if (result.resultType == XPathResult2.STRING_TYPE) {
            result = result.stringValue;
          } else if (result.resultType == XPathResult2.NUMBER_TYPE) {
            result = result.numberValue;
          } else if (result.resultType == XPathResult2.BOOLEAN_TYPE) {
            result = result.booleanValue;
          } else {
            result = result.nodes;
            if (single) {
              result = result[0];
            }
          }
          return result;
        };
        exports3.select1 = function(e, doc) {
          return exports3.select(e, doc, true);
        };
        var isArrayOfNodes = function(value) {
          return Array.isArray(value) && value.every(isNodeLike);
        };
        var isNodeOfType = function(type) {
          return function(value) {
            return isNodeLike(value) && value.nodeType === type;
          };
        };
        assign(
          exports3,
          {
            isNodeLike,
            isArrayOfNodes,
            isElement: isNodeOfType(NodeTypes.ELEMENT_NODE),
            isAttribute: isNodeOfType(NodeTypes.ATTRIBUTE_NODE),
            isTextNode: isNodeOfType(NodeTypes.TEXT_NODE),
            isCDATASection: isNodeOfType(NodeTypes.CDATA_SECTION_NODE),
            isProcessingInstruction: isNodeOfType(NodeTypes.PROCESSING_INSTRUCTION_NODE),
            isComment: isNodeOfType(NodeTypes.COMMENT_NODE),
            isDocumentNode: isNodeOfType(NodeTypes.DOCUMENT_NODE),
            isDocumentTypeNode: isNodeOfType(NodeTypes.DOCUMENT_TYPE_NODE),
            isDocumentFragment: isNodeOfType(NodeTypes.DOCUMENT_FRAGMENT_NODE)
          }
        );
      })(xpath);
    }
  });

  // modules/std/data/xml.js
  var require_xml = __commonJS({
    "modules/std/data/xml.js"(exports2, module2) {
      "use strict";
      var nextId = 1;
      var nodeIds = /* @__PURE__ */ new WeakMap();
      var wrappers = /* @__PURE__ */ new WeakMap();
      function withSafeObjectPrototype(fn2) {
        const hidden = [];
        for (const name2 of ["get", "set"]) {
          const desc = Object.prototype.hasOwnProperty.call(Object.prototype, name2) ? Object.getOwnPropertyDescriptor(Object.prototype, name2) : null;
          if (desc && desc.configurable) {
            hidden.push([name2, desc]);
            delete Object.prototype[name2];
          }
        }
        try {
          return fn2();
        } finally {
          for (const [name2, desc] of hidden) {
            Object.defineProperty(Object.prototype, name2, desc);
          }
        }
      }
      function domClasses() {
        if (typeof DOMParser !== "undefined" && typeof XMLSerializer !== "undefined") {
          return { DOMParser, XMLSerializer };
        }
        return withSafeObjectPrototype(() => require_lib());
      }
      function xpathEngine() {
        if (typeof document !== "undefined" && document.evaluate) {
          return null;
        }
        return withSafeObjectPrototype(() => require_xpath());
      }
      function isPath(value) {
        return value && value.constructor && value.constructor.name === "Path" && typeof value.slurp_utf8 === "function" && typeof value.spew_utf8 === "function";
      }
      function nodeKey(node) {
        if (!nodeIds.has(node)) {
          nodeIds.set(node, nextId++);
        }
        return String(nodeIds.get(node));
      }
      function wrap(node) {
        if (!node) {
          return null;
        }
        if (wrappers.has(node)) {
          return wrappers.get(node);
        }
        let wrapped;
        if (node.nodeType === 9) {
          wrapped = new XMLDocument(node);
        } else if (node.nodeType === 1) {
          wrapped = new XMLElement(node);
        } else if (node.nodeType === 2) {
          wrapped = new DOMAttr(node);
        } else if (node.nodeType === 3 || node.nodeType === 4) {
          wrapped = new DOMText(node);
        } else if (node.nodeType === 8) {
          wrapped = new DOMComment(node);
        } else {
          wrapped = new XMLNode(node);
        }
        wrappers.set(node, wrapped);
        return wrapped;
      }
      function unwrap(value) {
        return value instanceof XMLNode ? value._node : null;
      }
      function nodeArray(list) {
        return Array.from(list || []).map(wrap).filter(Boolean);
      }
      function elementChildren(node) {
        return Array.from(node.childNodes || []).filter((child) => child.nodeType === 1);
      }
      function descendants(node, includeSelf = false) {
        const out = [];
        const visit = (current) => {
          out.push(current);
          for (const child of Array.from(current.childNodes || [])) {
            visit(child);
          }
        };
        if (includeSelf) {
          visit(node);
        } else {
          for (const child of Array.from(node.childNodes || [])) {
            visit(child);
          }
        }
        return out;
      }
      function simpleSelectorAll(node, selector) {
        const text = String(selector || "").trim();
        if (text === "") {
          return [];
        }
        if (typeof node.querySelectorAll === "function") {
          try {
            return nodeArray(node.querySelectorAll(text));
          } catch (_err) {
          }
        }
        if (text.startsWith(".")) {
          const klass = text.slice(1);
          return descendants(node, false).filter((child) => child.nodeType === 1).filter((child) => {
            const className = child.getAttribute("class");
            return className && className.split(/\s+/u).includes(klass);
          }).map(wrap);
        }
        if (typeof node.getElementsByTagName === "function") {
          return nodeArray(node.getElementsByTagName(text));
        }
        return descendants(node, false).filter((child) => child.nodeType === 1 && child.nodeName === text).map(wrap);
      }
      function evaluateBrowserXPath(node, expr, type) {
        if (typeof XPathResult === "undefined") {
          return null;
        }
        const doc = node.nodeType === 9 ? node : node.ownerDocument;
        if (!doc || typeof doc.evaluate !== "function") {
          return null;
        }
        return doc.evaluate(expr, node, null, type, null);
      }
      function findNodes(node, expr) {
        const text = String(expr || "").trim();
        if (text === "") {
          return [];
        }
        const snapshotType = typeof XPathResult !== "undefined" ? XPathResult.ORDERED_NODE_SNAPSHOT_TYPE : 0;
        const browserResult = evaluateBrowserXPath(node, text, snapshotType);
        if (browserResult) {
          const out = [];
          for (let i = 0; i < browserResult.snapshotLength; i++) {
            out.push(wrap(browserResult.snapshotItem(i)));
          }
          return out;
        }
        const xpath = xpathEngine();
        const result = xpath.select(text, node);
        return Array.isArray(result) ? nodeArray(result) : [];
      }
      function findValue(node, expr) {
        const text = String(expr || "").trim();
        if (text === "") {
          return "";
        }
        const anyType = typeof XPathResult !== "undefined" ? XPathResult.ANY_TYPE : 0;
        const browserResult = evaluateBrowserXPath(node, text, anyType);
        if (browserResult) {
          switch (browserResult.resultType) {
            case XPathResult.NUMBER_TYPE:
              return String(browserResult.numberValue);
            case XPathResult.STRING_TYPE:
              return browserResult.stringValue;
            case XPathResult.BOOLEAN_TYPE:
              return browserResult.booleanValue ? "true" : "false";
            default: {
              const found = browserResult.iterateNext();
              return found ? nodeStringValue(found) : "";
            }
          }
        }
        const xpath = xpathEngine();
        const result = xpath.select1(text, node);
        if (result == null) {
          return "";
        }
        if (typeof result === "number" || typeof result === "boolean") {
          return String(result);
        }
        if (typeof result === "string") {
          return result;
        }
        return nodeStringValue(result);
      }
      function nodeStringValue(node) {
        if (node.nodeType === 2) {
          return node.value || node.nodeValue || "";
        }
        return node.textContent || node.nodeValue || "";
      }
      function serialize(node) {
        const { XMLSerializer: XMLSerializer2 } = domClasses();
        return new XMLSerializer2().serializeToString(node);
      }
      function parseXml(text) {
        const { DOMParser: DOMParser2 } = domClasses();
        const parser = new DOMParser2();
        const doc = parser.parseFromString(String(text ?? ""), "application/xml");
        const parserError = doc.getElementsByTagName ? doc.getElementsByTagName("parsererror")[0] : null;
        if (parserError) {
          throw new Error(
            `Exception: XML.parse failed: ${nodeStringValue(parserError)}`
          );
        }
        return wrap(doc);
      }
      var XMLNode = class {
        constructor(node) {
          this._node = node;
        }
        nodeType() {
          return String(this._node.nodeType);
        }
        nodeName() {
          return this._node.nodeName || "";
        }
        nodeValue() {
          return this._node.nodeValue;
        }
        setNodeValue(value) {
          this._node.nodeValue = String(value ?? "");
          return this;
        }
        data() {
          return this._node.data ?? this.nodeValue();
        }
        setData(value) {
          this._node.data = String(value ?? "");
          return this;
        }
        nodeKind() {
          switch (this._node.nodeType) {
            case 1:
              return "element";
            case 2:
              return "attr";
            case 3:
            case 4:
              return "text";
            case 8:
              return "comment";
            case 9:
              return "document";
            default:
              return "node";
          }
        }
        localName() {
          return this._node.localName || null;
        }
        namespaceURI() {
          return this._node.namespaceURI || null;
        }
        parentNode() {
          return wrap(this._node.parentNode || this._node.ownerElement || null);
        }
        ownerDocument() {
          return wrap(this._node.nodeType === 9 ? this._node : this._node.ownerDocument);
        }
        childNodes() {
          return nodeArray(this._node.childNodes);
        }
        children() {
          return elementChildren(this._node).map(wrap);
        }
        hasChildNodes() {
          return this._node.hasChildNodes && this._node.hasChildNodes() ? 1 : 0;
        }
        firstChild() {
          return wrap(this._node.firstChild);
        }
        lastChild() {
          return wrap(this._node.lastChild);
        }
        nextSibling() {
          return wrap(this._node.nextSibling);
        }
        previousSibling() {
          return wrap(this._node.previousSibling);
        }
        textContent() {
          return this._node.textContent || "";
        }
        setTextContent(value) {
          this._node.textContent = String(value ?? "");
          return this;
        }
        appendChild(node) {
          return wrap(this._node.appendChild(unwrap(node)));
        }
        prependChild(node) {
          const raw = unwrap(node);
          if (this._node.firstChild) {
            this._node.insertBefore(raw, this._node.firstChild);
          } else {
            this._node.appendChild(raw);
          }
          return node;
        }
        insertBefore(newNode, refNode) {
          this._node.insertBefore(unwrap(newNode), unwrap(refNode));
          return newNode;
        }
        replaceChild(newNode, oldNode) {
          return wrap(this._node.replaceChild(unwrap(newNode), unwrap(oldNode)));
        }
        removeChild(childNode) {
          return wrap(this._node.removeChild(unwrap(childNode)));
        }
        remove() {
          if (this._node.parentNode) {
            this._node.parentNode.removeChild(this._node);
          }
          return this;
        }
        cloneNode(deep = false) {
          return wrap(this._node.cloneNode(Boolean(deep)));
        }
        normalize() {
          this._node.normalize();
          return this;
        }
        isSameNode(other) {
          return unwrap(other) === this._node ? 1 : 0;
        }
        isEqualNode(other) {
          const raw = unwrap(other);
          if (this._node.isEqualNode) {
            return this._node.isEqualNode(raw) ? 1 : 0;
          }
          return raw && serialize(this._node) === serialize(raw) ? 1 : 0;
        }
        contains(other) {
          let cur = unwrap(other);
          while (cur) {
            if (cur === this._node) {
              return 1;
            }
            cur = cur.parentNode || cur.ownerElement || null;
          }
          return 0;
        }
        visitEach(fn2) {
          for (const node of descendants(this._node, true)) {
            fn2(wrap(node));
          }
          return this;
        }
        findFirst(fn2) {
          for (const node of descendants(this._node, false)) {
            const wrapped = wrap(node);
            if (fn2(wrapped)) {
              return wrapped;
            }
          }
          return null;
        }
        findnodes(xpath) {
          return findNodes(this._node, xpath);
        }
        findvalue(xpath) {
          return findValue(this._node, xpath);
        }
        querySelectorAll(selector) {
          return simpleSelectorAll(this._node, selector);
        }
        querySelector(selector) {
          return this.querySelectorAll(selector)[0] || null;
        }
        getElementsByTagName(name2) {
          return this._node.getElementsByTagName ? nodeArray(this._node.getElementsByTagName(String(name2 || ""))) : [];
        }
        toXML(_pretty = false) {
          return serialize(this._node);
        }
        to_String() {
          return this.toXML(false);
        }
        uniqueKey() {
          return nodeKey(this._node);
        }
        unique_id() {
          return this.uniqueKey();
        }
      };
      var XMLElement = class extends XMLNode {
        tagName() {
          return this.nodeName();
        }
        id() {
          return this.getAttribute("id");
        }
        setId(value) {
          return this.setAttribute("id", value);
        }
        getAttribute(name2) {
          const value = this._node.getAttribute(String(name2 || ""));
          return value == null ? null : value;
        }
        setAttribute(name2, value) {
          this._node.setAttribute(String(name2 || ""), String(value ?? ""));
          return this;
        }
        hasAttribute(name2) {
          return this._node.hasAttribute(String(name2 || "")) ? 1 : 0;
        }
        removeAttribute(name2) {
          this._node.removeAttribute(String(name2 || ""));
          return this;
        }
        attributeNames() {
          return Array.from(this._node.attributes || []).map((attr) => attr.name);
        }
        attributes() {
          return nodeArray(this._node.attributes);
        }
      };
      var DOMAttr = class extends XMLNode {
      };
      var DOMText = class extends XMLNode {
      };
      var DOMComment = class extends XMLNode {
      };
      var XMLDocument = class extends XMLNode {
        documentElement() {
          return wrap(this._node.documentElement);
        }
        createElement(name2) {
          return wrap(this._node.createElement(String(name2 || "")));
        }
        createTextNode(text) {
          return wrap(this._node.createTextNode(String(text ?? "")));
        }
        createComment(text) {
          return wrap(this._node.createComment(String(text ?? "")));
        }
        createCDATASection(text) {
          return wrap(this._node.createCDATASection(String(text ?? "")));
        }
        getElementById(id) {
          if (typeof this._node.getElementById === "function") {
            return wrap(this._node.getElementById(String(id || "")));
          }
          return this.findFirst(
            (node) => node instanceof XMLElement && node.getAttribute("id") === String(id || "")
          );
        }
      };
      var XML = {
        parse(text) {
          return parseXml(text);
        },
        load(pathValue) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: XML.load expects Path as first argument");
          }
          return parseXml(pathValue.slurp_utf8());
        },
        dump(pathValue, value, pretty = false) {
          if (!isPath(pathValue)) {
            throw new Error("TypeException: XML.dump expects Path as first argument");
          }
          const xml = value && typeof value.toXML === "function" ? value.toXML(pretty) : String(value ?? "");
          pathValue.spew_utf8(xml);
          return pathValue;
        }
      };
      module2.exports = {
        XML,
        XMLDocument,
        XMLNode,
        DOMNode: XMLNode,
        DOMElement: XMLElement,
        DOMAttr,
        DOMText,
        DOMComment,
        DOMDocument: XMLDocument
      };
    }
  });

  // modules/std/digest/md5.js
  var require_md5 = __commonJS({
    "modules/std/digest/md5.js"(exports2, module2) {
      "use strict";
      var {
        bytesToBase64,
        bytesToHex,
        digestBytes: digestBytes2,
        toBinary
      } = require_hash();
      function md5(value) {
        return toBinary(digestBytes2("md5", value, "md5"));
      }
      function md5_hex(value) {
        return bytesToHex(digestBytes2("md5", value, "md5_hex"));
      }
      function md5_b64(value) {
        return bytesToBase64(digestBytes2("md5", value, "md5_b64"));
      }
      module2.exports = {
        md5,
        md5_hex,
        md5_b64
      };
    }
  });

  // modules/std/digest/sha.js
  var require_sha = __commonJS({
    "modules/std/digest/sha.js"(exports2, module2) {
      "use strict";
      var {
        bytesToBase64,
        bytesToHex,
        digestBytes: digestBytes2,
        hmacBytes: hmacBytes2,
        toBinary
      } = require_hash();
      function digestFn(algorithm, fnName) {
        return (value) => {
          return toBinary(digestBytes2(algorithm, value, fnName));
        };
      }
      function digestHexFn(algorithm, fnName) {
        return (value) => {
          return bytesToHex(digestBytes2(algorithm, value, fnName));
        };
      }
      function digestB64Fn(algorithm, fnName) {
        return (value) => {
          return bytesToBase64(digestBytes2(algorithm, value, fnName));
        };
      }
      function hmacFn(algorithm, fnName) {
        return (value, key) => {
          return toBinary(hmacBytes2(algorithm, value, key, fnName));
        };
      }
      function hmacHexFn(algorithm, fnName) {
        return (value, key) => {
          return bytesToHex(hmacBytes2(algorithm, value, key, fnName));
        };
      }
      function hmacB64Fn(algorithm, fnName) {
        return (value, key) => {
          return bytesToBase64(hmacBytes2(algorithm, value, key, fnName));
        };
      }
      module2.exports = {
        sha1: digestFn("sha1", "sha1"),
        sha224: digestFn("sha224", "sha224"),
        sha256: digestFn("sha256", "sha256"),
        sha384: digestFn("sha384", "sha384"),
        sha512: digestFn("sha512", "sha512"),
        sha1_hex: digestHexFn("sha1", "sha1_hex"),
        sha224_hex: digestHexFn("sha224", "sha224_hex"),
        sha256_hex: digestHexFn("sha256", "sha256_hex"),
        sha384_hex: digestHexFn("sha384", "sha384_hex"),
        sha512_hex: digestHexFn("sha512", "sha512_hex"),
        sha1_b64: digestB64Fn("sha1", "sha1_b64"),
        sha256_b64: digestB64Fn("sha256", "sha256_b64"),
        sha512_b64: digestB64Fn("sha512", "sha512_b64"),
        hmac_sha1: hmacFn("sha1", "hmac_sha1"),
        hmac_sha224: hmacFn("sha224", "hmac_sha224"),
        hmac_sha256: hmacFn("sha256", "hmac_sha256"),
        hmac_sha384: hmacFn("sha384", "hmac_sha384"),
        hmac_sha512: hmacFn("sha512", "hmac_sha512"),
        hmac_sha1_hex: hmacHexFn("sha1", "hmac_sha1_hex"),
        hmac_sha224_hex: hmacHexFn("sha224", "hmac_sha224_hex"),
        hmac_sha256_hex: hmacHexFn("sha256", "hmac_sha256_hex"),
        hmac_sha384_hex: hmacHexFn("sha384", "hmac_sha384_hex"),
        hmac_sha512_hex: hmacHexFn("sha512", "hmac_sha512_hex"),
        hmac_sha256_b64: hmacB64Fn("sha256", "hmac_sha256_b64")
      };
    }
  });

  // modules/std/net/http.js
  var require_http = __commonJS({
    "modules/std/net/http.js"(exports2, module2) {
      "use strict";
      var nodeSpawnSync;
      var nodeSpawnLoaded = false;
      var nodeFs;
      var nodeHttps;
      var nodeOs;
      var nodePath;
      var hostName2 = null;
      var { Task, traceBlockingOperation } = require_task();
      function _nodeSpawnSync() {
        if (nodeSpawnLoaded) {
          return nodeSpawnSync;
        }
        nodeSpawnLoaded = true;
        if (typeof __require !== "function") {
          nodeSpawnSync = null;
          return nodeSpawnSync;
        }
        try {
          nodeSpawnSync = __require("node:child_process").spawnSync;
        } catch (_err) {
          nodeSpawnSync = null;
        }
        return nodeSpawnSync;
      }
      function _nodeModule(name2) {
        if (typeof __require !== "function") {
          return null;
        }
        try {
          return __require(name2);
        } catch (_err) {
          return null;
        }
      }
      function _nodeFs() {
        nodeFs = nodeFs || _nodeModule("node:fs");
        return nodeFs;
      }
      function _nodeHttps() {
        nodeHttps = nodeHttps || _nodeModule("node:https");
        return nodeHttps;
      }
      function _nodeOs() {
        nodeOs = nodeOs || _nodeModule("node:os");
        return nodeOs;
      }
      function _nodePath() {
        nodePath = nodePath || _nodeModule("node:path");
        return nodePath;
      }
      function _toDict(value) {
        if (value == null) {
          return {};
        }
        if (value && Array.isArray(value.list)) {
          const out = {};
          for (const pair of value.list) {
            if (Array.isArray(pair) && pair.length >= 2) {
              out[String(pair[0])] = pair[1];
            }
          }
          return out;
        }
        if (typeof value !== "object" || Array.isArray(value)) {
          return {};
        }
        return { ...value };
      }
      function _decorateDict(value) {
        if (value == null || typeof value !== "object" || Array.isArray(value)) {
          return value;
        }
        if (!Object.prototype.hasOwnProperty.call(value, "get")) {
          Object.defineProperty(value, "get", {
            value(key, fallback = null) {
              return Object.prototype.hasOwnProperty.call(this, String(key)) ? this[String(key)] : fallback;
            },
            enumerable: false,
            configurable: true,
            writable: true
          });
        }
        return value;
      }
      function _syncUnsupportedResponse(spec) {
        return new Response({
          status: 599,
          reason: "Synchronous HTTP is unsupported on JS/Browser",
          url: _urlWithQuery(spec.url, spec.query),
          content: "",
          headers: {},
          success: false
        });
      }
      function _urlWithQuery(url, query) {
        const queryMap = _toDict(query);
        const keys = Object.keys(queryMap);
        if (keys.length === 0) {
          return String(url);
        }
        const usp = new URLSearchParams();
        for (const key of keys.sort()) {
          usp.set(key, queryMap[key] == null ? "" : String(queryMap[key]));
        }
        const base = String(url);
        return `${base}${base.includes("?") ? "&" : "?"}${usp.toString()}`;
      }
      function _maxRedirect(spec, uaConfig) {
        const value = spec.max_redirect ?? uaConfig.max_redirect ?? 10;
        const number = Number(value);
        return Number.isFinite(number) && number >= 0 ? Math.floor(number) : 10;
      }
      function _writeDownload(spec, content) {
        if (spec.download_to === void 0) {
          return;
        }
        const fs = _nodeFs();
        if (!fs) {
          throw new Error("Exception: download_to filesystem support is unavailable");
        }
        fs.writeFileSync(String(spec.download_to), content, "utf8");
      }
      var CookieJar = class {
        constructor() {
          this._cookies = /* @__PURE__ */ new Map();
        }
        add(url, setCookie) {
          this._cookies.set(String(url ?? ""), String(setCookie ?? ""));
          return this;
        }
        cookie_header(url) {
          return this._cookies.get(String(url ?? "")) ?? null;
        }
        clear() {
          this._cookies.clear();
          return this;
        }
      };
      var Response = class {
        constructor(payload) {
          this._payload = payload;
        }
        status() {
          return this._payload.status;
        }
        reason() {
          return this._payload.reason;
        }
        url() {
          return this._payload.url;
        }
        content() {
          return this._payload.content;
        }
        headers() {
          return { ...this._payload.headers };
        }
        header(name2) {
          return this._payload.headers[String(name2).toLowerCase()] ?? null;
        }
        success() {
          return this._payload.success ? 1 : 0;
        }
        json() {
          return JSON.parse(this._payload.content || "");
        }
        expect_success() {
          if (this.success()) {
            return this;
          }
          throw new Error(`HTTP request failed with status ${this.status()}`);
        }
        to_Dict() {
          return _decorateDict({
            status: this.status(),
            reason: this.reason(),
            url: this.url(),
            content: this.content(),
            headers: _decorateDict(this.headers()),
            success: this.success()
          });
        }
      };
      var Request = class {
        constructor(method, url) {
          this._spec = {
            method: String(method || "GET").toUpperCase(),
            url: String(url || ""),
            headers: {}
          };
        }
        method(value) {
          this._spec.method = String(value).toUpperCase();
          return this;
        }
        url(value) {
          this._spec.url = String(value);
          return this;
        }
        header(name2, value) {
          this._spec.headers[String(name2).toLowerCase()] = String(value);
          return this;
        }
        headers(value) {
          for (const [key, item] of Object.entries(_toDict(value))) {
            this.header(key, item);
          }
          return this;
        }
        query(value) {
          this._spec.query = _toDict(value);
          return this;
        }
        body(value) {
          this._spec.body = value == null ? "" : String(value);
          return this;
        }
        json(value) {
          this._spec.json = value;
          this._spec.headers["content-type"] = this._spec.headers["content-type"] || "application/json";
          return this;
        }
        auth_bearer(token) {
          return this.header("authorization", `Bearer ${token}`);
        }
        timeout(value) {
          this._spec.timeout = Number(value);
          return this;
        }
        retries(value) {
          this._spec.retries = Number(value);
          return this;
        }
        max_redirect(value) {
          this._spec.max_redirect = Number(value);
          return this;
        }
        download_to(value) {
          this._spec.download_to = String(value);
          return this;
        }
        upload_from(value) {
          this._spec.upload_from = String(value);
          return this;
        }
        tls_identity(value) {
          this._spec.tls_identity = value ?? null;
          return this;
        }
        multipart(value) {
          this._spec.multipart = _toDict(value);
          return this;
        }
        send(ua) {
          if (!(ua instanceof UserAgent)) {
            throw new Error("Request.send expects a UserAgent");
          }
          return ua.send(this);
        }
        send_async(ua) {
          if (!(ua instanceof UserAgent)) {
            throw new Error("Request.send_async expects a UserAgent");
          }
          return ua.send_async(this);
        }
      };
      function _derToPem(label, der) {
        const bytes = der instanceof Uint8Array ? der : der && der.bytes instanceof Uint8Array ? der.bytes : Uint8Array.from(der || []);
        const base642 = Buffer.from(bytes).toString("base64");
        const lines = base642.match(/.{1,64}/gu) || [];
        return `-----BEGIN ${label}-----
${lines.join("\n")}
-----END ${label}-----
`;
      }
      function _certificatePem(value, label) {
        if (value == null) {
          return "";
        }
        if (typeof value === "string") {
          if (!value.includes("-----BEGIN CERTIFICATE-----")) {
            throw new Error(`${label} expects PEM certificate text`);
          }
          return value;
        }
        if (value && value.__secureCertificate) {
          return _derToPem("CERTIFICATE", value.__secureCertificate.der);
        }
        throw new Error(`TypeException: ${label} expects Certificate, String PEM, or Array`);
      }
      function _caPem(value, label) {
        if (value == null) {
          return null;
        }
        if (Array.isArray(value)) {
          return value.map((item) => _certificatePem(item, label)).join("");
        }
        return _certificatePem(value, label);
      }
      function _tlsPolicy(spec, uaConfig) {
        const config = _toDict(uaConfig);
        const policy = {
          tls_identity: Object.prototype.hasOwnProperty.call(spec, "tls_identity") ? spec.tls_identity : config.tls_identity ?? null,
          tls_ca: config.tls_ca ?? null,
          tls_verify: Object.prototype.hasOwnProperty.call(config, "tls_verify") ? Boolean(config.tls_verify) : true,
          tls_server_name: config.tls_server_name ?? null,
          tls_min_version: config.tls_min_version ?? null,
          tls_ciphers: config.tls_ciphers ?? null
        };
        policy.active = Boolean(
          policy.tls_identity || policy.tls_ca || policy.tls_verify === false || policy.tls_server_name || policy.tls_min_version || policy.tls_ciphers
        );
        return policy;
      }
      function _assertBrowserTlsSupported(policy) {
        if (hostName2 === "browser" && policy.active) {
          throw new Error(
            "std/net/http TLS client configuration is not supported on JS/Browser"
          );
        }
      }
      function _identityState(identity, label) {
        if (!identity || !identity.__secureTlsIdentity) {
          throw new Error(`TypeException: ${label} expects TlsIdentity`);
        }
        return identity.__secureTlsIdentity;
      }
      function _tlsMinVersion(value) {
        if (value == null) {
          return void 0;
        }
        const text = String(value).toLowerCase();
        if (text === "tls1.2") {
          return "TLSv1.2";
        }
        if (text === "tls1.3") {
          return "TLSv1.3";
        }
        throw new Error("std/net/http tls_min_version must be 'tls1.2' or 'tls1.3'");
      }
      function _writeTempFile(content, files) {
        const fs = _nodeFs();
        const os = _nodeOs();
        const path = _nodePath();
        if (!fs || !os || !path) {
          throw new Error("Exception: temporary TLS file support is unavailable");
        }
        const dir = fs.mkdtempSync(path.join(os.tmpdir(), "zuzu-http-tls-"));
        const file = path.join(dir, "material.pem");
        fs.writeFileSync(file, content);
        files.push(file, dir);
        return file;
      }
      function _cleanupTempFiles(files) {
        const fs = _nodeFs();
        if (!fs) {
          return;
        }
        for (const file of files) {
          try {
            if (fs.statSync(file).isDirectory()) {
              fs.rmdirSync(file);
            } else {
              fs.unlinkSync(file);
            }
          } catch (_err) {
          }
        }
      }
      function _curlRequest(spec, uaConfig) {
        const spawnSync = _nodeSpawnSync();
        if (!spawnSync) {
          throw new Error("Exception: curl transport is unavailable");
        }
        const policy = _tlsPolicy(spec, uaConfig);
        if (policy.tls_server_name) {
          throw new Error(
            "std/net/http tls_server_name is not supported by the synchronous JS/Node HTTP backend"
          );
        }
        const method = String(spec.method || "GET").toUpperCase();
        const target = _urlWithQuery(spec.url, spec.query);
        const args = [
          "-sS",
          "-i",
          "-L",
          "--max-redirs",
          String(_maxRedirect(spec, uaConfig)),
          "-w",
          "\n\n__ZUZU_EFFECTIVE_URL:%{url_effective}",
          "-X",
          method,
          target
        ];
        const tempFiles = [];
        const headers = { ..._toDict(uaConfig.default_headers), ..._toDict(spec.headers) };
        if (uaConfig.agent) {
          headers["user-agent"] = String(uaConfig.agent);
        }
        if (uaConfig.cookie_jar && typeof uaConfig.cookie_jar.cookie_header === "function") {
          const cookie = uaConfig.cookie_jar.cookie_header(target);
          if (cookie) {
            headers.cookie = cookie;
          }
        }
        for (const [name2, value] of Object.entries(headers)) {
          args.push("-H", `${name2}: ${String(value)}`);
        }
        if (spec.json !== void 0) {
          args.push("--data", JSON.stringify(spec.json));
        } else if (spec.upload_from !== void 0) {
          args.push("--data-binary", `@${String(spec.upload_from)}`);
        } else if (spec.body !== void 0) {
          args.push("--data", String(spec.body));
        }
        if (policy.tls_identity) {
          const identity = _identityState(
            policy.tls_identity,
            "std/net/http tls_identity"
          );
          args.push("--cert", _writeTempFile(
            identity.certPem,
            tempFiles
          ));
          args.push("--key", _writeTempFile(identity.keyPem, tempFiles));
        }
        if (policy.tls_ca) {
          args.push("--cacert", _writeTempFile(
            _caPem(policy.tls_ca, "std/net/http tls_ca"),
            tempFiles
          ));
        }
        if (policy.tls_verify === false) {
          args.push("--insecure");
        }
        if (policy.tls_min_version) {
          args.push(
            String(policy.tls_min_version).toLowerCase() === "tls1.3" ? "--tlsv1.3" : "--tlsv1.2"
          );
        }
        if (policy.tls_ciphers) {
          args.push("--ciphers", String(policy.tls_ciphers));
        }
        let spawned;
        try {
          spawned = spawnSync("curl", args, { encoding: "utf8" });
        } finally {
          _cleanupTempFiles(tempFiles);
        }
        if (spawned.error) {
          throw spawned.error;
        }
        let raw = String(spawned.stdout || "");
        let effectiveUrl = target;
        const effectiveMatch = raw.match(/\n\n__ZUZU_EFFECTIVE_URL:([^\n\r]*)\s*$/u);
        if (effectiveMatch) {
          effectiveUrl = effectiveMatch[1] || target;
          raw = raw.slice(0, effectiveMatch.index);
        }
        const split = raw.split(/\r?\n\r?\n/u);
        let headerIndex = 0;
        for (let i = 0; i < split.length; i++) {
          if (/^HTTP\/\d(?:\.\d)?\s+\d+/u.test(split[i] || "")) {
            headerIndex = i;
          }
        }
        const headerText = split[headerIndex] || "";
        const body = split.slice(headerIndex + 1).join("\n\n");
        const headerLines = headerText.split(/\r?\n/u);
        const statusLine = headerLines.shift() || "HTTP/1.1 599 Request Failed";
        const statusMatch = statusLine.match(/^HTTP\/\d(?:\.\d)?\s+(\d+)(?:\s+(.*))?$/u);
        const status = statusMatch ? Number(statusMatch[1]) : 599;
        const reason = statusMatch ? statusMatch[2] || "" : "Request Failed";
        const outHeaders = {};
        for (const line of headerLines) {
          const idx = line.indexOf(":");
          if (idx < 0) {
            continue;
          }
          outHeaders[line.slice(0, idx).trim().toLowerCase()] = line.slice(idx + 1).trim();
        }
        if (outHeaders["set-cookie"] && uaConfig.cookie_jar && typeof uaConfig.cookie_jar.add === "function") {
          uaConfig.cookie_jar.add(effectiveUrl, outHeaders["set-cookie"]);
        }
        _writeDownload(spec, body);
        return new Response({
          status,
          reason,
          url: effectiveUrl,
          content: body,
          headers: outHeaders,
          success: status >= 200 && status < 300
        });
      }
      function _nodeHttpsRequest(spec, uaConfig, signal = null) {
        const https = _nodeHttps();
        if (!https) {
          throw new Error("Exception: https transport is unavailable");
        }
        const policy = _tlsPolicy(spec, uaConfig);
        const method = String(spec.method || "GET").toUpperCase();
        const target = _urlWithQuery(spec.url, spec.query);
        const url = new URL(target);
        if (url.protocol !== "https:") {
          throw new Error("std/net/http TLS configuration requires an https URL");
        }
        const headers = { ..._toDict(uaConfig.default_headers), ..._toDict(spec.headers) };
        if (uaConfig.agent) {
          headers["user-agent"] = String(uaConfig.agent);
        }
        if (uaConfig.cookie_jar && typeof uaConfig.cookie_jar.cookie_header === "function") {
          const cookie = uaConfig.cookie_jar.cookie_header(target);
          if (cookie) {
            headers.cookie = cookie;
          }
        }
        const body = spec.json !== void 0 ? JSON.stringify(spec.json) : spec.body !== void 0 ? String(spec.body) : null;
        if (spec.json !== void 0) {
          headers["content-type"] = headers["content-type"] || "application/json";
        }
        const options = {
          method,
          headers,
          rejectUnauthorized: policy.tls_verify !== false
        };
        if (policy.tls_identity) {
          const identity = _identityState(
            policy.tls_identity,
            "std/net/http tls_identity"
          );
          options.cert = identity.chainPem || identity.certPem;
          options.key = identity.keyPem;
          if (identity.password) {
            options.passphrase = identity.password;
          }
        }
        if (policy.tls_ca) {
          options.ca = _caPem(policy.tls_ca, "std/net/http tls_ca");
        }
        if (policy.tls_server_name) {
          options.servername = String(policy.tls_server_name);
        }
        if (policy.tls_min_version) {
          options.minVersion = _tlsMinVersion(policy.tls_min_version);
        }
        if (policy.tls_ciphers) {
          options.ciphers = String(policy.tls_ciphers);
        }
        return new Promise((resolve, reject) => {
          const req = https.request(url, options, (response) => {
            const chunks = [];
            response.on("data", (chunk) => chunks.push(chunk));
            response.on("end", () => {
              const outHeaders = {};
              for (const [name2, value] of Object.entries(response.headers)) {
                outHeaders[String(name2).toLowerCase()] = Array.isArray(value) ? value.join(", ") : String(value ?? "");
              }
              if (outHeaders["set-cookie"] && uaConfig.cookie_jar && typeof uaConfig.cookie_jar.add === "function") {
                uaConfig.cookie_jar.add(target, outHeaders["set-cookie"]);
              }
              const content = Buffer.concat(chunks).toString("utf8");
              _writeDownload(spec, content);
              resolve(new Response({
                status: response.statusCode || 599,
                reason: response.statusMessage || "",
                url: target,
                content,
                headers: outHeaders,
                success: (response.statusCode || 0) >= 200 && (response.statusCode || 0) < 300
              }));
            });
          });
          req.on("error", reject);
          if (signal) {
            signal.addEventListener("abort", () => req.destroy(
              new Error("HTTP request cancelled")
            ));
          }
          if (body != null) {
            req.write(body);
          }
          req.end();
        });
      }
      async function _fetchRequest(spec, uaConfig, signal = null) {
        if (typeof fetch !== "function") {
          throw new Error("Exception: fetch transport is unavailable");
        }
        const method = String(spec.method || "GET").toUpperCase();
        const target = _urlWithQuery(spec.url, spec.query);
        const headers = { ..._toDict(uaConfig.default_headers), ..._toDict(spec.headers) };
        if (uaConfig.agent) {
          headers["user-agent"] = String(uaConfig.agent);
        }
        if (uaConfig.cookie_jar && typeof uaConfig.cookie_jar.cookie_header === "function") {
          const cookie = uaConfig.cookie_jar.cookie_header(target);
          if (cookie) {
            headers.cookie = cookie;
          }
        }
        const fetchOptions = {
          method,
          headers
        };
        if (signal) {
          fetchOptions.signal = signal;
        }
        if (spec.json !== void 0) {
          headers["content-type"] = headers["content-type"] || "application/json";
          fetchOptions.body = JSON.stringify(spec.json);
        } else if (spec.body !== void 0) {
          fetchOptions.body = String(spec.body);
        }
        const response = await fetch(target, {
          ...fetchOptions,
          redirect: _maxRedirect(spec, uaConfig) === 0 ? "manual" : "follow"
        });
        const outHeaders = {};
        if (response.headers && typeof response.headers.forEach === "function") {
          response.headers.forEach((value, key) => {
            outHeaders[String(key).toLowerCase()] = String(value);
          });
        }
        if (outHeaders["set-cookie"] && uaConfig.cookie_jar && typeof uaConfig.cookie_jar.add === "function") {
          uaConfig.cookie_jar.add(target, outHeaders["set-cookie"]);
        }
        const content = await response.text();
        _writeDownload(spec, content);
        return new Response({
          status: response.status,
          reason: response.statusText || "",
          url: response.url || target,
          content,
          headers: outHeaders,
          success: response.ok
        });
      }
      async function _asyncRequest(spec, uaConfig, signal = null) {
        try {
          const policy = _tlsPolicy(spec, uaConfig);
          _assertBrowserTlsSupported(policy);
          if (hostName2 !== "browser" && policy.active) {
            return await _nodeHttpsRequest(spec, uaConfig, signal);
          }
          if (typeof fetch === "function") {
            return await _fetchRequest(spec, uaConfig, signal);
          }
          if (hostName2 !== "browser" && String(_urlWithQuery(spec.url, spec.query)).startsWith("https:") && _nodeHttps()) {
            return await _nodeHttpsRequest(spec, uaConfig, signal);
          }
          return _curlRequest(spec, uaConfig);
        } catch (err) {
          return new Response({
            status: 599,
            reason: err && err.message ? err.message : String(err || "Request Failed"),
            url: _urlWithQuery(spec.url, spec.query),
            content: "",
            headers: {},
            success: false
          });
        }
      }
      var UserAgent = class {
        constructor(options = {}, named = {}) {
          this._config = { ..._toDict(options), ..._toDict(named) };
        }
        build_request(method, url) {
          return new Request(method, url);
        }
        send(request) {
          if (!(request instanceof Request)) {
            throw new Error("UserAgent.send expects a Request");
          }
          traceBlockingOperation("std/net/http UserAgent.send");
          const policy = _tlsPolicy(request._spec, this._config);
          _assertBrowserTlsSupported(policy);
          if (hostName2 === "browser") {
            return _syncUnsupportedResponse(request._spec);
          }
          if (!_nodeSpawnSync() && typeof fetch === "function") {
            return _fetchRequest(request._spec, this._config);
          }
          return _curlRequest(request._spec, this._config);
        }
        send_async(request) {
          if (!(request instanceof Request)) {
            throw new Error("UserAgent.send_async expects a Request");
          }
          const timeoutSeconds = Number(
            request._spec.timeout || this._config.timeout || 0
          );
          const controller = typeof AbortController === "function" ? new AbortController() : null;
          let timer = null;
          const task = new Task(
            () => _asyncRequest(
              request._spec,
              this._config,
              controller ? controller.signal : null
            ),
            {
              name: "http.request",
              cancel() {
                if (timer != null) {
                  clearTimeout(timer);
                  timer = null;
                }
                if (controller) {
                  controller.abort();
                }
              }
            }
          );
          if (timeoutSeconds > 0 && controller) {
            timer = setTimeout(() => {
              controller.abort();
            }, Math.floor(timeoutSeconds * 1e3));
            task.finally(() => {
              if (timer != null) {
                clearTimeout(timer);
                timer = null;
              }
            });
          }
          return task;
        }
        request(method, url, data, headers) {
          const req = this.build_request(method, url);
          if (method === "POST" || method === "PUT" || method === "PATCH") {
            if (data !== void 0) {
              req.body(data);
            }
            if (headers !== void 0) {
              req.headers(headers);
            }
          } else {
            if (data !== void 0) {
              req.headers(data);
            }
          }
          return this.send(req);
        }
        request_async(method, url, data, headers) {
          const req = this.build_request(method, url);
          if (method === "POST" || method === "PUT" || method === "PATCH") {
            if (data !== void 0) {
              req.body(data);
            }
            if (headers !== void 0) {
              req.headers(headers);
            }
          } else if (data !== void 0) {
            req.headers(data);
          }
          return this.send_async(req);
        }
        get(url, headers) {
          return this.request("GET", url, headers);
        }
        get_async(url, headers) {
          return this.request_async("GET", url, headers);
        }
        head(url, headers) {
          return this.request("HEAD", url, headers);
        }
        head_async(url, headers) {
          return this.request_async("HEAD", url, headers);
        }
        delete(url, headers) {
          return this.request("DELETE", url, headers);
        }
        delete_async(url, headers) {
          return this.request_async("DELETE", url, headers);
        }
        options(url, headers) {
          return this.request("OPTIONS", url, headers);
        }
        options_async(url, headers) {
          return this.request_async("OPTIONS", url, headers);
        }
        post(url, data, headers) {
          return this.request("POST", url, data, headers);
        }
        post_async(url, data, headers) {
          return this.request_async("POST", url, data, headers);
        }
        put(url, data, headers) {
          return this.request("PUT", url, data, headers);
        }
        put_async(url, data, headers) {
          return this.request_async("PUT", url, data, headers);
        }
        patch(url, data, headers) {
          return this.request("PATCH", url, data, headers);
        }
        patch_async(url, data, headers) {
          return this.request_async("PATCH", url, data, headers);
        }
      };
      var api = {
        CookieJar,
        Request,
        Response,
        UserAgent
      };
      Object.defineProperty(api, "__zuzu_set_runtime_policy", {
        value(policy = {}) {
          hostName2 = policy.host_name || null;
        },
        enumerable: false
      });
      module2.exports = api;
    }
  });

  // modules/std/math.js
  var require_math = __commonJS({
    "modules/std/math.js"(exports2, module2) {
      "use strict";
      var PI = Math.PI;
      function normalizeNumberArgs(values) {
        if (values.length === 1 && Array.isArray(values[0])) {
          return values[0];
        }
        return values;
      }
      var ZMath = {
        pi: PI,
        sin(value) {
          return Math.sin(Number(value ?? 0));
        },
        cos(value) {
          return Math.cos(Number(value ?? 0));
        },
        tan(value) {
          return Math.tan(Number(value ?? 0));
        },
        asin(value) {
          return Math.asin(Number(value ?? 0));
        },
        acos(value) {
          return Math.acos(Number(value ?? 0));
        },
        atan(value) {
          return Math.atan(Number(value ?? 0));
        },
        atan2(y, x) {
          return Math.atan2(Number(y ?? 0), Number(x ?? 0));
        },
        pow(base, exp) {
          return Math.pow(Number(base ?? 0), Number(exp ?? 0));
        },
        exp(value) {
          return Math.exp(Number(value ?? 0));
        },
        log(value) {
          return Math.log(Number(value ?? 0));
        },
        log10(value) {
          return Math.log10(Number(value ?? 0));
        },
        min(...values) {
          return Math.min(...normalizeNumberArgs(values).map(Number));
        },
        max(...values) {
          return Math.max(...normalizeNumberArgs(values).map(Number));
        },
        sum(...values) {
          return normalizeNumberArgs(values).map(Number).reduce((acc, v) => acc + v, 0);
        },
        clamp(value, low, high) {
          return Math.min(Number(high ?? 0), Math.max(Number(low ?? 0), Number(value ?? 0)));
        },
        hypot(...values) {
          return Math.hypot(...values.map(Number));
        },
        deg2rad(degrees) {
          return Number(degrees ?? 0) * (PI / 180);
        },
        rad2deg(radians) {
          return Number(radians ?? 0) * (180 / PI);
        },
        rand() {
          return Math.random();
        },
        hex2dec(value) {
          return convertBase(value, 16, 10);
        },
        hex2oct(value) {
          return convertBase(value, 16, 8);
        },
        hex2bin(value) {
          return convertBase(value, 16, 2);
        },
        dec2hex(value) {
          return convertBase(value, 10, 16);
        },
        dec2oct(value) {
          return convertBase(value, 10, 8);
        },
        dec2bin(value) {
          return convertBase(value, 10, 2);
        },
        oct2hex(value) {
          return convertBase(value, 8, 16);
        },
        oct2dec(value) {
          return convertBase(value, 8, 10);
        },
        oct2bin(value) {
          return convertBase(value, 8, 2);
        },
        bin2hex(value) {
          return convertBase(value, 2, 16);
        },
        bin2dec(value) {
          return convertBase(value, 2, 10);
        },
        bin2oct(value) {
          return convertBase(value, 2, 8);
        }
      };
      function normalizeDigits(value, base) {
        let text = String(value ?? "").trim().toLowerCase();
        if (base === 16) {
          text = text.replace(/^0x/u, "");
        } else if (base === 8) {
          text = text.replace(/^0o/u, "");
        } else if (base === 2) {
          text = text.replace(/^0b/u, "");
        }
        return text;
      }
      function convertBase(value, fromBase, toBase) {
        const text = normalizeDigits(value, fromBase);
        if (text === "") {
          return "0";
        }
        const num = Number.parseInt(text, fromBase);
        if (Number.isNaN(num)) {
          return "0";
        }
        return num.toString(toBase);
      }
      module2.exports = {
        Math: ZMath,
        pi: PI,
        \u03C0: PI
      };
    }
  });

  // modules/std/math/bignum.js
  var require_bignum = __commonJS({
    "modules/std/math/bignum.js"(exports2, module2) {
      "use strict";
      var BigNum = class _BigNum {
        constructor(value, text = null, isInt = null) {
          this._value = Number(value ?? 0);
          this._text = text == null ? String(this._value) : String(text);
          this._isInt = isInt == null ? Number.isInteger(this._value) : Boolean(isInt);
        }
        static _coerce(value) {
          if (value instanceof _BigNum) {
            return value;
          }
          if (typeof value === "string") {
            return _BigNum.from_dec(value);
          }
          return new _BigNum(Number(value ?? 0));
        }
        static from_dec(value) {
          const text = String(value ?? "0").trim();
          return new _BigNum(Number(text || "0"), text || "0", !/[.eE]/.test(text));
        }
        static from_hex(value) {
          const text = String(value ?? "0").trim().toLowerCase().replace(/^0x/u, "") || "0";
          const parsed = Number.parseInt(text, 16);
          return new _BigNum(parsed, String(parsed), true);
        }
        get is_int() {
          return this._isInt;
        }
        bcmp(other) {
          const rhs = _BigNum._coerce(other)._value;
          return this._value < rhs ? -1 : this._value > rhs ? 1 : 0;
        }
        beq(other) {
          return this.bcmp(other) === 0;
        }
        bne(other) {
          return this.bcmp(other) !== 0;
        }
        blt(other) {
          return this.bcmp(other) < 0;
        }
        ble(other) {
          return this.bcmp(other) <= 0;
        }
        bgt(other) {
          return this.bcmp(other) > 0;
        }
        bge(other) {
          return this.bcmp(other) >= 0;
        }
        get babs() {
          return new _BigNum(Math.abs(this._value), String(Math.abs(this._value)), this._isInt);
        }
        get bneg() {
          return new _BigNum(-this._value, String(-this._value), this._isInt);
        }
        get binv() {
          return new _BigNum(1 / this._value);
        }
        get bsin() {
          return new _BigNum(Math.sin(this._value), String(Math.sin(this._value)), false);
        }
        get bcos() {
          return new _BigNum(Math.cos(this._value));
        }
        get btan() {
          return new _BigNum(Math.tan(this._value), String(Math.tan(this._value)), false);
        }
        get bsqrt() {
          return new _BigNum(Math.sqrt(this._value));
        }
        get bround() {
          return new _BigNum(Math.round(this._value));
        }
        get bfloor() {
          return new _BigNum(Math.floor(this._value));
        }
        get bceil() {
          return new _BigNum(Math.ceil(this._value));
        }
        badd(other) {
          return new _BigNum(this._value + _BigNum._coerce(other)._value, String(this._value + _BigNum._coerce(other)._value), false);
        }
        bsub(other) {
          return new _BigNum(this._value - _BigNum._coerce(other)._value, String(this._value - _BigNum._coerce(other)._value), false);
        }
        bmul(other) {
          return new _BigNum(this._value * _BigNum._coerce(other)._value, String(this._value * _BigNum._coerce(other)._value), false);
        }
        bdiv(other) {
          return new _BigNum(this._value / _BigNum._coerce(other)._value);
        }
        bmod(other) {
          return new _BigNum(this._value % _BigNum._coerce(other)._value);
        }
        bpow(other) {
          return new _BigNum(this._value ** _BigNum._coerce(other)._value);
        }
        get to_hex() {
          return `0x${Math.trunc(this._value).toString(16)}`;
        }
        get to_dec() {
          return this._isInt ? Math.trunc(this._value) : this._textify();
        }
        get to_String() {
          return this.to_dec;
        }
        get to_Number() {
          return this._value;
        }
        _textify() {
          if (this._text != null && /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/u.test(this._text)) {
            return this._text.replace(/\.0+$/u, "").replace(/(\.\d*?)0+$/u, "$1").replace(/\.$/u, "");
          }
          return String(this._value);
        }
      };
      module2.exports = {
        BigNum
      };
    }
  });

  // modules/std/eval.js
  var require_eval = __commonJS({
    "modules/std/eval.js"(exports2, module2) {
      "use strict";
      function evalZuzu(code) {
        const src = String(code ?? "");
        return (0, eval)(src);
      }
      module2.exports = {
        eval: evalZuzu
      };
    }
  });

  // modules/std/gui/objects.js
  var require_objects = __commonJS({
    "modules/std/gui/objects.js"(exports2, module2) {
      "use strict";
      var {
        makeWeakValue,
        retainValue,
        releaseValue,
        resolveWeakValue
      } = require_runtime_helpers();
      var runtimePolicy2 = {
        deny_gui: true,
        gui: null,
        host_name: "node"
      };
      var meta = {
        backend: "electron-dom",
        font_size_pixels: 16,
        font_name: "system-ui",
        font_point_size: 12
      };
      var nextWidgetId = 1;
      function _getProp(props, key, fallback = null) {
        if (props && typeof props.get === "function") {
          return props.get(key, fallback);
        }
        if (props && Object.prototype.hasOwnProperty.call(props, key)) {
          return props[key];
        }
        return fallback;
      }
      function _setProp(props, key, value) {
        if (props && typeof props.set === "function") {
          if (typeof props.remove === "function") {
            props.remove(key);
          }
          props.set(key, value);
          return;
        }
        props[key] = value;
      }
      function _getChildren(props) {
        const children = _getProp(props, "children", []);
        return Array.isArray(children) ? children : [];
      }
      function _asBool(value) {
        return value ? true : false;
      }
      function _asArray(value) {
        return Array.isArray(value) ? value : [];
      }
      function _itemChildren(item) {
        if (item && typeof item === "object") {
          if (typeof item.get === "function") {
            return _asArray(item.get("children", []));
          }
          if (Array.isArray(item.children)) {
            return item.children;
          }
        }
        return [];
      }
      function _isMenuKind(value) {
        return value instanceof Menu || value instanceof MenuItem;
      }
      function _weak(value) {
        return makeWeakValue(value);
      }
      function _resolve(value) {
        return resolveWeakValue(value);
      }
      function _retainDispatchPath(path) {
        for (const widget of path) {
          retainValue(widget);
        }
      }
      function _releaseDispatchPath(path) {
        for (const widget of path) {
          releaseValue(widget);
        }
      }
      var ListenerToken = class {
        constructor(widget, type, id) {
          this.widget = _weak(widget);
          this.type = String(type);
          this.id = id;
        }
      };
      var Event = class {
        constructor(props = {}) {
          this.__zuzu_name = String(props.name || props.type || "");
          this.__zuzu_target = _weak(props.target || null);
          this.__zuzu_current_target = _weak(props.current_target || null);
          this.__zuzu_timestamp = Date.now() / 1e3;
          this.__zuzu_data = Object.prototype.hasOwnProperty.call(props, "data") ? props.data : null;
          this.__zuzu_value = Object.prototype.hasOwnProperty.call(props, "value") ? props.value : null;
          this.__zuzu_cancelled = false;
          this.__zuzu_propagation_stopped = false;
          this.__zuzu_default_prevented = false;
          this.__zuzu_phase = "";
        }
        name() {
          return this.__zuzu_name;
        }
        type() {
          return this.__zuzu_name;
        }
        target() {
          return _resolve(this.__zuzu_target);
        }
        current_target() {
          return _resolve(this.__zuzu_current_target);
        }
        currentTarget() {
          return _resolve(this.__zuzu_current_target);
        }
        phase() {
          return this.__zuzu_phase;
        }
        timestamp() {
          return this.__zuzu_timestamp;
        }
        data() {
          return this.__zuzu_data;
        }
        value() {
          return this.__zuzu_value;
        }
        cancelled() {
          return this.__zuzu_cancelled;
        }
        propagation_stopped() {
          return this.__zuzu_propagation_stopped;
        }
        default_prevented() {
          return this.__zuzu_default_prevented;
        }
        window() {
          const target = _resolve(this.__zuzu_target);
          return target instanceof Widget ? target.__zuzu_owner_window_live() : null;
        }
        stop_propagation() {
          this.__zuzu_propagation_stopped = true;
          this.__zuzu_cancelled = true;
          return this;
        }
        prevent_default() {
          this.__zuzu_default_prevented = true;
          this.__zuzu_cancelled = true;
          return this;
        }
      };
      var Widget = class _Widget {
        constructor(props = {}) {
          this.__zuzu_gui_id = `w${nextWidgetId++}`;
          this.__zuzu_gui_type = this.__zuzu_gui_type_name || this.constructor.name;
          this.__zuzu_props = props || {};
          this.__zuzu_parent = _weak(null);
          this.__zuzu_event_parent = null;
          this.__zuzu_children = [];
          this.__zuzu_listeners = /* @__PURE__ */ new Map();
          this.__zuzu_listener_seq = 0;
          this.__zuzu_meta = /* @__PURE__ */ Object.create(null);
          this.__zuzu_style = /* @__PURE__ */ Object.create(null);
          this.__zuzu_classes = [];
          for (const child of _getChildren(this.__zuzu_props)) {
            this.add_child(child);
          }
        }
        id(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "id", null);
          }
          _setProp(this.__zuzu_props, "id", value == null ? null : String(value));
          this.__zuzu_update_native();
          return this;
        }
        set_id(value) {
          return this.id(value);
        }
        parent() {
          return _resolve(this.__zuzu_parent);
        }
        children() {
          return this.__zuzu_children.slice();
        }
        add_child(child) {
          if (child == null) {
            return this;
          }
          if (!(child instanceof _Widget)) {
            throw new Error("GUI_PROP_TYPE: add_child expects a Widget");
          }
          if (this instanceof MenuItem) {
            throw new Error("GUI_PROP_TYPE: MenuItem widgets cannot have children");
          }
          if (child instanceof Menu && !(this instanceof Window)) {
            throw new Error("GUI_PROP_TYPE: Menu widgets can only be Window children");
          }
          if (child instanceof MenuItem && !(this instanceof Menu)) {
            throw new Error("GUI_PROP_TYPE: MenuItem widgets can only be Menu children");
          }
          if (this instanceof Menu && !(child instanceof MenuItem)) {
            throw new Error("GUI_PROP_TYPE: Menu widgets can only contain MenuItem children");
          }
          const oldParent = child.parent();
          if (oldParent && oldParent !== this) {
            oldParent.remove_child(child);
          }
          if (this.__zuzu_children.includes(child)) {
            return this;
          }
          child.__zuzu_parent = _weak(this);
          child.__zuzu_event_parent = this;
          this.__zuzu_children.push(child);
          this.__zuzu_child_added(child);
          if (this instanceof Window && !_isMenuKind(child) && this.__zuzu_content == null) {
            this.__zuzu_content = child;
          }
          this.__zuzu_create_native_child(child);
          return this;
        }
        __zuzu_child_added(_child) {
        }
        remove_child(child) {
          if (!(child instanceof _Widget)) {
            return this;
          }
          const before = this.__zuzu_children.length;
          this.__zuzu_children = this.__zuzu_children.filter((item) => item !== child);
          if (this.__zuzu_children.length === before) {
            return this;
          }
          this.__zuzu_destroy_native_child(child);
          this.__zuzu_child_removed(child);
          if (child.parent() === this) {
            child.__zuzu_parent = _weak(null);
          }
          if (child.__zuzu_event_parent === this) {
            child.__zuzu_event_parent = null;
          }
          if (this instanceof Window && this.__zuzu_content === child) {
            this.__zuzu_content = this.__zuzu_children.find(
              (item) => !_isMenuKind(item)
            ) || null;
          }
          return this;
        }
        __zuzu_child_removed(_child) {
        }
        find_by_id(id) {
          if (this.id() != null && this.id() === String(id)) {
            return this;
          }
          for (const child of this.__zuzu_children) {
            const found = child.find_by_id(id);
            if (found) {
              return found;
            }
          }
          return null;
        }
        enabled(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "disabled", false) ? false : Boolean(_getProp(this.__zuzu_props, "enabled", true));
          }
          _setProp(this.__zuzu_props, "enabled", value ? true : false);
          _setProp(this.__zuzu_props, "disabled", value ? false : true);
          this.__zuzu_update_native();
          return this;
        }
        set_enabled(value) {
          return this.enabled(value);
        }
        disabled(value) {
          if (arguments.length === 0) {
            return this.enabled() ? false : true;
          }
          return this.enabled(value ? false : true);
        }
        visible(value) {
          if (arguments.length === 0) {
            return Boolean(_getProp(this.__zuzu_props, "visible", true));
          }
          _setProp(this.__zuzu_props, "visible", value ? true : false);
          this.__zuzu_update_native();
          return this;
        }
        set_visible(value) {
          return this.visible(value);
        }
        classes() {
          return this.__zuzu_classes.slice();
        }
        add_class(name2) {
          const key = String(name2);
          if (!this.__zuzu_classes.includes(key)) {
            this.__zuzu_classes.push(key);
            this.__zuzu_update_native();
          }
          return this;
        }
        remove_class(name2) {
          const key = String(name2);
          const before = this.__zuzu_classes.length;
          this.__zuzu_classes = this.__zuzu_classes.filter((item) => item !== key);
          if (before !== this.__zuzu_classes.length) {
            this.__zuzu_update_native();
          }
          return this;
        }
        style(key, value) {
          if (arguments.length === 0) {
            return { ...this.__zuzu_style };
          }
          const name2 = String(key);
          if (arguments.length === 1) {
            return this.__zuzu_style[name2] ?? null;
          }
          this.__zuzu_style[name2] = value;
          this.__zuzu_update_native();
          return this;
        }
        meta(key, value) {
          if (arguments.length === 0) {
            return { ...this.__zuzu_meta };
          }
          const name2 = String(key);
          if (arguments.length === 1) {
            return this.__zuzu_meta[name2] ?? null;
          }
          this.__zuzu_meta[name2] = value;
          return this;
        }
        on(type, handler) {
          if (typeof handler !== "function") {
            throw new Error("GUI_EVENT_HANDLER: on expects a Function handler");
          }
          const name2 = String(type);
          const id = ++this.__zuzu_listener_seq;
          if (!this.__zuzu_listeners.has(name2)) {
            this.__zuzu_listeners.set(name2, []);
          }
          this.__zuzu_listeners.get(name2).push({
            id,
            handler,
            once: false
          });
          return new ListenerToken(this, name2, id);
        }
        once(type, handler) {
          if (typeof handler !== "function") {
            throw new Error("GUI_EVENT_HANDLER: once expects a Function handler");
          }
          const name2 = String(type);
          const id = ++this.__zuzu_listener_seq;
          if (!this.__zuzu_listeners.has(name2)) {
            this.__zuzu_listeners.set(name2, []);
          }
          this.__zuzu_listeners.get(name2).push({
            id,
            handler,
            once: true
          });
          return new ListenerToken(this, name2, id);
        }
        off(token) {
          if (!(token instanceof ListenerToken) || _resolve(token.widget) !== this) {
            return false;
          }
          const listeners = this.__zuzu_listeners.get(token.type);
          if (!listeners) {
            return false;
          }
          const before = listeners.length;
          const kept = listeners.filter((listener) => listener.id !== token.id);
          this.__zuzu_listeners.set(token.type, kept);
          return kept.length !== before;
        }
        emit(type, payload = null) {
          const name2 = String(type);
          const event = payload instanceof Event ? payload : new Event({
            name: name2,
            target: this,
            data: payload,
            value: payload
          });
          event.__zuzu_name = name2;
          if (_resolve(event.__zuzu_target) == null) {
            event.__zuzu_target = _weak(this);
          }
          this.__zuzu_dispatch_event(event);
          return event;
        }
        __zuzu_dispatch_event(event) {
          const path = [];
          let current = this;
          while (current) {
            path.push(current);
            current = current.__zuzu_event_parent;
          }
          _retainDispatchPath(path);
          try {
            this.__zuzu_dispatch_at(event, "target");
            for (let i = 1; i < path.length; i++) {
              if (event.__zuzu_propagation_stopped) {
                break;
              }
              path[i].__zuzu_dispatch_at(event, "bubble");
            }
          } finally {
            _releaseDispatchPath(path);
          }
        }
        __zuzu_dispatch_at(event, phase) {
          const listeners = (this.__zuzu_listeners.get(event.__zuzu_name) || []).slice();
          if (listeners.length === 0) {
            return;
          }
          event.__zuzu_current_target = _weak(this);
          event.__zuzu_phase = phase;
          for (const listener of listeners) {
            listener.handler(event);
            if (listener.once) {
              this.off(new ListenerToken(this, event.__zuzu_name, listener.id));
            }
            if (event.__zuzu_propagation_stopped) {
              break;
            }
          }
        }
        __zuzu_owner_window() {
          let current = this;
          while (current) {
            if (current instanceof Window) {
              return current;
            }
            current = current.parent();
          }
          return null;
        }
        __zuzu_owner_window_live() {
          let current = this;
          while (current) {
            if (current instanceof Window) {
              return current;
            }
            current = current.__zuzu_event_parent;
          }
          return null;
        }
        __zuzu_create_native_child(child) {
          const window2 = this.__zuzu_owner_window_live();
          if (!window2 || window2.__zuzu_electron_window_id == null || !runtimePolicy2.gui || typeof runtimePolicy2.gui.createWidget !== "function") {
            return;
          }
          runtimePolicy2.gui.createWidget(
            window2.__zuzu_electron_window_id,
            this.__zuzu_gui_id,
            child.__zuzu_gui_snapshot(),
            this.__zuzu_children.indexOf(child)
          );
        }
        __zuzu_destroy_native_child(child) {
          const window2 = this.__zuzu_owner_window_live();
          if (!window2 || window2.__zuzu_electron_window_id == null || !runtimePolicy2.gui || typeof runtimePolicy2.gui.destroyWidget !== "function") {
            return;
          }
          runtimePolicy2.gui.destroyWidget(
            window2.__zuzu_electron_window_id,
            child.__zuzu_gui_id
          );
        }
        __zuzu_update_native() {
          const window2 = this.__zuzu_owner_window_live();
          if (!window2 || window2.__zuzu_electron_window_id == null || !runtimePolicy2.gui || typeof runtimePolicy2.gui.updateWidget !== "function") {
            return;
          }
          runtimePolicy2.gui.updateWidget(
            window2.__zuzu_electron_window_id,
            this.__zuzu_gui_snapshot()
          );
        }
        __zuzu_set_prop_silent(key, value) {
          _setProp(this.__zuzu_props, key, value);
        }
        __zuzu_find_by_guid(guid) {
          if (this.__zuzu_gui_id === guid) {
            return this;
          }
          for (const child of this.__zuzu_children) {
            const found = child.__zuzu_find_by_guid(guid);
            if (found) {
              return found;
            }
          }
          return null;
        }
        __zuzu_gui_snapshot() {
          return {
            guid: this.__zuzu_gui_id,
            type: this.__zuzu_gui_type,
            id: this.id(),
            classes: this.classes(),
            props: {
              disabled: this.disabled(),
              enabled: this.enabled(),
              visible: this.visible(),
              align: _getProp(this.__zuzu_props, "align", null),
              alt: _getProp(this.__zuzu_props, "alt", null),
              checked: _getProp(this.__zuzu_props, "checked", null),
              closable: _getProp(this.__zuzu_props, "closable", null),
              collapsible: _getProp(this.__zuzu_props, "collapsible", null),
              collapsed: _getProp(this.__zuzu_props, "collapsed", null),
              first_day_of_week: _getProp(this.__zuzu_props, "first_day_of_week", null),
              fit: _getProp(this.__zuzu_props, "fit", null),
              for_id: this.for_id ? this.for_id() : null,
              group: _getProp(this.__zuzu_props, "group", null),
              icon: _getProp(this.__zuzu_props, "icon", null),
              indeterminate: _getProp(this.__zuzu_props, "indeterminate", null),
              items: _getProp(this.__zuzu_props, "items", null),
              label: _getProp(this.__zuzu_props, "label", null),
              max: _getProp(this.__zuzu_props, "max", null),
              min: _getProp(this.__zuzu_props, "min", null),
              modal: _getProp(this.__zuzu_props, "modal", null),
              multiline: _getProp(this.__zuzu_props, "multiline", null),
              multiple: _getProp(this.__zuzu_props, "multiple", null),
              name: _getProp(this.__zuzu_props, "name", null),
              options: _getProp(this.__zuzu_props, "options", null),
              orientation: _getProp(this.__zuzu_props, "orientation", null),
              password: _getProp(this.__zuzu_props, "password", null),
              title: _getProp(this.__zuzu_props, "title", null),
              placement: _getProp(this.__zuzu_props, "placement", null),
              text: _getProp(this.__zuzu_props, "text", null),
              readonly: _getProp(this.__zuzu_props, "readonly", null),
              required: _getProp(this.__zuzu_props, "required", null),
              resizable: _getProp(this.__zuzu_props, "resizable", null),
              selected: _getProp(this.__zuzu_props, "selected", null),
              selected_index: _getProp(this.__zuzu_props, "selected_index", null),
              selected_path: _getProp(this.__zuzu_props, "selected_path", null),
              show_text: _getProp(this.__zuzu_props, "show_text", null),
              src: _getProp(this.__zuzu_props, "src", null),
              step: _getProp(this.__zuzu_props, "step", null),
              value: _getProp(this.__zuzu_props, "value", null),
              placeholder: _getProp(this.__zuzu_props, "placeholder", null),
              variant: _getProp(this.__zuzu_props, "variant", null),
              wrap: _getProp(this.__zuzu_props, "wrap", null),
              width: _getProp(this.__zuzu_props, "width", null),
              height: _getProp(this.__zuzu_props, "height", null),
              minwidth: _getProp(this.__zuzu_props, "minwidth", null),
              minheight: _getProp(this.__zuzu_props, "minheight", null),
              maxwidth: _getProp(this.__zuzu_props, "maxwidth", null),
              maxheight: _getProp(this.__zuzu_props, "maxheight", null),
              gap: _getProp(this.__zuzu_props, "gap", null),
              padding: _getProp(this.__zuzu_props, "padding", null)
            },
            children: this.__zuzu_children.map(
              (child) => child.__zuzu_gui_snapshot()
            )
          };
        }
      };
      for (const name2 of [
        "width",
        "height",
        "minwidth",
        "minheight",
        "maxwidth",
        "maxheight",
        "align",
        "alt",
        "closable",
        "collapsible",
        "collapsed",
        "first_day_of_week",
        "fit",
        "gap",
        "group",
        "icon",
        "indeterminate",
        "label",
        "max",
        "min",
        "modal",
        "multiline",
        "multiple",
        "name",
        "orientation",
        "padding",
        "password",
        "placement",
        "readonly",
        "required",
        "resizable",
        "selected",
        "show_text",
        "src",
        "step",
        "title",
        "text",
        "value",
        "placeholder",
        "variant",
        "wrap"
      ]) {
        Widget.prototype[name2] = function propAccessor(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, name2, null);
          }
          _setProp(this.__zuzu_props, name2, value == null ? "" : value);
          this.__zuzu_update_native();
          return this;
        };
      }
      Widget.prototype.for_id = function forId(value) {
        if (arguments.length === 0) {
          return _getProp(this.__zuzu_props, "for", null);
        }
        _setProp(this.__zuzu_props, "for", value == null ? null : String(value));
        this.__zuzu_update_native();
        return this;
      };
      Widget.prototype.set_for_id = function setForId(value) {
        return this.for_id(value);
      };
      Widget.prototype.set_value = function setValue(value) {
        return this.value(value);
      };
      Widget.prototype.set_text = function setText(value) {
        return this.text(value);
      };
      Widget.prototype.set_title = function setTitle(value) {
        return this.title(value);
      };
      for (const eventName of [
        "activate",
        "blur",
        "change",
        "click",
        "close_request",
        "closed",
        "collapse",
        "enter",
        "expand",
        "focus",
        "input",
        "open",
        "resize",
        "select",
        "submit"
      ]) {
        Widget.prototype[eventName] = function eventShortcut(handler = null) {
          if (handler == null) {
            return this.emit(eventName);
          }
          return this.on(eventName, handler);
        };
      }
      var Window = class extends Widget {
        constructor(props = {}) {
          super(props);
          this.__zuzu_close_result = null;
          this.__zuzu_electron_window_id = null;
          this.__zuzu_closed = false;
          this.__zuzu_shown = false;
          this.__zuzu_native_close_allowed = false;
          this.__zuzu_close_waiters = [];
          this.__zuzu_content = _getProp(props, "content", null);
          if (this.__zuzu_content != null && (!(this.__zuzu_content instanceof Widget) || _isMenuKind(this.__zuzu_content))) {
            throw new Error("GUI_PROP_TYPE: Window content expects a non-menu Widget or null");
          }
          if (this.__zuzu_content != null && !this.__zuzu_children.includes(this.__zuzu_content)) {
            this.add_child(this.__zuzu_content);
          }
          if (this.__zuzu_content == null) {
            this.__zuzu_content = this.__zuzu_children.find(
              (child) => !_isMenuKind(child)
            ) || null;
          }
        }
        content() {
          return this.__zuzu_content;
        }
        menus() {
          return this.__zuzu_children.filter((child) => child instanceof Menu);
        }
        set_content(child = null) {
          if (child != null && (!(child instanceof Widget) || _isMenuKind(child))) {
            throw new Error("GUI_PROP_TYPE: set_content expects a non-menu Widget or null");
          }
          for (const old of this.__zuzu_children.slice()) {
            if (!_isMenuKind(old)) {
              this.remove_child(old);
            }
          }
          this.__zuzu_content = child;
          if (child != null) {
            this.add_child(child);
          }
          return this;
        }
        show() {
          if (runtimePolicy2.deny_gui || !runtimePolicy2.gui) {
            throw new Error(
              `GUI is not available on host '${runtimePolicy2.host_name}'`
            );
          }
          if (this.__zuzu_electron_window_id != null) {
            return this;
          }
          const result = runtimePolicy2.gui.openWindow(
            this.__zuzu_gui_snapshot(),
            {
              onEvent: (event) => this.__zuzu_receive_gui_event(event),
              onCloseRequest: () => this.__zuzu_native_close_request(),
              onClosed: () => this.__zuzu_native_closed()
            }
          );
          const markShown = (windowId) => {
            this.__zuzu_electron_window_id = windowId;
            this.__zuzu_shown = true;
            this.emit("open");
            return this;
          };
          if (result && typeof result.then === "function") {
            return result.then(markShown);
          }
          return markShown(result);
        }
        call(options = null) {
          const asyncCall = _getProp(options, "async", false) ? true : false;
          if (this.__zuzu_closed) {
            if (asyncCall) {
              return Promise.resolve(this.__zuzu_close_result);
            }
            return this.__zuzu_close_result;
          }
          if (runtimePolicy2.host_name === "browser" && !asyncCall) {
            throw new Error(
              "GUI_CALL_SYNC_UNSUPPORTED: Window.call requires async: true on host 'browser'"
            );
          }
          const shown = this.show();
          if (shown && typeof shown.then === "function") {
            return shown.then(() => this.__zuzu_wait_for_close());
          }
          return this.__zuzu_wait_for_close();
        }
        close(result = null) {
          return this.__zuzu_close(result, false);
        }
        __zuzu_close(result = null, nativeClose = false) {
          if (this.__zuzu_closed) {
            return this;
          }
          const request = this.emit("close_request", result);
          if (request.cancelled() || request.default_prevented()) {
            return this;
          }
          this.__zuzu_closed = true;
          this.__zuzu_close_result = result;
          if (!nativeClose && runtimePolicy2.gui && typeof runtimePolicy2.gui.closeWindow === "function" && this.__zuzu_electron_window_id != null) {
            runtimePolicy2.gui.closeWindow(this.__zuzu_electron_window_id);
          }
          this.emit("closed", result);
          this.__zuzu_resolve_close_waiters();
          return this;
        }
        __zuzu_wait_for_close() {
          if (this.__zuzu_closed) {
            return this.__zuzu_close_result;
          }
          return new Promise((resolve) => {
            this.__zuzu_close_waiters.push(resolve);
          });
        }
        __zuzu_resolve_close_waiters() {
          const waiters = this.__zuzu_close_waiters.splice(0);
          for (const resolve of waiters) {
            resolve(this.__zuzu_close_result);
          }
        }
        __zuzu_native_close_request() {
          if (this.__zuzu_closed) {
            return false;
          }
          const request = this.emit("close_request", null);
          if (request.cancelled() || request.default_prevented()) {
            return true;
          }
          this.__zuzu_native_close_allowed = true;
          return false;
        }
        __zuzu_native_closed() {
          if (this.__zuzu_closed) {
            return;
          }
          this.__zuzu_closed = true;
          this.__zuzu_close_result = null;
          this.emit("closed", null);
          this.__zuzu_resolve_close_waiters();
        }
        __zuzu_receive_gui_event(raw = {}) {
          const target = raw.widgetGuid ? this.__zuzu_find_by_guid(raw.widgetGuid) : this;
          if (!target) {
            return;
          }
          if (Object.prototype.hasOwnProperty.call(raw, "value")) {
            target.__zuzu_set_prop_silent("value", raw.value);
          }
          if (Object.prototype.hasOwnProperty.call(raw, "checked") && typeof target.checked === "function") {
            target.__zuzu_set_prop_silent("checked", raw.checked ? true : false);
          }
          if (Object.prototype.hasOwnProperty.call(raw, "selected_index") && typeof target.selected_index === "function") {
            target.__zuzu_set_prop_silent(
              "selected_index",
              raw.selected_index == null ? null : Number(raw.selected_index)
            );
          }
          if (Object.prototype.hasOwnProperty.call(raw, "selected") && typeof target.selected === "function") {
            target.__zuzu_set_prop_silent(
              "selected",
              raw.selected == null ? null : String(raw.selected)
            );
            if (target instanceof Tabs) {
              target.__zuzu_sync_tabs();
            }
          }
          if (Object.prototype.hasOwnProperty.call(raw, "selected_path") && typeof target.selected_path === "function") {
            target.__zuzu_set_prop_silent(
              "selected_path",
              _asArray(raw.selected_path).map(Number)
            );
          }
          if (target instanceof TreeView && Object.prototype.hasOwnProperty.call(raw, "selected_path") && raw.type === "expand") {
            target.__zuzu_set_expanded_silent(raw.selected_path, true);
            target.emit(raw.type, new Event({
              name: raw.type,
              target,
              data: raw,
              value: raw.selected_path
            }));
            return;
          }
          if (target instanceof TreeView && Object.prototype.hasOwnProperty.call(raw, "selected_path") && raw.type === "collapse") {
            target.__zuzu_set_expanded_silent(raw.selected_path, false);
            target.emit(raw.type, new Event({
              name: raw.type,
              target,
              data: raw,
              value: raw.selected_path
            }));
            return;
          }
          target.emit(raw.type, new Event({
            name: raw.type,
            target,
            data: raw,
            value: Object.prototype.hasOwnProperty.call(raw, "value") ? raw.value : null
          }));
        }
      };
      var VBox = class extends Widget {
      };
      var HBox = class extends Widget {
      };
      var Frame = class extends Widget {
      };
      var Label = class extends Widget {
      };
      var Text = class extends Widget {
      };
      var RichText = class extends Widget {
      };
      var Image = class extends Widget {
      };
      var Input = class extends Widget {
        constructor(props = {}) {
          if (props && typeof props.get === "function") {
            if (typeof props.has === "function" && props.has("value")) {
              const value = props.get("value");
              props.set("value", value == null ? "" : String(value));
            }
            super(props);
            return;
          }
          const cooked = { ...props };
          if (Object.prototype.hasOwnProperty.call(cooked, "value")) {
            cooked.value = cooked.value == null ? "" : String(cooked.value);
          }
          super(cooked);
        }
        value(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "value", null);
          }
          _setProp(this.__zuzu_props, "value", value == null ? "" : String(value));
          this.__zuzu_update_native();
          return this;
        }
        select_all() {
          this.emit("select_all");
          return this;
        }
      };
      var DatePicker = class extends Widget {
      };
      var Checkbox = class extends Widget {
        checked(value) {
          if (arguments.length === 0) {
            return _asBool(_getProp(this.__zuzu_props, "checked", false));
          }
          _setProp(this.__zuzu_props, "checked", _asBool(value));
          this.__zuzu_update_native();
          return this;
        }
      };
      var Radio = class extends Checkbox {
        checked(value) {
          if (arguments.length === 0) {
            return super.checked();
          }
          super.checked(value);
          const parent = this.parent();
          if (value && parent instanceof RadioGroup) {
            parent.value(this.value());
          }
          return this;
        }
      };
      var RadioGroup = class extends Widget {
        constructor(props = {}) {
          super(props);
          this.__zuzu_sync_radios();
        }
        options() {
          return this.children().filter((child) => child instanceof Radio);
        }
        value(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "value", null);
          }
          _setProp(this.__zuzu_props, "value", value == null ? null : String(value));
          this.__zuzu_sync_radios();
          this.__zuzu_update_native();
          return this;
        }
        __zuzu_child_added(child) {
          if (child instanceof Radio) {
            this.__zuzu_sync_radios();
          }
        }
        __zuzu_sync_radios() {
          const selected = this.value();
          for (const radio of this.options()) {
            _setProp(
              radio.__zuzu_props,
              "checked",
              selected != null && String(radio.value()) === String(selected)
            );
          }
        }
        __zuzu_set_prop_silent(key, value) {
          super.__zuzu_set_prop_silent(key, value);
          if (key === "value") {
            this.__zuzu_sync_radios();
          }
        }
      };
      var Select = class extends Widget {
        options() {
          return _asArray(_getProp(this.__zuzu_props, "options", [])).slice();
        }
        add_option(option) {
          const options = this.options();
          options.push(option);
          _setProp(this.__zuzu_props, "options", options);
          this.__zuzu_update_native();
          return this;
        }
        clear_options() {
          _setProp(this.__zuzu_props, "options", []);
          this.__zuzu_update_native();
          return this;
        }
      };
      var Menu = class extends Widget {
        items() {
          return this.children();
        }
      };
      var MenuItem = class extends Widget {
      };
      var Button = class extends Widget {
      };
      var Separator = class extends Widget {
      };
      var Slider = class extends Widget {
      };
      var Progress = class extends Widget {
      };
      var Tabs = class extends Widget {
        constructor(props = {}) {
          super(props);
          this.__zuzu_sync_tabs();
        }
        tabs() {
          return this.children().filter((child) => child instanceof Tab);
        }
        selected(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "selected", null);
          }
          _setProp(this.__zuzu_props, "selected", value == null ? null : String(value));
          this.__zuzu_sync_tabs();
          this.__zuzu_update_native();
          return this;
        }
        selected_tab() {
          const selected = this.selected();
          return this.tabs().find((tab) => String(tab.value()) === String(selected)) || null;
        }
        __zuzu_child_added(child) {
          if (child instanceof Tab) {
            this.__zuzu_sync_tabs();
          }
        }
        __zuzu_sync_tabs() {
          const selected = this.selected();
          for (const tab of this.tabs()) {
            _setProp(
              tab.__zuzu_props,
              "selected",
              selected != null && String(tab.value()) === String(selected)
            );
          }
        }
      };
      var Tab = class extends Widget {
        selected(value) {
          if (arguments.length === 0) {
            return _asBool(_getProp(this.__zuzu_props, "selected", false));
          }
          _setProp(this.__zuzu_props, "selected", _asBool(value));
          const parent = this.parent();
          if (value && parent instanceof Tabs) {
            parent.selected(this.value());
          } else {
            this.__zuzu_update_native();
          }
          return this;
        }
      };
      var ListView = class extends Widget {
        items() {
          return _asArray(_getProp(this.__zuzu_props, "items", [])).slice();
        }
        selected_index(value) {
          if (arguments.length === 0) {
            return _getProp(this.__zuzu_props, "selected_index", null);
          }
          _setProp(
            this.__zuzu_props,
            "selected_index",
            value == null ? null : Number(value)
          );
          this.__zuzu_update_native();
          return this;
        }
        selected_item() {
          const index = this.selected_index();
          const items = this.items();
          return index == null ? null : items[Number(index)] ?? null;
        }
        add_item(item) {
          const items = this.items();
          items.push(item);
          _setProp(this.__zuzu_props, "items", items);
          this.__zuzu_update_native();
          return this;
        }
        clear_items() {
          _setProp(this.__zuzu_props, "items", []);
          _setProp(this.__zuzu_props, "selected_index", null);
          this.__zuzu_update_native();
          return this;
        }
        activate_index(index) {
          this.selected_index(index);
          this.emit("activate", index);
          return this;
        }
      };
      var TreeView = class extends Widget {
        constructor(props = {}) {
          super(props);
          this.__zuzu_expanded = /* @__PURE__ */ new Set();
          this.__zuzu_mark_initial_expanded(this.items(), []);
        }
        items() {
          return _asArray(_getProp(this.__zuzu_props, "items", [])).slice();
        }
        selected_path(value) {
          if (arguments.length === 0) {
            return _asArray(_getProp(this.__zuzu_props, "selected_path", [])).slice();
          }
          _setProp(this.__zuzu_props, "selected_path", _asArray(value).map(Number));
          this.__zuzu_update_native();
          return this;
        }
        selected_item() {
          return this.__zuzu_item_at_path(this.selected_path());
        }
        add_item(item) {
          const items = this.items();
          items.push(item);
          _setProp(this.__zuzu_props, "items", items);
          this.__zuzu_update_native();
          return this;
        }
        clear_items() {
          _setProp(this.__zuzu_props, "items", []);
          _setProp(this.__zuzu_props, "selected_path", []);
          this.__zuzu_expanded.clear();
          this.__zuzu_update_native();
          return this;
        }
        activate_path(path) {
          this.selected_path(path);
          this.emit("activate", path);
          return this;
        }
        expand_path(path) {
          this.__zuzu_expanded.add(this.__zuzu_path_key(path));
          this.__zuzu_update_native();
          this.emit("expand", path);
          return this;
        }
        collapse_path(path) {
          this.__zuzu_expanded.delete(this.__zuzu_path_key(path));
          this.__zuzu_update_native();
          this.emit("collapse", path);
          return this;
        }
        is_expanded(path) {
          return this.__zuzu_expanded.has(this.__zuzu_path_key(path));
        }
        __zuzu_gui_snapshot() {
          const snapshot = super.__zuzu_gui_snapshot();
          snapshot.props.expanded_paths = [...this.__zuzu_expanded].map(
            (key) => key.split(",").filter(Boolean).map(Number)
          );
          return snapshot;
        }
        __zuzu_item_at_path(path) {
          let items = this.items();
          let current = null;
          for (const rawIndex of _asArray(path)) {
            const index = Number(rawIndex);
            current = items[index] ?? null;
            if (current == null) {
              return null;
            }
            items = _itemChildren(current);
          }
          return current;
        }
        __zuzu_path_key(path) {
          return _asArray(path).map((part) => Number(part)).join(",");
        }
        __zuzu_mark_initial_expanded(items, prefix) {
          for (let i = 0; i < items.length; i++) {
            const path = [...prefix, i];
            const children = _itemChildren(items[i]);
            if (children.length > 0) {
              this.__zuzu_expanded.add(this.__zuzu_path_key(path));
              this.__zuzu_mark_initial_expanded(children, path);
            }
          }
        }
        __zuzu_set_expanded_silent(path, expanded) {
          const key = this.__zuzu_path_key(path);
          if (expanded) {
            this.__zuzu_expanded.add(key);
          } else {
            this.__zuzu_expanded.delete(key);
          }
        }
      };
      function _nativeDialogue(name2) {
        return function nativeDialogue(first, ...rest) {
          if (runtimePolicy2.gui && typeof runtimePolicy2.gui[name2] === "function") {
            return runtimePolicy2.gui[name2](first, ...rest);
          }
          return null;
        };
      }
      function _tagGuiType(klass, names) {
        Object.defineProperty(klass.prototype, "__zuzu_gui_type_name", {
          value: names[0],
          enumerable: false,
          configurable: false
        });
        Object.defineProperty(klass.prototype, "__zuzu_type_names", {
          value: names,
          enumerable: false,
          configurable: false
        });
      }
      for (const [klass, names] of [
        [Widget, ["Widget"]],
        [Window, ["Window", "Widget"]],
        [VBox, ["VBox", "Widget"]],
        [HBox, ["HBox", "Widget"]],
        [Frame, ["Frame", "Widget"]],
        [Label, ["Label", "Widget"]],
        [Text, ["Text", "Widget"]],
        [RichText, ["RichText", "Widget"]],
        [Image, ["Image", "Widget"]],
        [Input, ["Input", "Widget"]],
        [DatePicker, ["DatePicker", "Widget"]],
        [Checkbox, ["Checkbox", "Widget"]],
        [Radio, ["Radio", "Checkbox", "Widget"]],
        [RadioGroup, ["RadioGroup", "Widget"]],
        [Select, ["Select", "Widget"]],
        [Menu, ["Menu", "Widget"]],
        [MenuItem, ["MenuItem", "Widget"]],
        [Button, ["Button", "Widget"]],
        [Separator, ["Separator", "Widget"]],
        [Slider, ["Slider", "Widget"]],
        [Progress, ["Progress", "Widget"]],
        [Tabs, ["Tabs", "Widget"]],
        [Tab, ["Tab", "Widget"]],
        [ListView, ["ListView", "Widget"]],
        [TreeView, ["TreeView", "Widget"]]
      ]) {
        _tagGuiType(klass, names);
      }
      module2.exports = {
        Widget,
        Window,
        VBox,
        HBox,
        Frame,
        Label,
        Text,
        RichText,
        Image,
        Input,
        DatePicker,
        Checkbox,
        Radio,
        RadioGroup,
        Select,
        Menu,
        MenuItem,
        Button,
        Separator,
        Slider,
        Progress,
        Tabs,
        Tab,
        ListView,
        TreeView,
        Event,
        ListenerToken,
        meta,
        native_file_open: _nativeDialogue("fileOpen"),
        native_file_save: _nativeDialogue("fileSave"),
        native_directory_open: _nativeDialogue("directoryOpen"),
        native_directory_save: _nativeDialogue("directorySave"),
        native_alert: _nativeDialogue("alert"),
        native_confirm: _nativeDialogue("confirm"),
        native_prompt: _nativeDialogue("prompt"),
        native_colour_picker: _nativeDialogue("colourPicker"),
        __zuzu_set_runtime_policy(policy = {}) {
          runtimePolicy2 = {
            ...runtimePolicy2,
            ...policy
          };
          meta.backend = runtimePolicy2.host_name === "browser" ? "browser-dom" : "electron-dom";
        }
      };
    }
  });

  // modules/std/tui.js
  var require_tui = __commonJS({
    "modules/std/tui.js"(exports2, module2) {
      "use strict";
      var stdinBuffer = null;
      var denyFs = false;
      function hasProcess() {
        return typeof process !== "undefined" && process;
      }
      function nodeRequire2(name2) {
        if (typeof __require !== "function") {
          return null;
        }
        try {
          return __require(name2);
        } catch (_err) {
          return null;
        }
      }
      function ansi_esc() {
        return "\x1B";
      }
      function supports_ansi() {
        if (!hasProcess() || process.env.NO_COLOR) {
          return 0;
        }
        if (!process.stdout || !process.stdout.isTTY) {
          return 0;
        }
        if (process.platform === "win32") {
          return process.env.ANSICON || process.env.WT_SESSION || process.env.ConEmuANSI || process.env.TERM_PROGRAM ? 1 : 0;
        }
        const term = process.env.TERM || "";
        return term && term !== "dumb" ? 1 : 0;
      }
      function ansiCode(colour) {
        switch (String(colour || "").toLowerCase()) {
          case "black":
            return 30;
          case "red":
            return 31;
          case "green":
            return 32;
          case "yellow":
            return 33;
          case "blue":
            return 34;
          case "magenta":
            return 35;
          case "cyan":
            return 36;
          case "white":
            return 37;
          default:
            return null;
        }
      }
      function colour_text(text, colour) {
        const value = text == null ? "" : String(text);
        const code = ansiCode(colour);
        if (!code || !supports_ansi()) {
          return value;
        }
        return `${ansi_esc()}[${code}m${value}${ansi_esc()}[0m`;
      }
      function output(text) {
        if (hasProcess() && process.stdout && typeof process.stdout.write === "function") {
          process.stdout.write(String(text));
          return;
        }
        if (typeof console !== "undefined" && typeof console.log === "function") {
          console.log(String(text));
        }
      }
      function write(text, colour) {
        output(colour_text(text, colour));
        return null;
      }
      function write_line(text, colour) {
        output(`${colour_text(text, colour)}
`);
        return null;
      }
      function readStdinLine() {
        const fs = nodeRequire2("node:fs") || nodeRequire2("fs");
        if (!fs) {
          return null;
        }
        if (stdinBuffer == null) {
          try {
            stdinBuffer = fs.readFileSync(0, "utf8");
          } catch (_err) {
            stdinBuffer = "";
          }
        }
        if (stdinBuffer.length === 0) {
          return null;
        }
        const match = /^([^\n\r]*)(?:\r?\n|\r)?/.exec(stdinBuffer);
        const line = match ? match[1] : stdinBuffer;
        stdinBuffer = stdinBuffer.slice(match ? match[0].length : stdinBuffer.length);
        return line;
      }
      function readline(prompt = "", defaultValue = "", _completionCallback = null) {
        if (_completionCallback != null && typeof _completionCallback !== "function") {
          throw new Error("readline completion must be Function or null");
        }
        output(prompt == null ? "" : String(prompt));
        const line = readStdinLine();
        if (line == null || line === "") {
          return defaultValue == null ? "" : String(defaultValue);
        }
        return line;
      }
      function readline_supports_completion() {
        return 0;
      }
      function pathCompletions(text, directoryOnly) {
        if (denyFs) {
          return [];
        }
        const fs = nodeRequire2("node:fs") || nodeRequire2("fs");
        const path = nodeRequire2("node:path") || nodeRequire2("path");
        if (!fs || !path) {
          return [];
        }
        const raw = text == null ? "" : String(text);
        const sepMatch = /[/\\]$/u.test(raw);
        const dir = sepMatch ? raw : path.dirname(raw || ".");
        const base = sepMatch ? "" : path.basename(raw);
        const searchDir = dir && dir !== "." ? dir : ".";
        const visibleDir = dir && dir !== "." ? dir : "";
        let entries;
        try {
          entries = fs.readdirSync(searchDir, { withFileTypes: true });
        } catch (_err) {
          return [];
        }
        return entries.filter((entry) => entry.name.startsWith(base)).filter((entry) => !directoryOnly || entry.isDirectory()).map((entry) => {
          const prefix = visibleDir ? `${visibleDir}${path.sep}` : "";
          return `${prefix}${entry.name}${entry.isDirectory() ? path.sep : ""}`;
        }).sort();
      }
      function filename_completions(text) {
        return pathCompletions(text, false);
      }
      function directory_completions(text) {
        return pathCompletions(text, true);
      }
      var api = {
        ansi_esc,
        colour_text,
        directory_completions,
        filename_completions,
        readline,
        readline_supports_completion,
        supports_ansi,
        write,
        write_line
      };
      Object.defineProperty(api, "__zuzu_set_runtime_policy", {
        value(policy = {}) {
          denyFs = !!policy.deny_fs;
        },
        enumerable: false
      });
      module2.exports = api;
    }
  });

  // modules/std/internals.js
  var require_internals = __commonJS({
    "modules/std/internals.js"(exports2, module2) {
      "use strict";
      var { getCompiledSource } = require_execution_metadata();
      var taskRuntime2 = require_task();
      var frameProps = /* @__PURE__ */ new Map();
      var refIds = /* @__PURE__ */ new WeakMap();
      var scopeTrees = /* @__PURE__ */ new Map();
      var ZUZU_SKIP_BUILD = /* @__PURE__ */ Symbol.for("zuzu.skip_build");
      var refSeq = 1;
      var nodeFs;
      var nodeFsLoaded = false;
      var runtimePolicy2 = {
        load_module: null,
        builtin_class: null,
        to_String: null,
        to_Number: null,
        to_Boolean: null,
        to_Regexp: null,
        to_Regexp_with_flags: null
      };
      function setRuntimePolicy2(policy = {}) {
        runtimePolicy2 = {
          ...runtimePolicy2,
          ...policy
        };
      }
      function _thisModuleFilename() {
        return typeof __filename === "string" ? __filename : null;
      }
      function _nodeFs() {
        if (nodeFsLoaded) {
          return nodeFs;
        }
        nodeFsLoaded = true;
        if (typeof __require !== "function") {
          nodeFs = null;
          return nodeFs;
        }
        try {
          nodeFs = __require("node:fs");
        } catch (_err) {
          nodeFs = null;
        }
        return nodeFs;
      }
      function parseUserFrames() {
        const lines = String(new Error().stack || "").split("\n").slice(1);
        const frames = [];
        for (const line of lines) {
          const trimmed = line.trim();
          let match = trimmed.match(/^at\s+(.*?)\s+\((.+):(\d+):(\d+)\)$/);
          if (!match) {
            match = trimmed.match(/^at\s+(.+):(\d+):(\d+)$/);
            if (match) {
              match = [match[0], "", match[1], match[2], match[3]];
            }
          }
          if (!match) {
            continue;
          }
          const file = match[2];
          if (file.includes("<anonymous>") || file.startsWith("eval at ")) {
            continue;
          }
          const thisFile = _thisModuleFilename();
          if (thisFile != null && file === thisFile || /[\\/]extras[\\/]zuzu-js[\\/]lib[\\/]runtime\.js$/.test(file) || /[\\/]zuzu-js[\\/]lib[\\/]runtime\.js$/.test(file) || /[\\/]zuzu-browser\.js$/.test(file) || file.startsWith("node:") || file === "[stdin]") {
            continue;
          }
          frames.push({
            func: match[1] || "",
            file,
            line: Number(match[3]),
            col: Number(match[4])
          });
        }
        return frames;
      }
      function loadScopeTree(file) {
        if (scopeTrees.has(file)) {
          return scopeTrees.get(file);
        }
        let source = "";
        const compiled = getCompiledSource(file);
        if (compiled != null) {
          source = compiled;
        } else try {
          const fs = _nodeFs();
          if (!fs) {
            throw new Error("fs unavailable");
          }
          source = fs.readFileSync(file, "utf8");
        } catch (_err) {
          const fallback = {
            nodes: [{ id: 0, parent: null, startLine: 1, endLine: Number.MAX_SAFE_INTEGER }]
          };
          scopeTrees.set(file, fallback);
          return fallback;
        }
        const nodes = [
          { id: 0, parent: null, startLine: 1, endLine: Number.MAX_SAFE_INTEGER }
        ];
        const stack = [0];
        let line = 1;
        let mode = "code";
        let quote = "";
        let escaped = false;
        let atLineStart = true;
        let inPod = false;
        for (let i = 0; i < source.length; i++) {
          const ch = source[i];
          const next = source[i + 1] || "";
          if (ch === "\n") {
            line++;
            atLineStart = true;
            if (mode === "line-comment") {
              mode = "code";
            }
            continue;
          }
          if (inPod) {
            if (atLineStart && ch === "=") {
              const end = source.indexOf("\n", i);
              const rest = source.slice(i, end === -1 ? source.length : end);
              if (/^=cut\b/.test(rest)) {
                inPod = false;
              }
            }
            atLineStart = false;
            continue;
          }
          if (atLineStart && ch === "=") {
            const end = source.indexOf("\n", i);
            const rest = source.slice(i, end === -1 ? source.length : end);
            if (/^=\w+/.test(rest) && !/^=cut\b/.test(rest)) {
              inPod = true;
              atLineStart = false;
              continue;
            }
          }
          atLineStart = false;
          if (mode === "line-comment") {
            continue;
          }
          if (mode === "block-comment") {
            if (ch === "*" && next === "/") {
              mode = "code";
              i++;
            }
            continue;
          }
          if (mode === "string") {
            if (escaped) {
              escaped = false;
              continue;
            }
            if (ch === "\\") {
              escaped = true;
              continue;
            }
            if (ch === quote) {
              mode = "code";
            }
            continue;
          }
          if (ch === "/" && next === "/") {
            mode = "line-comment";
            i++;
            continue;
          }
          if (ch === "/" && next === "*") {
            mode = "block-comment";
            i++;
            continue;
          }
          if (ch === '"' || ch === "'" || ch === "`") {
            mode = "string";
            quote = ch;
            escaped = false;
            continue;
          }
          if (ch === "{") {
            const id = nodes.length;
            nodes.push({
              id,
              parent: stack[stack.length - 1],
              startLine: line,
              endLine: Number.MAX_SAFE_INTEGER
            });
            stack.push(id);
            continue;
          }
          if (ch === "}" && stack.length > 1) {
            const id = stack.pop();
            nodes[id].endLine = line;
          }
        }
        const tree = { nodes };
        scopeTrees.set(file, tree);
        return tree;
      }
      function scopePathForLocation(file, line) {
        const tree = loadScopeTree(file);
        let current = 0;
        let found = true;
        while (found) {
          found = false;
          for (let i = tree.nodes.length - 1; i >= 1; i--) {
            const node = tree.nodes[i];
            if (node.parent !== current) {
              continue;
            }
            if (node.startLine <= line && line <= node.endLine) {
              current = node.id;
              found = true;
              break;
            }
          }
        }
        const path = [];
        let nodeId = current;
        while (nodeId != null) {
          path.push(nodeId);
          nodeId = tree.nodes[nodeId].parent;
        }
        return path;
      }
      function contextAtDepth(depth = 0) {
        const frames = parseUserFrames();
        const frame = frames[depth];
        if (!frame) {
          return null;
        }
        const isVirtualBrowserPath = runtimePolicy2.host_name === "browser";
        const line = isVirtualBrowserPath ? frame.line - 2 : frame.line;
        return {
          activationKey: `file:${frame.file}`,
          scopePath: scopePathForLocation(frame.file, Math.max(1, line))
        };
      }
      function ensureFrame(activationKey, scopeId) {
        const key = `${activationKey}#${scopeId}`;
        if (!frameProps.has(key)) {
          frameProps.set(key, /* @__PURE__ */ new Map());
        }
        return frameProps.get(key);
      }
      function getFrame(activationKey, scopeId) {
        return frameProps.get(`${activationKey}#${scopeId}`);
      }
      function class_name(value) {
        if (value == null || typeof value !== "object") {
          return null;
        }
        return value.constructor && value.constructor.name ? value.constructor.name : null;
      }
      function classof(value) {
        if (value == null) {
          return null;
        }
        if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") {
          return null;
        }
        const builtinClass = typeof runtimePolicy2.builtin_class === "function" ? runtimePolicy2.builtin_class : () => null;
        if (Array.isArray(value)) {
          return builtinClass("Array") || value.constructor || null;
        }
        if (Object.prototype.toString.call(value) === "[object Set]") {
          return builtinClass("Set") || value.constructor || null;
        }
        if (value && value.constructor) {
          const ctor = value.constructor;
          const name2 = ctor.__zuzu_class_name || ctor.name || "";
          if (name2 === "Object") {
            return builtinClass("Dict") || ctor;
          }
          if (name2 === "ZuzuBag") {
            return builtinClass("Bag") || ctor;
          }
          return ctor;
        }
        if (typeof value === "function") {
          const source = Function.prototype.toString.call(value);
          if (/^\s*class\b/.test(source)) {
            return builtinClass("Class") || Function;
          }
          return builtinClass("Function") || Function;
        }
        return null;
      }
      function object_slots(value) {
        if (value == null || typeof value !== "object") {
          return null;
        }
        const out = {};
        for (const key of Object.keys(value)) {
          if (!key.startsWith("_")) {
            out[key] = value[key];
          }
        }
        Object.defineProperty(
          out,
          "get",
          {
            value(key) {
              const id = String(key);
              return Object.prototype.hasOwnProperty.call(out, id) ? out[id] : null;
            },
            enumerable: false
          }
        );
        Object.defineProperty(
          out,
          "keys",
          {
            value() {
              return Object.keys(out);
            },
            enumerable: false
          }
        );
        Object.defineProperty(
          out,
          "sorted_keys",
          {
            value() {
              return Object.keys(out).sort();
            },
            enumerable: false
          }
        );
        return out;
      }
      function ansi_esc() {
        return "\x1B";
      }
      function ref_id(value) {
        if (value == null || typeof value !== "object" && typeof value !== "function") {
          return null;
        }
        if (!refIds.has(value)) {
          refIds.set(value, `ref:${refSeq++}`);
        }
        return refIds.get(value);
      }
      function make_instance(klass, slots = null) {
        if (typeof klass !== "function" || typeof klass.__zuzu_class_name !== "string") {
          throw new Error("make_instance expects a user class");
        }
        if (slots == null) {
          return new klass(ZUZU_SKIP_BUILD);
        }
        if (typeof slots !== "object" || Array.isArray(slots)) {
          throw new Error("make_instance slot values must be Dict");
        }
        return new klass(ZUZU_SKIP_BUILD, slots);
      }
      function currentUserFile() {
        const frame = parseUserFrames()[0];
        return frame && frame.file ? frame.file : null;
      }
      function moduleExportKeys(loaded) {
        return Reflect.ownKeys(Object(loaded)).filter((key) => typeof key === "string").filter((key) => !key.startsWith("__zuzu_"));
      }
      function load_module(moduleName, symbolName = null) {
        if (arguments.length < 1 || arguments.length > 2) {
          throw new Error("load_module expects 1 to 2 arguments");
        }
        if (typeof moduleName !== "string") {
          throw new Error("load_module module must be String");
        }
        if (symbolName != null && typeof symbolName !== "string") {
          throw new Error("load_module symbol must be String");
        }
        if (typeof runtimePolicy2.load_module !== "function") {
          throw new Error("load_module is unavailable in this runtime");
        }
        const loaded = runtimePolicy2.load_module(moduleName, currentUserFile());
        if (symbolName != null) {
          if (!Object.prototype.hasOwnProperty.call(Object(loaded), symbolName)) {
            throw new Error(`Module '${moduleName}' has no export '${symbolName}'`);
          }
          return loaded[symbolName];
        }
        const out = {};
        for (const key of moduleExportKeys(loaded)) {
          out[key] = loaded[key];
        }
        return out;
      }
      function requirePolicyFunction(name2) {
        const fn2 = runtimePolicy2[name2];
        if (typeof fn2 !== "function") {
          throw new Error(`${name2} is unavailable in this runtime`);
        }
        return fn2;
      }
      function to_String(value) {
        return requirePolicyFunction("to_String")(value);
      }
      function to_Number(value) {
        return requirePolicyFunction("to_Number")(value);
      }
      function to_Boolean(value) {
        return requirePolicyFunction("to_Boolean")(value);
      }
      function to_Regexp(value) {
        return requirePolicyFunction("to_Regexp")(value);
      }
      function to_Regexp_with_flags(value, flags) {
        return requirePolicyFunction("to_Regexp_with_flags")(value, flags);
      }
      function validateKey(key) {
        if (typeof key !== "string") {
          throw new Error("getprop|setprop key must be String");
        }
      }
      function setprop(key, value) {
        validateKey(key);
        const ctx = contextAtDepth(0);
        if (!ctx) {
          return value;
        }
        ensureFrame(ctx.activationKey, ctx.scopePath[0]).set(key, value);
        return value;
      }
      function getprop(key) {
        validateKey(key);
        const ctx = contextAtDepth(0);
        if (!ctx) {
          return null;
        }
        for (const scopeId of ctx.scopePath) {
          const frame = getFrame(ctx.activationKey, scopeId);
          if (frame && frame.has(key)) {
            return frame.get(key);
          }
        }
        return null;
      }
      function setupperprop(level, key, value) {
        validateKey(key);
        const ctx = contextAtDepth(Number(level ?? 0));
        if (!ctx) {
          return value;
        }
        ensureFrame(ctx.activationKey, ctx.scopePath[0]).set(key, value);
        return value;
      }
      function getupperprop(level, key) {
        validateKey(key);
        const ctx = contextAtDepth(Number(level ?? 0));
        if (!ctx) {
          return null;
        }
        for (const scopeId of ctx.scopePath) {
          const frame = getFrame(ctx.activationKey, scopeId);
          if (frame && frame.has(key)) {
            return frame.get(key);
          }
        }
        return null;
      }
      var api = {
        active_task_count: taskRuntime2.activeCount,
        ansi_esc,
        class_name,
        classof,
        clear_task_trace: taskRuntime2.clearTrace,
        getprop,
        getupperprop,
        load_module,
        make_instance,
        object_slots,
        ref_id,
        setprop,
        setupperprop,
        shutdown_tasks: taskRuntime2.shutdown,
        task_trace: taskRuntime2.taskTrace,
        to_Boolean,
        to_Number,
        to_Regexp,
        to_Regexp_with_flags,
        to_String
      };
      Object.defineProperty(api, "__zuzu_set_runtime_policy", {
        value: setRuntimePolicy2,
        enumerable: false,
        configurable: true,
        writable: true
      });
      module2.exports = api;
    }
  });

  // modules/std/net/url.js
  var require_url = __commonJS({
    "modules/std/net/url.js"(exports2, module2) {
      "use strict";
      function _str(value, fallback = "") {
        if (value == null) {
          return fallback;
        }
        return String(value);
      }
      function _dict(source = {}) {
        const out = { ...source };
        Object.defineProperties(out, {
          has: {
            value(key) {
              return Object.prototype.hasOwnProperty.call(out, String(key)) ? 1 : 0;
            },
            enumerable: false
          },
          exists: {
            value(key) {
              return out.has(key);
            },
            enumerable: false
          },
          get: {
            value(key, fallback = null) {
              return out.has(key) ? out[String(key)] : fallback;
            },
            enumerable: false
          }
        });
        return out;
      }
      function escape(value) {
        return encodeURIComponent(_str(value));
      }
      function unescape(value) {
        return decodeURIComponent(_str(value));
      }
      function parse(value) {
        const urlText = _str(value);
        const parsed = new URL(urlText, "http://localhost");
        const out = _dict({
          url: parsed.href,
          scheme: parsed.protocol.replace(/:$/u, "") || null,
          authority: parsed.host || null,
          userinfo: null,
          host: parsed.hostname || null,
          port: parsed.port || null,
          path: parsed.pathname || "",
          query: parsed.search.replace(/^\?/u, "") || null,
          fragment: parsed.hash.replace(/^#/u, "") || null,
          query_params: _dict({})
        });
        if (parsed.username || parsed.password) {
          out.userinfo = parsed.username;
          if (parsed.password) {
            out.userinfo += `:${parsed.password}`;
          }
        }
        for (const [key, item] of parsed.searchParams.entries()) {
          out.query_params[key] = item;
        }
        return out;
      }
      function _templateVar(values, name2) {
        if (values[name2] == null) {
          return "";
        }
        return encodeURIComponent(_str(values[name2]));
      }
      function _templateQuery(values, namesText) {
        const names = String(namesText).split(/\s*,\s*/u).filter(Boolean);
        const parts = [];
        for (const name2 of names) {
          if (values[name2] == null) {
            continue;
          }
          const key = encodeURIComponent(name2);
          const val = encodeURIComponent(_str(values[name2]));
          parts.push(`${key}=${val}`);
        }
        return parts.length > 0 ? `?${parts.join("&")}` : "";
      }
      function fill_template(template, values) {
        const source = _str(template);
        const data = values && typeof values === "object" && !Array.isArray(values) ? values : {};
        return source.replace(/\{\?([^}]+)\}/gu, (_, names) => _templateQuery(data, names)).replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/gu, (_, name2) => _templateVar(data, name2));
      }
      module2.exports = {
        escape,
        unescape,
        parse,
        fill_template
      };
    }
  });

  // ../../../../../tmp/zuzu-browser-build.WePoiO/browser-stdlib.generated.js
  var require_browser_stdlib_generated = __commonJS({
    "../../../../../tmp/zuzu-browser-build.WePoiO/browser-stdlib.generated.js"(exports2, module2) {
      "use strict";
      function createBrowserStdlib2() {
        const jsModules = /* @__PURE__ */ Object.create(null);
        jsModules["/modules/javascript.js"] = require_javascript();
        jsModules["/modules/std/string.js"] = require_string();
        jsModules["/modules/std/string/base64.js"] = require_base64();
        jsModules["/modules/std/time.js"] = require_time();
        jsModules["/modules/std/marshal.js"] = require_marshal();
        jsModules["/modules/std/task.js"] = require_task();
        jsModules["/modules/std/worker.js"] = require_worker();
        jsModules["/modules/std/secure.js"] = require_secure();
        jsModules["/modules/std/data/json.js"] = require_json();
        jsModules["/modules/std/data/yaml.js"] = require_yaml();
        jsModules["/modules/std/data/csv.js"] = require_csv();
        jsModules["/modules/std/data/xml.js"] = require_xml();
        jsModules["/modules/std/digest/md5.js"] = require_md5();
        jsModules["/modules/std/digest/sha.js"] = require_sha();
        jsModules["/modules/std/net/http.js"] = require_http();
        jsModules["/modules/std/math.js"] = require_math();
        jsModules["/modules/std/math/bignum.js"] = require_bignum();
        jsModules["/modules/std/eval.js"] = require_eval();
        jsModules["/modules/std/gui/objects.js"] = require_objects();
        jsModules["/modules/std/tui.js"] = require_tui();
        jsModules["/modules/std/internals.js"] = require_internals();
        jsModules["/modules/std/net/url.js"] = require_url();
        const virtualFiles = /* @__PURE__ */ Object.create(null);
        virtualFiles["/modules/std/colour.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/colour - Colour parsing helpers.\n\n=head1 SYNOPSIS\n\n  from std/colour import parse_colour;\n\n  say( parse_colour("red") );  # #ff0000\n  say( parse_colour("#abc") ); # #aabbcc\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nC<parse_colour> accepts three- and six-digit hexadecimal colours and the\nCSS3 extended colour keywords. It returns a lowercase six-digit\nhexadecimal colour string.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item C<< parse_colour(String x) >>\n\nParameters: C<x> is a CSS colour keyword or a three- or six-digit\nhexadecimal colour string. Returns: C<String>. Returns the normalized\nlowercase C<#rrggbb> colour string, or throws if C<x> is not recognised.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/colour >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import trim;\n\nconst _COLOUR_KEYWORDS := {\n	aliceblue: "#f0f8ff",\n	antiquewhite: "#faebd7",\n	aqua: "#00ffff",\n	aquamarine: "#7fffd4",\n	azure: "#f0ffff",\n	beige: "#f5f5dc",\n	bisque: "#ffe4c4",\n	black: "#000000",\n	blanchedalmond: "#ffebcd",\n	blue: "#0000ff",\n	blueviolet: "#8a2be2",\n	brown: "#a52a2a",\n	burlywood: "#deb887",\n	cadetblue: "#5f9ea0",\n	chartreuse: "#7fff00",\n	chocolate: "#d2691e",\n	coral: "#ff7f50",\n	cornflowerblue: "#6495ed",\n	cornsilk: "#fff8dc",\n	crimson: "#dc143c",\n	cyan: "#00ffff",\n	darkblue: "#00008b",\n	darkcyan: "#008b8b",\n	darkgoldenrod: "#b8860b",\n	darkgray: "#a9a9a9",\n	darkgreen: "#006400",\n	darkgrey: "#a9a9a9",\n	darkkhaki: "#bdb76b",\n	darkmagenta: "#8b008b",\n	darkolivegreen: "#556b2f",\n	darkorange: "#ff8c00",\n	darkorchid: "#9932cc",\n	darkred: "#8b0000",\n	darksalmon: "#e9967a",\n	darkseagreen: "#8fbc8f",\n	darkslateblue: "#483d8b",\n	darkslategray: "#2f4f4f",\n	darkslategrey: "#2f4f4f",\n	darkturquoise: "#00ced1",\n	darkviolet: "#9400d3",\n	deeppink: "#ff1493",\n	deepskyblue: "#00bfff",\n	dimgray: "#696969",\n	dimgrey: "#696969",\n	dodgerblue: "#1e90ff",\n	firebrick: "#b22222",\n	floralwhite: "#fffaf0",\n	forestgreen: "#228b22",\n	fuchsia: "#ff00ff",\n	gainsboro: "#dcdcdc",\n	ghostwhite: "#f8f8ff",\n	gold: "#ffd700",\n	goldenrod: "#daa520",\n	gray: "#808080",\n	green: "#008000",\n	greenyellow: "#adff2f",\n	grey: "#808080",\n	honeydew: "#f0fff0",\n	hotpink: "#ff69b4",\n	indianred: "#cd5c5c",\n	indigo: "#4b0082",\n	ivory: "#fffff0",\n	khaki: "#f0e68c",\n	lavender: "#e6e6fa",\n	lavenderblush: "#fff0f5",\n	lawngreen: "#7cfc00",\n	lemonchiffon: "#fffacd",\n	lightblue: "#add8e6",\n	lightcoral: "#f08080",\n	lightcyan: "#e0ffff",\n	lightgoldenrodyellow: "#fafad2",\n	lightgray: "#d3d3d3",\n	lightgreen: "#90ee90",\n	lightgrey: "#d3d3d3",\n	lightpink: "#ffb6c1",\n	lightsalmon: "#ffa07a",\n	lightseagreen: "#20b2aa",\n	lightskyblue: "#87cefa",\n	lightslategray: "#778899",\n	lightslategrey: "#778899",\n	lightsteelblue: "#b0c4de",\n	lightyellow: "#ffffe0",\n	lime: "#00ff00",\n	limegreen: "#32cd32",\n	linen: "#faf0e6",\n	magenta: "#ff00ff",\n	maroon: "#800000",\n	mediumaquamarine: "#66cdaa",\n	mediumblue: "#0000cd",\n	mediumorchid: "#ba55d3",\n	mediumpurple: "#9370db",\n	mediumseagreen: "#3cb371",\n	mediumslateblue: "#7b68ee",\n	mediumspringgreen: "#00fa9a",\n	mediumturquoise: "#48d1cc",\n	mediumvioletred: "#c71585",\n	midnightblue: "#191970",\n	mintcream: "#f5fffa",\n	mistyrose: "#ffe4e1",\n	moccasin: "#ffe4b5",\n	navajowhite: "#ffdead",\n	navy: "#000080",\n	oldlace: "#fdf5e6",\n	olive: "#808000",\n	olivedrab: "#6b8e23",\n	orange: "#ffa500",\n	orangered: "#ff4500",\n	orchid: "#da70d6",\n	palegoldenrod: "#eee8aa",\n	palegreen: "#98fb98",\n	paleturquoise: "#afeeee",\n	palevioletred: "#db7093",\n	papayawhip: "#ffefd5",\n	peachpuff: "#ffdab9",\n	peru: "#cd853f",\n	pink: "#ffc0cb",\n	plum: "#dda0dd",\n	powderblue: "#b0e0e6",\n	purple: "#800080",\n	red: "#ff0000",\n	rosybrown: "#bc8f8f",\n	royalblue: "#4169e1",\n	saddlebrown: "#8b4513",\n	salmon: "#fa8072",\n	sandybrown: "#f4a460",\n	seagreen: "#2e8b57",\n	seashell: "#fff5ee",\n	sienna: "#a0522d",\n	silver: "#c0c0c0",\n	skyblue: "#87ceeb",\n	slateblue: "#6a5acd",\n	slategray: "#708090",\n	slategrey: "#708090",\n	snow: "#fffafa",\n	springgreen: "#00ff7f",\n	steelblue: "#4682b4",\n	tan: "#d2b48c",\n	teal: "#008080",\n	thistle: "#d8bfd8",\n	tomato: "#ff6347",\n	turquoise: "#40e0d0",\n	violet: "#ee82ee",\n	wheat: "#f5deb3",\n	white: "#ffffff",\n	whitesmoke: "#f5f5f5",\n	yellow: "#ffff00",\n	yellowgreen: "#9acd32",\n};\n\nfunction parse_colour ( String x ) {\n	let text := lc( trim(x) );\n\n	if ( text ~ /^#[0-9a-f]{6}$/ ) {\n		return text;\n	}\n\n	let short := text ~ /^#([0-9a-f])([0-9a-f])([0-9a-f])$/;\n	if ( short ) {\n		return "#"\n			_ short[1] _ short[1]\n			_ short[2] _ short[2]\n			_ short[3] _ short[3];\n	}\n\n	if ( _COLOUR_KEYWORDS.exists(text) ) {\n		return _COLOUR_KEYWORDS.get(text);\n	}\n\n	die `Invalid colour: ${x}`;\n}\n';
        virtualFiles["/modules/std/result.zzm"] = "=encoding utf8\n\n=head1 NAME\n\nstd/result - A simple Result object for explicit success and failure values.\n\n=head1 SYNOPSIS\n\n  from std/result import Result;\n\n  let r := Result.ok(42);\n\n  if ( r.is_ok() ) {\n    say r.unwrap();\n  }\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nC<Result> is a small, subclassable object modelled on a simplified version\nof Rust's C<Result> concept. It is useful when a function, task, or worker\nwants to return an explicit success or failure value without throwing an\nexception.\n\nIt is a normal ZuzuScript class. Workers do not require C<Result>; any value\nsupported by C<std/marshal> may be returned.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<Result>\n\nContainer for either an ok value or an error value.\n\n=over\n\n=item C<< Result.ok(value) >>\n\nParameters: C<value> is any success value. Returns: C<Result>. Creates an\nok result wrapping C<value>.\n\n=item C<< Result.err(error) >>\n\nParameters: C<error> is any error value. Returns: C<Result>. Creates an\nerror result wrapping C<error>.\n\n=item C<< result.is_ok() >>\n\nParameters: none. Returns: C<Boolean>. Returns true when the result is an\nok value.\n\n=item C<< result.is_err() >>\n\nParameters: none. Returns: C<Boolean>. Returns true when the result is an\nerror value.\n\n=item C<< result.value() >>\n\nParameters: none. Returns: value. Returns the stored ok value, or\nC<null> for an error result.\n\n=item C<< result.error() >>\n\nParameters: none. Returns: value. Returns the stored error value, or\nC<null> for an ok result.\n\n=item C<< result.unwrap() >>\n\nParameters: none. Returns: value. Returns the ok value, or throws if the\nresult is an error.\n\n=item C<< result.unwrap_err() >>\n\nParameters: none. Returns: value. Returns the error value, or throws if\nthe result is ok.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/result >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nclass Result {\n	let Boolean _is_ok := true;\n	let _value := null;\n	let _error := null;\n\n	static method ok ( value ) {\n		return new self(\n			_is_ok: true,\n			_value: value,\n			_error: null,\n		);\n	}\n\n	static method err ( error ) {\n		return new self(\n			_is_ok: false,\n			_value: null,\n			_error: error,\n		);\n	}\n\n	method is_ok () {\n		return _is_ok;\n	}\n\n	method is_err () {\n		return not _is_ok;\n	}\n\n	method value () {\n		return _value;\n	}\n\n	method error () {\n		return _error;\n	}\n\n	method unwrap () {\n		if ( _is_ok ) {\n			return _value;\n		}\n\n		die `called Result.unwrap() on an err value: ${_error}`;\n	}\n\n	method unwrap_err () {\n		if ( not _is_ok ) {\n			return _error;\n		}\n\n		die `called Result.unwrap_err() on an ok value: ${_value}`;\n	}\n}\n";
        virtualFiles["/modules/std/string/quoted_printable.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/string/quoted_printable - Quoted-printable encoders and decoders.\n\n=head1 SYNOPSIS\n\n  from std/string/quoted_printable import encode, decode;\n\n  let raw := to_binary( "Hello, world!\\r\\n" );\n\n  let text := encode(raw);\n  let bytes := decode(text);\n\n  let binary_text := encode(raw, binary: true);\n  let short_lines := encode(raw, line_length: 40, newline: "\\n");\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides quoted-printable encoding and decoding helpers for\nRFC 2045-style byte transport. Encoding returns ASCII C<String> text.\nDecoding returns a C<BinaryString>, because quoted-printable is a byte\ntransfer encoding rather than a Unicode text format.\n\nThe C<binary> option controls how input line break bytes are encoded.\nIn the default non-binary mode, CRLF, CR, and LF bytes are normalized to\nthe configured C<newline> string. In binary mode, CR and LF bytes are\nencoded as C<=0D> and C<=0A>.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item * C<encode(BinaryString bytes, ... PairList options)>\n\nParameters: C<bytes> is binary input data and C<options> controls\nencoding. Returns: C<String>. Encodes C<bytes> as quoted-printable ASCII\ntext.\n\n=item * C<decode(String text, ... PairList options)>\n\nParameters: C<text> is quoted-printable text and C<options> controls\nstrictness. Returns: C<BinaryString>. Decodes quoted-printable text into\nbytes.\n\n=back\n\n=head1 OPTIONS\n\n=over\n\n=item * C<line_length>\n\nMaximum encoded line length. Defaults to C<76> and must be at least\nC<4>.\n\n=item * C<newline>\n\nOutput newline for hard line breaks and encoded soft breaks. Defaults\nto CRLF.\n\n=item * C<binary>\n\nWhen true, encode CR and LF bytes as C<=0D> and C<=0A>. Defaults to\nfalse.\n\n=item * C<strict>\n\nWhen true, malformed quoted-printable escape sequences throw during\ndecoding. Non-strict decoding preserves malformed escape text\nliterally.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/string/quoted_printable >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\n\nlet encode := null;\nlet decode := null;\n\n{\n	from std/string import chr, index, ord, substr;\n	from std/string/base64 import\n		encode as _base64_encode,\n		decode as _base64_decode;\n\n	let _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\n		_ "abcdefghijklmnopqrstuvwxyz0123456789+/";\n	let _HEX := "0123456789ABCDEF";\n\n	function _div_floor ( Number n, Number d ) {\n		return floor( n / d );\n	}\n\n	function _mod ( Number n, Number d ) {\n		return n - _div_floor( n, d ) * d;\n	}\n\n	function _bytes_to_binary ( Array bytes ) {\n		let out := "";\n		let i := 0;\n		let n := bytes.length();\n\n		while ( i < n ) {\n			let b0 := bytes[i];\n			let b1 := null;\n			let b2 := null;\n			if ( i + 1 < n ) {\n				b1 := bytes[i + 1];\n			}\n			if ( i + 2 < n ) {\n				b2 := bytes[i + 2];\n			}\n\n			let c0 := _div_floor( b0, 4 );\n			let c1 := _mod( b0, 4 ) * 16;\n			let c2 := 64;\n			let c3 := 64;\n\n			if ( not( b1 == null ) ) {\n				c1 += _div_floor( b1, 16 );\n				c2 := _mod( b1, 16 ) * 4;\n				if ( not( b2 == null ) ) {\n					c2 += _div_floor( b2, 64 );\n					c3 := _mod( b2, 64 );\n				}\n			}\n\n			out _= substr( _B64_ALPHABET, c0, 1 );\n			out _= substr( _B64_ALPHABET, c1, 1 );\n			out _= c2 == 64 ? "=" : substr( _B64_ALPHABET, c2, 1 );\n			out _= c3 == 64 ? "=" : substr( _B64_ALPHABET, c3, 1 );\n			i += 3;\n		}\n\n		return _base64_decode(out);\n	}\n\n	function _binary_to_bytes ( BinaryString raw ) {\n		let b64 := _base64_encode(raw);\n		let out := [];\n		let i := 0;\n		let n := length b64;\n\n		while ( i < n ) {\n			let c0 := index( _B64_ALPHABET, substr( b64, i, 1 ) );\n			let c1 := index( _B64_ALPHABET, substr( b64, i + 1, 1 ) );\n			let ch2 := substr( b64, i + 2, 1 );\n			let ch3 := substr( b64, i + 3, 1 );\n			let c2 := -1;\n			let c3 := -1;\n			if ( ch2 ne "=" ) {\n				c2 := index( _B64_ALPHABET, ch2 );\n			}\n			if ( ch3 ne "=" ) {\n				c3 := index( _B64_ALPHABET, ch3 );\n			}\n\n			out.push( c0 * 4 + _div_floor( c1, 16 ) );\n			if ( c2 >= 0 ) {\n				out.push( _mod( c1, 16 ) * 16 + _div_floor( c2, 4 ) );\n			}\n			if ( c3 >= 0 ) {\n				out.push( _mod( c2, 4 ) * 64 + c3 );\n			}\n\n			i += 4;\n		}\n\n		return out;\n	}\n\n	function _parse_options ( PairList options ) {\n		let line_length := 76;\n		let newline := "\\r\\n";\n		let binary := false;\n		let strict := false;\n\n		for ( let option in options.enumerate() ) {\n			let key := option.key;\n			let value := option.value;\n\n			if ( key eq "line_length" ) {\n				line_length := value;\n			}\n			else if ( key eq "newline" ) {\n				newline := value;\n			}\n			else if ( key eq "binary" ) {\n				binary := value;\n			}\n			else if ( key eq "strict" ) {\n				strict := value;\n			}\n			else {\n				die `quoted_printable option \'${key}\' is not supported`;\n			}\n		}\n\n		if ( not( line_length instanceof Number ) ) {\n			die "quoted_printable line_length option expects Number";\n		}\n		if ( line_length < 4 ) {\n			die "quoted_printable line_length option must be at least 4";\n		}\n		if ( not( newline instanceof String ) ) {\n			die "quoted_printable newline option expects String";\n		}\n		if ( not( binary instanceof Boolean ) ) {\n			die "quoted_printable binary option expects Boolean";\n		}\n		if ( not( strict instanceof Boolean ) ) {\n			die "quoted_printable strict option expects Boolean";\n		}\n\n		return {\n			line_length: int(line_length),\n			newline: newline,\n			binary: binary,\n			strict: strict,\n		};\n	}\n\n	function _is_safe_literal ( Number b ) {\n		return ( b >= 33 and b <= 60 ) or ( b >= 62 and b <= 126 );\n	}\n\n	function _byte_to_hex_token ( Number b ) {\n		return "="\n			_ substr( _HEX, _div_floor( b, 16 ), 1 )\n			_ substr( _HEX, _mod( b, 16 ), 1 );\n	}\n\n	function _simple_token_length ( Number b, Boolean final_byte ) {\n		if ( ( b == 9 or b == 32 ) and not final_byte ) {\n			return 1;\n		}\n		if ( _is_safe_literal(b) ) {\n			return 1;\n		}\n		return 3;\n	}\n\n	function _space_tab_needs_escape (\n		Array bytes,\n		Number i,\n		Number column,\n		Number line_length,\n	) {\n		let n := bytes.length();\n		if ( i + 1 >= n ) {\n			return true;\n		}\n\n		let j := i + 1;\n		while ( j < n and ( bytes[j] == 9 or bytes[j] == 32 ) ) {\n			j++;\n		}\n		if ( j >= n ) {\n			return true;\n		}\n\n		let next_is_final := i + 2 >= n;\n		let next_len := _simple_token_length( bytes[i + 1], next_is_final );\n		let max := next_is_final ? line_length : line_length - 1;\n		return column + 1 + next_len > max;\n	}\n\n	function _token_for_byte (\n		Array bytes,\n		Number i,\n		Number column,\n		Number line_length,\n	) {\n		let b := bytes[i];\n\n		if ( b == 9 or b == 32 ) {\n			if ( _space_tab_needs_escape( bytes, i, column, line_length ) ) {\n				return _byte_to_hex_token(b);\n			}\n			return chr(b);\n		}\n\n		if ( _is_safe_literal(b) ) {\n			return chr(b);\n		}\n\n		return _byte_to_hex_token(b);\n	}\n\n	function _emit_token (\n		String out,\n		Number column,\n		String token,\n		Boolean more_after,\n		Number line_length,\n		String newline,\n	) {\n		let max := more_after ? line_length - 1 : line_length;\n		let updated_out := out;\n		let updated_column := column;\n\n		if ( updated_column > 0 and updated_column + ( length token ) > max ) {\n			updated_out _= "=" _ newline;\n			updated_column := 0;\n		}\n\n		updated_out _= token;\n		updated_column += length token;\n\n		return [ updated_out, updated_column ];\n	}\n\n	function _encode_segment (\n		Array bytes,\n		Number line_length,\n		String newline,\n	) {\n		let out := "";\n		let column := 0;\n		let i := 0;\n		let n := bytes.length();\n\n		while ( i < n ) {\n			let token := _token_for_byte( bytes, i, column, line_length );\n			let emitted := _emit_token(\n				out,\n				column,\n				token,\n				i + 1 < n,\n				line_length,\n				newline,\n			);\n			out := emitted[0];\n			column := emitted[1];\n			i++;\n		}\n\n		return out;\n	}\n\n	function _encode_text_bytes (\n		Array bytes,\n		Number line_length,\n		String newline,\n	) {\n		let out := "";\n		let line := [];\n		let i := 0;\n		let n := bytes.length();\n\n		while ( i < n ) {\n			let b := bytes[i];\n			if ( b == 13 or b == 10 ) {\n				out _= _encode_segment( line, line_length, newline );\n				out _= newline;\n				line := [];\n\n				if ( b == 13 and i + 1 < n and bytes[i + 1] == 10 ) {\n					i++;\n				}\n			}\n			else {\n				line.push(b);\n			}\n\n			i++;\n		}\n\n		out _= _encode_segment( line, line_length, newline );\n		return out;\n	}\n\n	function _hex_value ( String ch ) {\n		let cp := ord(ch);\n		if ( cp >= 48 and cp <= 57 ) {\n			return cp - 48;\n		}\n		if ( cp >= 65 and cp <= 70 ) {\n			return cp - 55;\n		}\n		if ( cp >= 97 and cp <= 102 ) {\n			return cp - 87;\n		}\n		return -1;\n	}\n\n	function _decode_text_bytes ( String text, Boolean strict ) {\n		let out := [];\n		let i := 0;\n		let n := length text;\n\n		while ( i < n ) {\n			let ch := substr( text, i, 1 );\n			let cp := ord( text, i );\n\n			if ( cp > 127 ) {\n				die "quoted_printable.decode rejects non-ASCII input";\n			}\n\n			if ( ch eq "=" ) {\n				if ( i + 1 >= n ) {\n					die "malformed quoted-printable escape" if strict;\n					out.push(61);\n					i++;\n					next;\n				}\n\n				let ch1 := substr( text, i + 1, 1 );\n				if ( ch1 eq "\\r" ) {\n					if ( i + 2 < n and substr( text, i + 2, 1 ) eq "\\n" ) {\n						i += 3;\n					}\n					else {\n						i += 2;\n					}\n					next;\n				}\n				if ( ch1 eq "\\n" ) {\n					i += 2;\n					next;\n				}\n\n				if ( i + 2 < n ) {\n					let hi := _hex_value(ch1);\n					let lo := _hex_value( substr( text, i + 2, 1 ) );\n					if ( hi >= 0 and lo >= 0 ) {\n						out.push( hi * 16 + lo );\n						i += 3;\n						next;\n					}\n				}\n\n				die "malformed quoted-printable escape" if strict;\n				out.push(61);\n				i++;\n				next;\n			}\n\n			out.push(cp);\n			i++;\n		}\n\n		return out;\n	}\n\n	encode := function ( BinaryString bytes, ... PairList options ) {\n		let opts := _parse_options(options);\n		let raw := _binary_to_bytes(bytes);\n\n		if ( opts{binary} ) {\n			return _encode_segment(\n				raw,\n				opts{line_length},\n				opts{newline},\n			);\n		}\n\n		return _encode_text_bytes(\n			raw,\n			opts{line_length},\n			opts{newline},\n		);\n	};\n\n	decode := function ( String text, ... PairList options ) {\n		let opts := _parse_options(options);\n		return _bytes_to_binary( _decode_text_bytes( text, opts{strict} ) );\n	};\n}\n';
        virtualFiles["/modules/std/gui.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/gui - User-facing GUI constructor helpers.\n\n=head1 SYNOPSIS\n\n  from std/gui import *;\n\n  let w := Window(\n  	title: "Demo",\n  	VBox(\n  		Label( text: "Name:" ),\n  		Input( id: "name" ),\n  		Button( text: "OK", id: "submit" ),\n  	),\n  );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Electron.\nIt is not supported by zuzu-js on Node. It is partially supported by\nzuzu-js in the browser: core GUI and widget lifecycle coverage passes,\nbut filesystem-backed file and directory dialogue coverage is unsupported.\n\n=head1 DESCRIPTION\n\nThis module provides thin constructor helpers over C<std/gui/objects>.\nHost runtimes expose the shared widget, object tree, event, and window\nlifecycle APIs when GUI support is available. It also re-exports\nbackend-native file and directory dialogue hooks for C<std/gui/dialogue>.\n\nThe module exports C<EM>, the standard UI font height in logical\npixels, derived from C<std/gui/objects> metadata.\n\n=head1 EXPORTS\n\n=head2 Constants\n\n=over\n\n=item C<EM>\n\nType: C<Number>. Standard UI font height in logical pixels.\n\n=item C<GUI_XML_NS>\n\nType: C<String>. XML namespace URI used by GUI XML serialization and\nparsing.\n\n=back\n\n=head2 Functions\n\n=over\n\n=item C<< Window(... PairList p, Array c) >>, C<< VBox(... PairList p, Array c) >>, C<< HBox(... PairList p, Array c) >>, C<< Frame(... PairList p, Array c) >>\n\nParameters: C<p> are widget properties and C<c> contains child widgets.\nReturns: widget object. Constructs window and layout widgets.\n\n=item C<< Label(... PairList p, Array c) >>, C<< Text(... PairList p, Array c) >>, C<< RichText(... PairList p, Array c) >>, C<< Image(... PairList p, Array c) >>\n\nParameters: C<p> are widget properties and C<c> contains child widgets.\nReturns: widget object. Constructs content widgets.\n\n=item C<< Input(... PairList p, Array c) >>, C<< DatePicker(... PairList p, Array c) >>, C<< Checkbox(... PairList p, Array c) >>, C<< Radio(... PairList p, Array c) >>, C<< RadioGroup(... PairList p, Array c) >>, C<< Select(... PairList p, Array c) >>\n\nParameters: C<p> are widget properties and C<c> contains child widgets.\nReturns: widget object. Constructs input widgets.\n\n=item C<< Menu(... PairList p, Array c) >>, C<< MenuItem(... PairList p, Array c) >>, C<< Button(... PairList p, Array c) >>, C<< Separator(... PairList p, Array c) >>, C<< Slider(... PairList p, Array c) >>, C<< Progress(... PairList p, Array c) >>\n\nParameters: C<p> are widget properties and C<c> contains child widgets.\nReturns: widget object. Constructs command and control widgets.\n\n=item C<< Tabs(... PairList p, Array c) >>, C<< Tab(... PairList p, Array c) >>, C<< ListView(... PairList p, Array c) >>, C<< TreeView(... PairList p, Array c) >>\n\nParameters: C<p> are widget properties and C<c> contains child widgets.\nReturns: widget object. Constructs tabular and collection widgets.\n\n=item C<< unbind(BindingToken token) >>\n\nParameters: C<token> is a binding token. Returns: C<null>. Removes a GUI\nbinding.\n\n=item C<< gui_from_xml(String xml) >>, C<< gui_from_xml_file(path) >>\n\nParameters: C<xml> is GUI XML text and C<path> is a file path. Returns:\nwidget object. Builds a GUI object tree from XML.\n\n=item C<< gui_to_xml(Widget root) >>\n\nParameters: C<root> is a GUI widget. Returns: C<String>. Serializes a\nGUI object tree to XML.\n\n=back\n\n=head2 Classes\n\n=over\n\n=item C<BindingToken>\n\nRepresents a model/widget binding.\n\n=over\n\n=item C<< token.is_active() >>\n\nParameters: none. Returns: C<Boolean>. Returns true while the binding is\nactive.\n\n=item C<< token.set_listener(token) >>\n\nParameters: C<token> is a listener token. Returns: C<BindingToken>.\nStores the listener token associated with the binding.\n\n=item C<< token.sync_model_to_widget() >>, C<< token.sync_widget_to_model() >>\n\nParameters: none. Returns: C<null>. Synchronizes the bound values.\n\n=item C<< token.unbind() >>\n\nParameters: none. Returns: C<null>. Removes the binding.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/gui >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/gui/objects import\n	Window as _WindowClass,\n	VBox as _VBoxClass,\n	HBox as _HBoxClass,\n	Frame as _FrameClass,\n	Label as _LabelClass,\n	Text as _TextClass,\n	RichText as _RichTextClass,\n	Image as _ImageClass,\n	Input as _InputClass,\n	DatePicker as _DatePickerClass,\n	Checkbox as _CheckboxClass,\n	Radio as _RadioClass,\n	RadioGroup as _RadioGroupClass,\n	Select as _SelectClass,\n	Menu as _MenuClass,\n	MenuItem as _MenuItemClass,\n	Button as _ButtonClass,\n	Separator as _SeparatorClass,\n	Slider as _SliderClass,\n	Progress as _ProgressClass,\n	Tabs as _TabsClass,\n	Tab as _TabClass,\n	ListView as _ListViewClass,\n	TreeView as _TreeViewClass,\n	Widget,\n	Event,\n	ListenerToken,\n	native_file_open,\n	native_file_save,\n	native_directory_open,\n	native_directory_save,\n	native_colour_picker,\n	meta as _gui_meta;\n\nfrom std/gui/objects try import\n	native_alert,\n	native_confirm,\n	native_prompt;\n\nfrom std/data/xml import XML;\nfrom std/data/xml/escape import escape_xml;\nfrom std/internals import getupperprop;\nfrom std/path/zz import ZZPath;\nfrom std/string import join, split, substr, trim;\n\n\nconst Number EM := _gui_meta{font_size_pixels};\n\nfunction _assert_known_props ( String ctor, PairList props, Array allowed ) {\n	let geometry := [\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n	];\n	for ( let key in props.keys() ) {\n		if ( key \u2209 allowed and key \u2209 geometry ) {\n			die `GUI_PROP_UNKNOWN: ${ctor} does not accept property \'${key}\'`;\n		}\n	}\n}\n\nfunction _assert_prop_value ( String ctor, String prop, value, Array allowed ) {\n	if ( value \u2209 allowed ) {\n		die `GUI_PROP_TYPE: ${ctor} property \'${prop}\' has invalid value`;\n	}\n}\n\nfunction _assert_prop_array ( String ctor, String prop, value ) {\n	if ( not( value instanceof Array ) ) {\n		die `GUI_PROP_TYPE: ${ctor} property \'${prop}\' expects Array`;\n	}\n}\n\nfunction _with_geometry_props ( Array allowed ) {\n	for ( let key in [\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n	] ) {\n		allowed.push(key) unless key \u2208 allowed;\n	}\n	return allowed;\n}\n\nfunction _apply_geometry ( Widget widget, PairList p ) {\n	for ( let key in [\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n	] ) {\n		if ( p.has(key) ) {\n			widget.(key)( p.get(key) );\n		}\n	}\n	return widget;\n}\n\nfunction Window ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Window",\n		p,\n		_with_geometry_props( [\n			"id",\n			"title",\n			"width",\n			"height",\n			"resizable",\n			"modal",\n			"visible",\n			"enabled",\n			"disabled",\n		] ),\n	);\n\n	return new _WindowClass(\n		id: p.get( "id", null ),\n		title: p.get( "title", "" ),\n		width: p.get( "width", 800 ),\n		height: p.get( "height", 600 ),\n		minwidth: p.get( "minwidth", null ),\n		minheight: p.get( "minheight", null ),\n		maxwidth: p.get( "maxwidth", null ),\n		maxheight: p.get( "maxheight", null ),\n		resizable: p.get( "resizable", true ),\n		modal: p.get( "modal", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	);\n}\n\nfunction VBox ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"VBox",\n		p,\n		[\n			"id",\n			"align",\n			"gap",\n			"padding",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	_assert_prop_value(\n		"VBox",\n		"align",\n		p.get( "align", "top" ),\n		[ "top", "centre", "bottom", "stretch" ],\n	);\n\n	return _apply_geometry( new _VBoxClass(\n		id: p.get( "id", null ),\n		align: p.get( "align", "top" ),\n		gap: p.get( "gap", 0 ),\n		padding: p.get( "padding", 0 ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction HBox ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"HBox",\n		p,\n		_with_geometry_props( [\n			"id",\n			"align",\n			"gap",\n			"padding",\n			"visible",\n			"enabled",\n			"disabled",\n		] ),\n	);\n\n	_assert_prop_value(\n		"HBox",\n		"align",\n		p.get( "align", "left" ),\n		[ "left", "centre", "right", "stretch" ],\n	);\n\n	return new _HBoxClass(\n		id: p.get( "id", null ),\n		align: p.get( "align", "left" ),\n		gap: p.get( "gap", 0 ),\n		padding: p.get( "padding", 0 ),\n		width: p.get( "width", null ),\n		height: p.get( "height", null ),\n		minwidth: p.get( "minwidth", null ),\n		minheight: p.get( "minheight", null ),\n		maxwidth: p.get( "maxwidth", null ),\n		maxheight: p.get( "maxheight", null ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	);\n}\n\nfunction Frame ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Frame",\n		p,\n		[\n			"id",\n			"label",\n			"collapsible",\n			"collapsed",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _FrameClass(\n		id: p.get( "id", null ),\n		label: p.get( "label", "" ),\n		collapsible: p.get( "collapsible", false ),\n		collapsed: p.get( "collapsed", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Label ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Label",\n		p,\n		[ "id", "text", "for", "visible", "enabled", "disabled" ],\n	);\n\n	let label := new _LabelClass(\n		id: p.get( "id", null ),\n		text: p.get( "text", "" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	);\n	if ( p.has("for") ) {\n		label.set_for_id( p.get( "for", null ) );\n	}\n\n	return _apply_geometry( label, p );\n}\n\nfunction Text ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Text",\n		p,\n		[\n			"id",\n			"value",\n			"multiline",\n			"readonly",\n			"wrap",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _TextClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", "" ),\n		multiline: p.get( "multiline", false ),\n		readonly: p.get( "readonly", false ),\n		wrap: p.get( "wrap", true ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction RichText ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"RichText",\n		p,\n		[\n			"id",\n			"value",\n			"multiline",\n			"readonly",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _RichTextClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", "" ),\n		multiline: p.get( "multiline", true ),\n		readonly: p.get( "readonly", true ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Image ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Image",\n		p,\n		[ "id", "src", "alt", "fit", "visible", "enabled", "disabled" ],\n	);\n\n	_assert_prop_value(\n		"Image",\n		"fit",\n		p.get( "fit", "none" ),\n		[ "none", "contain", "cover", "stretch" ],\n	);\n\n	return _apply_geometry( new _ImageClass(\n		id: p.get( "id", null ),\n		src: p.get( "src", "" ),\n		alt: p.get( "alt", "" ),\n		fit: p.get( "fit", "none" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Input ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Input",\n		p,\n		[\n			"id",\n			"value",\n			"placeholder",\n			"multiline",\n			"readonly",\n			"password",\n			"required",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _InputClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", "" ),\n		placeholder: p.get( "placeholder", "" ),\n		multiline: p.get( "multiline", false ),\n		readonly: p.get( "readonly", false ),\n		password: p.get( "password", false ),\n		required: p.get( "required", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction DatePicker ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"DatePicker",\n		p,\n		[\n			"id",\n			"value",\n			"min",\n			"max",\n			"first_day_of_week",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _DatePickerClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", null ),\n		min: p.get( "min", null ),\n		max: p.get( "max", null ),\n		first_day_of_week: p.get( "first_day_of_week", 0 ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Checkbox ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Checkbox",\n		p,\n		[\n			"id",\n			"label",\n			"checked",\n			"indeterminate",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _CheckboxClass(\n		id: p.get( "id", null ),\n		label: p.get( "label", "" ),\n		checked: p.get( "checked", false ),\n		indeterminate: p.get( "indeterminate", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Radio ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Radio",\n		p,\n		[\n			"id",\n			"label",\n			"value",\n			"group",\n			"checked",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _RadioClass(\n		id: p.get( "id", null ),\n		label: p.get( "label", "" ),\n		value: p.get( "value", "" ),\n		group: p.get( "group", null ),\n		checked: p.get( "checked", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction RadioGroup ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"RadioGroup",\n		p,\n		[\n			"id",\n			"name",\n			"value",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _RadioGroupClass(\n		id: p.get( "id", null ),\n		name: p.get( "name", "" ),\n		value: p.get( "value", null ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Select ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Select",\n		p,\n		[\n			"id",\n			"value",\n			"options",\n			"multiple",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	if ( p.has("options") ) {\n		_assert_prop_array( "Select", "options", p.get("options") );\n	}\n\n	return _apply_geometry( new _SelectClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", null ),\n		options: p.get( "options", [] ),\n		multiple: p.get( "multiple", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Menu ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Menu",\n		p,\n		[ "id", "text", "visible", "enabled", "disabled" ],\n	);\n\n	return _apply_geometry( new _MenuClass(\n		id: p.get( "id", null ),\n		text: p.get( "text", "" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction MenuItem ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"MenuItem",\n		p,\n		[ "id", "text", "disabled", "visible", "enabled" ],\n	);\n\n	return _apply_geometry( new _MenuItemClass(\n		id: p.get( "id", null ),\n		text: p.get( "text", "" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Button ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Button",\n		p,\n		_with_geometry_props( [\n			"id",\n			"text",\n			"variant",\n			"visible",\n			"enabled",\n			"disabled",\n		] ),\n	);\n\n	_assert_prop_value(\n		"Button",\n		"variant",\n		p.get( "variant", "default" ),\n		[ "default", "primary", "danger" ],\n	);\n\n	return new _ButtonClass(\n		id: p.get( "id", null ),\n		text: p.get( "text", "" ),\n		variant: p.get( "variant", "default" ),\n		width: p.get( "width", null ),\n		height: p.get( "height", null ),\n		minwidth: p.get( "minwidth", null ),\n		minheight: p.get( "minheight", null ),\n		maxwidth: p.get( "maxwidth", null ),\n		maxheight: p.get( "maxheight", null ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	);\n}\n\nfunction Separator ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Separator",\n		p,\n		[ "id", "orientation", "visible", "enabled", "disabled" ],\n	);\n\n	_assert_prop_value(\n		"Separator",\n		"orientation",\n		p.get( "orientation", "horizontal" ),\n		[ "horizontal", "vertical" ],\n	);\n\n	return _apply_geometry( new _SeparatorClass(\n		id: p.get( "id", null ),\n		orientation: p.get( "orientation", "horizontal" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Slider ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Slider",\n		p,\n		[\n			"id",\n			"value",\n			"min",\n			"max",\n			"step",\n			"orientation",\n			"readonly",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	_assert_prop_value(\n		"Slider",\n		"orientation",\n		p.get( "orientation", "horizontal" ),\n		[ "horizontal", "vertical" ],\n	);\n\n	return _apply_geometry( new _SliderClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", 0 ),\n		min: p.get( "min", 0 ),\n		max: p.get( "max", 100 ),\n		step: p.get( "step", 1 ),\n		orientation: p.get( "orientation", "horizontal" ),\n		readonly: p.get( "readonly", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Progress ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Progress",\n		p,\n		[\n			"id",\n			"value",\n			"min",\n			"max",\n			"indeterminate",\n			"show_text",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _ProgressClass(\n		id: p.get( "id", null ),\n		value: p.get( "value", 0 ),\n		min: p.get( "min", 0 ),\n		max: p.get( "max", 100 ),\n		indeterminate: p.get( "indeterminate", false ),\n		show_text: p.get( "show_text", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Tabs ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Tabs",\n		p,\n		[\n			"id",\n			"selected",\n			"placement",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	_assert_prop_value(\n		"Tabs",\n		"placement",\n		p.get( "placement", "top" ),\n		[ "top", "bottom", "left", "right" ],\n	);\n\n	return _apply_geometry( new _TabsClass(\n		id: p.get( "id", null ),\n		selected: p.get( "selected", null ),\n		placement: p.get( "placement", "top" ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction Tab ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"Tab",\n		p,\n		[\n			"id",\n			"title",\n			"value",\n			"selected",\n			"closable",\n			"icon",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	return _apply_geometry( new _TabClass(\n		id: p.get( "id", null ),\n		title: p.get( "title", "" ),\n		value: p.get( "value", "" ),\n		selected: p.get( "selected", false ),\n		closable: p.get( "closable", false ),\n		icon: p.get( "icon", null ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction ListView ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"ListView",\n		p,\n		[\n			"id",\n			"items",\n			"selected_index",\n			"multiple",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	if ( p.has("items") ) {\n		_assert_prop_array( "ListView", "items", p.get("items") );\n	}\n\n	return _apply_geometry( new _ListViewClass(\n		id: p.get( "id", null ),\n		items: p.get( "items", [] ),\n		selected_index: p.get( "selected_index", null ),\n		multiple: p.get( "multiple", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction TreeView ( ... PairList p, Array c ) {\n	_assert_known_props(\n		"TreeView",\n		p,\n		[\n			"id",\n			"items",\n			"selected_path",\n			"multiple",\n			"visible",\n			"enabled",\n			"disabled",\n		],\n	);\n\n	if ( p.has("items") ) {\n		_assert_prop_array( "TreeView", "items", p.get("items") );\n	}\n	if ( p.has("selected_path") ) {\n		_assert_prop_array( "TreeView", "selected_path", p.get("selected_path") );\n	}\n\n	return _apply_geometry( new _TreeViewClass(\n		id: p.get( "id", null ),\n		items: p.get( "items", [] ),\n		selected_path: p.get( "selected_path", [] ),\n		multiple: p.get( "multiple", false ),\n		visible: p.get( "visible", true ),\n		enabled: p.get( "enabled", true ),\n		disabled: p.get( "disabled", false ),\n		children: c,\n	), p );\n}\n\nfunction _binding_path_class ( path_class ) {\n	if ( path_class \u2261 null ) {\n		return ZZPath;\n	}\n	if ( not( path_class instanceof Class ) ) {\n		die "GUI_BIND_PATH: paths special property must be Class or null";\n	}\n	return path_class;\n}\n\nfunction _binding_compile_path ( String path_text, path_class ) {\n	if ( path_class \u2261 null ) {\n		try {\n			return new ZZPath( path: path_text );\n		}\n		catch ( Exception e ) {\n			die `GUI_BIND_PATH: ${e{message}}`;\n		}\n	}\n\n	let path_type := _binding_path_class(path_class);\n	try {\n		return new path_type( path: path_text );\n	}\n	catch ( Exception e ) {\n		die `GUI_BIND_PATH: ${e{message}}`;\n	}\n}\n\nfunction _binding_path ( pathish, path_class ) {\n	if ( pathish instanceof String ) {\n		return _binding_compile_path( pathish, path_class );\n	}\n	if (\n		pathish can first\n		and ( pathish can assign_first or pathish can ref_first )\n	) {\n		return pathish;\n	}\n\n	die "GUI_BIND_PATH: binding path must be String or path-like Object";\n}\n\nfunction _binding_get ( model, path ) {\n	return path.first( model, null );\n}\n\nfunction _binding_set ( model, path, value ) {\n	if ( path can assign_first ) {\n		return path.assign_first( model, value );\n	}\n\n	let ref := path.ref_first(model);\n	return ref(value);\n}\n\nclass BindingToken {\n	let Widget widget but weak;\n	let String widget_prop;\n	let model;\n	let model_path;\n	let String event := "change";\n	let listener := null;\n	let Boolean _active := true;\n\n	method is_active () {\n		return _active;\n	}\n\n	method set_listener ( token ) {\n		listener := token;\n		return self;\n	}\n\n	method sync_model_to_widget () {\n		widget.(widget_prop)( _binding_get( model, model_path ) );\n		return self;\n	}\n\n	method sync_widget_to_model () {\n		_binding_set( model, model_path, widget.(widget_prop)() );\n		return self;\n	}\n\n	method unbind () {\n		if ( _active and listener \u2262 null ) {\n			widget.off(listener);\n		}\n		_active := false;\n		return self;\n	}\n}\n\nfunction bind (\n	Widget widget,\n	String widget_prop,\n	model,\n	model_path,\n	... PairList p\n) {\n	let path := _binding_path( model_path, getupperprop( 1, "paths" ) );\n\n	let token := new BindingToken(\n		widget: widget,\n		widget_prop: widget_prop,\n		model: model,\n		model_path: path,\n		event: p.get( "event", "change" ),\n	);\n	let event_name := p.get( "event", "change" );\n\n	switch ( p.get( "initial", "model" ): eq ) {\n		case "model":\n			token.sync_model_to_widget();\n		case "widget":\n			token.sync_widget_to_model();\n		case "none":\n			// No initial sync.\n		default:\n			die "GUI_BIND_INITIAL: initial must be model, widget, or none";\n	}\n\n	token.set_listener(\n		widget.on( event_name, function () {\n			if ( token.is_active() ) {\n				token.sync_widget_to_model();\n			}\n		} ),\n	);\n	return token;\n}\n\nfunction unbind ( BindingToken token ) {\n	return token.unbind();\n}\n\nlet GUI_XML_NS := "https://zuzulang.org/ns/std/gui";\n\nfunction _xml_error ( String code, String message ) {\n	die `${code}: ${message}`;\n}\n\nfunction _xml_tag_name ( node ) {\n	return node.localName() ?: node.nodeName();\n}\n\nfunction _xml_assert_namespace ( node ) {\n	let ns := node.namespaceURI();\n	if ( ns \u2262 null and ns \u2262 "" and ns \u2262 GUI_XML_NS ) {\n		_xml_error(\n			"GUI_XML_STRUCTURE",\n			`unsupported GUI XML namespace \'${ns}\'`,\n		);\n	}\n}\n\nfunction _xml_common_allowed ( Array extra ) {\n	let out := [\n		"id",\n		"visible",\n		"enabled",\n		"disabled",\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n	];\n	for ( let attr in extra ) {\n		out.push(attr);\n	}\n	return out;\n}\n\nfunction _xml_allowed_attrs ( String tag ) {\n	switch ( tag: eq ) {\n		case "Window":\n			return _xml_common_allowed(\n				[ "title", "width", "height", "resizable", "modal" ],\n			);\n		case "VBox", "HBox":\n			return _xml_common_allowed( [ "align", "gap", "padding" ] );\n		case "Frame":\n			return _xml_common_allowed( [ "label", "collapsible", "collapsed" ] );\n		case "Label":\n			return _xml_common_allowed( [ "text", "for" ] );\n		case "Text":\n			return _xml_common_allowed(\n				[ "value", "multiline", "readonly", "wrap" ],\n			);\n		case "RichText":\n			return _xml_common_allowed(\n				[ "value", "multiline", "readonly" ],\n			);\n		case "Image":\n			return _xml_common_allowed( [ "src", "alt", "fit" ] );\n		case "Input":\n			return _xml_common_allowed( [\n				"value",\n				"placeholder",\n				"multiline",\n				"readonly",\n				"password",\n				"required",\n			] );\n		case "DatePicker":\n			return _xml_common_allowed(\n				[ "value", "min", "max", "first_day_of_week" ],\n			);\n		case "Checkbox":\n			return _xml_common_allowed( [ "label", "checked", "indeterminate" ] );\n		case "Radio":\n			return _xml_common_allowed( [ "label", "value", "group", "checked" ] );\n		case "RadioGroup":\n			return _xml_common_allowed( [ "name", "value" ] );\n		case "Select":\n			return _xml_common_allowed( [ "value", "multiple" ] );\n		case "Menu":\n			return _xml_common_allowed( [ "text" ] );\n		case "MenuItem":\n			return _xml_common_allowed( [ "text" ] );\n		case "Button":\n			return _xml_common_allowed( [ "text", "variant" ] );\n		case "Separator":\n			return _xml_common_allowed( [ "orientation" ] );\n		case "Slider":\n			return _xml_common_allowed( [\n				"value",\n				"min",\n				"max",\n				"step",\n				"orientation",\n				"readonly",\n			] );\n		case "Progress":\n			return _xml_common_allowed( [\n				"value",\n				"min",\n				"max",\n				"indeterminate",\n				"show_text",\n			] );\n		case "Tabs":\n			return _xml_common_allowed( [ "selected", "placement" ] );\n		case "Tab":\n			return _xml_common_allowed(\n				[ "title", "value", "selected", "closable", "icon" ],\n			);\n		case "ListView":\n			return _xml_common_allowed( [ "selected_index", "multiple" ] );\n		case "TreeView":\n			return _xml_common_allowed( [ "selected_path", "multiple" ] );\n	}\n\n	_xml_error( "GUI_XML_STRUCTURE", `unsupported GUI XML element \'${tag}\'` );\n}\n\nfunction _xml_bool_attrs ( String tag ) {\n	return [\n		"visible",\n		"enabled",\n		"disabled",\n		"resizable",\n		"modal",\n		"collapsible",\n		"collapsed",\n		"multiline",\n		"readonly",\n		"wrap",\n		"password",\n		"required",\n		"checked",\n		"indeterminate",\n		"multiple",\n		"show_text",\n		"selected",\n		"closable",\n	];\n}\n\nfunction _xml_number_attrs ( String tag ) {\n	return [\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n		"gap",\n		"padding",\n		"first_day_of_week",\n		"selected_index",\n		"value",\n		"min",\n		"max",\n		"step",\n	];\n}\n\nfunction _xml_bool ( String tag, String attr, String raw ) {\n	switch ( lc(raw): eq ) {\n		case "true", "1", "yes", "on": return true;\n		case "false", "0", "no", "off": return false;\n	}\n	_xml_error(\n		"GUI_XML_ATTR_TYPE",\n		`${tag}.${attr} expects a boolean XML attribute`,\n	);\n}\n\nfunction _xml_number ( String tag, String attr, String raw ) {\n	if ( not ( raw ~ /^-?[0-9]+(\\.[0-9]+)?$/ ) ) {\n		_xml_error(\n			"GUI_XML_ATTR_TYPE",\n			`${tag}.${attr} expects a numeric XML attribute`,\n		);\n	}\n	return 0 + raw;\n}\n\nfunction _xml_int_list ( String tag, String attr, String raw ) {\n	let out := [];\n	return out if raw eq "";\n	for ( let part in split( raw, "," ) ) {\n		let item := trim(part);\n		if ( not ( item ~ /^-?[0-9]+$/ ) ) {\n			_xml_error(\n				"GUI_XML_ATTR_TYPE",\n				`${tag}.${attr} expects comma-separated integers`,\n			);\n		}\n		out.push( 0 + item );\n	}\n	return out;\n}\n\nfunction _xml_coerce_attr ( String tag, String attr, String raw ) {\n	if ( attr eq "selected" and tag eq "Tabs" ) {\n		return raw;\n	}\n	if ( attr eq "value" and tag \u2209 [ "Slider", "Progress" ] ) {\n		return raw;\n	}\n	if ( attr eq "min" and tag eq "DatePicker" ) {\n		return raw;\n	}\n	if ( attr eq "max" and tag eq "DatePicker" ) {\n		return raw;\n	}\n	if ( attr eq "selected_path" ) {\n		return _xml_int_list( tag, attr, raw );\n	}\n	if ( attr \u2208 _xml_bool_attrs(tag) ) {\n		return _xml_bool( tag, attr, raw );\n	}\n	if ( attr \u2208 _xml_number_attrs(tag) ) {\n		return _xml_number( tag, attr, raw );\n	}\n	return raw;\n}\n\nfunction _xml_attrs ( node ) {\n	let tag := _xml_tag_name(node);\n	let props := {};\n	let meta := {};\n	let meta_keys := [];\n	let style := {};\n	let style_keys := [];\n	let allowed := _xml_allowed_attrs(tag);\n\n	for ( let attr in node.attributeNames() ) {\n		next if attr eq "xmlns";\n		next if substr( attr, 0, 6 ) eq "xmlns:";\n		let value := node.getAttribute(attr);\n		if ( substr( attr, 0, 5 ) eq "meta." ) {\n			let key := substr( attr, 5 );\n			_xml_error( "GUI_XML_ATTR_UNKNOWN", "empty meta attribute name" )\n				if key eq "";\n			meta{(key)} := value;\n			meta_keys.push(key);\n			next;\n		}\n		if ( substr( attr, 0, 6 ) eq "style." ) {\n			let key := substr( attr, 6 );\n			_xml_error( "GUI_XML_ATTR_UNKNOWN", "empty style attribute name" )\n				if key eq "";\n			style{(key)} := value;\n			style_keys.push(key);\n			next;\n		}\n		if ( attr \u2209 allowed ) {\n			_xml_error(\n				"GUI_XML_ATTR_UNKNOWN",\n				`${tag} does not accept XML attribute \'${attr}\'`,\n			);\n		}\n		props{(attr)} := _xml_coerce_attr( tag, attr, value );\n	}\n\n	return {\n		props: props,\n		meta: meta,\n		meta_keys: meta_keys,\n		style: style,\n		style_keys: style_keys,\n	};\n}\n\nfunction _xml_apply_meta ( Widget widget, Dict meta, Array keys ) {\n	for ( let key in keys ) {\n		widget.meta( key, meta{(key)} );\n	}\n	if ( keys.length() > 0 ) {\n		widget.meta( "__xml_meta_keys", keys );\n	}\n	return widget;\n}\n\nfunction _xml_apply_style ( Widget widget, Dict style, Array keys ) {\n	for ( let key in keys ) {\n		widget.style( key, style{(key)} );\n	}\n	if ( keys.length() > 0 ) {\n		widget.meta( "__xml_style_keys", keys );\n	}\n	return widget;\n}\n\nfunction _xml_widget_from_node ( node ) {\n	_xml_assert_namespace(node);\n\n	let tag := _xml_tag_name(node);\n	let child_widgets := [];\n	for ( let child in node.children() ) {\n		child_widgets.push( _xml_widget_from_node(child) );\n	}\n	let parsed := _xml_attrs(node);\n	let p := parsed{props};\n	let widget;\n\n	switch ( tag: eq ) {\n		case "Window":\n			widget := new _WindowClass(\n				id: p.get( "id", null ),\n				title: p.get( "title", "" ),\n				width: p.get( "width", 800 ),\n				height: p.get( "height", 600 ),\n				resizable: p.get( "resizable", true ),\n				modal: p.get( "modal", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "VBox":\n			widget := new _VBoxClass(\n				id: p.get( "id", null ),\n				align: p.get( "align", "top" ),\n				gap: p.get( "gap", 0 ),\n				padding: p.get( "padding", 0 ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "HBox":\n			widget := new _HBoxClass(\n				id: p.get( "id", null ),\n				align: p.get( "align", "left" ),\n				gap: p.get( "gap", 0 ),\n				padding: p.get( "padding", 0 ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "Frame":\n			widget := new _FrameClass(\n				id: p.get( "id", null ),\n				label: p.get( "label", "" ),\n				collapsible: p.get( "collapsible", false ),\n				collapsed: p.get( "collapsed", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "Label":\n			widget := Label(\n				id: p.get( "id", null ),\n				text: p.get( "text", "" ),\n				("for"): p.get( "for", null ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Text":\n			widget := Text(\n				id: p.get( "id", null ),\n				value: p.get( "value", "" ),\n				multiline: p.get( "multiline", false ),\n				readonly: p.get( "readonly", false ),\n				wrap: p.get( "wrap", true ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "RichText":\n			widget := RichText(\n				id: p.get( "id", null ),\n				value: p.get( "value", "" ),\n				multiline: p.get( "multiline", true ),\n				readonly: p.get( "readonly", true ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Image":\n			widget := Image(\n				id: p.get( "id", null ),\n				src: p.get( "src", "" ),\n				alt: p.get( "alt", "" ),\n				fit: p.get( "fit", "none" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Input":\n			widget := Input(\n				id: p.get( "id", null ),\n				value: p.get( "value", "" ),\n				placeholder: p.get( "placeholder", "" ),\n				multiline: p.get( "multiline", false ),\n				readonly: p.get( "readonly", false ),\n				password: p.get( "password", false ),\n				required: p.get( "required", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "DatePicker":\n			widget := DatePicker(\n				id: p.get( "id", null ),\n				value: p.get( "value", null ),\n				min: p.get( "min", null ),\n				max: p.get( "max", null ),\n				first_day_of_week: p.get( "first_day_of_week", 0 ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Checkbox":\n			widget := Checkbox(\n				id: p.get( "id", null ),\n				label: p.get( "label", "" ),\n				checked: p.get( "checked", false ),\n				indeterminate: p.get( "indeterminate", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Radio":\n			widget := Radio(\n				id: p.get( "id", null ),\n				label: p.get( "label", "" ),\n				value: p.get( "value", "" ),\n				group: p.get( "group", null ),\n				checked: p.get( "checked", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "RadioGroup":\n			widget := new _RadioGroupClass(\n				id: p.get( "id", null ),\n				name: p.get( "name", "" ),\n				value: p.get( "value", null ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "Select":\n			widget := Select(\n				id: p.get( "id", null ),\n				value: p.get( "value", null ),\n				multiple: p.get( "multiple", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Menu":\n			widget := new _MenuClass(\n				id: p.get( "id", null ),\n				text: p.get( "text", "" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "MenuItem":\n			widget := MenuItem(\n				id: p.get( "id", null ),\n				text: p.get( "text", "" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Button":\n			widget := Button(\n				id: p.get( "id", null ),\n				text: p.get( "text", "" ),\n				variant: p.get( "variant", "default" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Separator":\n			widget := Separator(\n				id: p.get( "id", null ),\n				orientation: p.get( "orientation", "horizontal" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Slider":\n			widget := Slider(\n				id: p.get( "id", null ),\n				value: p.get( "value", 0 ),\n				min: p.get( "min", 0 ),\n				max: p.get( "max", 100 ),\n				step: p.get( "step", 1 ),\n				orientation: p.get( "orientation", "horizontal" ),\n				readonly: p.get( "readonly", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Progress":\n			widget := Progress(\n				id: p.get( "id", null ),\n				value: p.get( "value", 0 ),\n				min: p.get( "min", 0 ),\n				max: p.get( "max", 100 ),\n				indeterminate: p.get( "indeterminate", false ),\n				show_text: p.get( "show_text", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "Tabs":\n			widget := new _TabsClass(\n				id: p.get( "id", null ),\n				selected: p.get( "selected", null ),\n				placement: p.get( "placement", "top" ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "Tab":\n			widget := new _TabClass(\n				id: p.get( "id", null ),\n				title: p.get( "title", "" ),\n				value: p.get( "value", "" ),\n				selected: p.get( "selected", false ),\n				closable: p.get( "closable", false ),\n				icon: p.get( "icon", null ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n				children: child_widgets,\n			);\n		case "ListView":\n			widget := ListView(\n				id: p.get( "id", null ),\n				selected_index: p.get( "selected_index", null ),\n				multiple: p.get( "multiple", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		case "TreeView":\n			widget := TreeView(\n				id: p.get( "id", null ),\n				selected_path: p.get( "selected_path", [] ),\n				multiple: p.get( "multiple", false ),\n				visible: p.get( "visible", true ),\n				enabled: p.get( "enabled", true ),\n				disabled: p.get( "disabled", false ),\n			);\n		default:\n			_xml_error(\n				"GUI_XML_STRUCTURE",\n				`unsupported GUI XML element \'${tag}\'`,\n			);\n	}\n\n	_xml_apply_meta( widget, parsed{meta}, parsed{meta_keys} );\n	return _xml_apply_style( widget, parsed{style}, parsed{style_keys} );\n}\n\nfunction gui_from_xml ( String xml ) {\n	return _xml_widget_from_node( XML.parse(xml).documentElement() );\n}\n\nfunction gui_from_xml_file ( path ) {\n	die "XML.load is denied by runtime policy" if __system__{deny_fs};\n	from std/io import Path;\n	let file := path instanceof Path ? path : new Path(path);\n	return _xml_widget_from_node( XML.load(file).documentElement() );\n}\n\nfunction _xml_tag_for_widget ( Widget widget ) {\n	if ( widget instanceof _WindowClass ) { return "Window"; }\n	if ( widget instanceof _VBoxClass ) { return "VBox"; }\n	if ( widget instanceof _HBoxClass ) { return "HBox"; }\n	if ( widget instanceof _FrameClass ) { return "Frame"; }\n	if ( widget instanceof _LabelClass ) { return "Label"; }\n	if ( widget instanceof _TextClass ) { return "Text"; }\n	if ( widget instanceof _RichTextClass ) { return "RichText"; }\n	if ( widget instanceof _ImageClass ) { return "Image"; }\n	if ( widget instanceof _InputClass ) { return "Input"; }\n	if ( widget instanceof _DatePickerClass ) { return "DatePicker"; }\n	if ( widget instanceof _CheckboxClass ) { return "Checkbox"; }\n	if ( widget instanceof _RadioClass ) { return "Radio"; }\n	if ( widget instanceof _RadioGroupClass ) { return "RadioGroup"; }\n	if ( widget instanceof _SelectClass ) { return "Select"; }\n	if ( widget instanceof _MenuClass ) { return "Menu"; }\n	if ( widget instanceof _MenuItemClass ) { return "MenuItem"; }\n	if ( widget instanceof _ButtonClass ) { return "Button"; }\n	if ( widget instanceof _SeparatorClass ) { return "Separator"; }\n	if ( widget instanceof _SliderClass ) { return "Slider"; }\n	if ( widget instanceof _ProgressClass ) { return "Progress"; }\n	if ( widget instanceof _TabsClass ) { return "Tabs"; }\n	if ( widget instanceof _TabClass ) { return "Tab"; }\n	if ( widget instanceof _ListViewClass ) { return "ListView"; }\n	if ( widget instanceof _TreeViewClass ) { return "TreeView"; }\n	_xml_error( "GUI_XML_STRUCTURE", "unsupported widget for gui_to_xml" );\n}\n\nfunction _xml_attr ( String name, value ) {\n	return "" if value \u2261 null;\n	return ` ${name}="${escape_xml(value)}"`;\n}\n\nfunction _xml_attr_if ( String name, value, fallback ) {\n	return "" if value \u2261 fallback;\n	return _xml_attr( name, value );\n}\n\nfunction _xml_bool_attr_if ( String name, value, fallback ) {\n	let normalized := value ? true : false;\n	let normalized_fallback := fallback ? true : false;\n	return "" if normalized \u2261 normalized_fallback;\n	return _xml_attr( name, normalized ? "true" : "false" );\n}\n\nfunction _xml_attr_nonempty ( String name, value ) {\n	return "" if value \u2261 null or value eq "";\n	return _xml_attr( name, value );\n}\n\nfunction _xml_join_ints ( Array values ) {\n	let out := [];\n	for ( let value in values ) {\n		out.push( "" _ value );\n	}\n	return join( ",", out );\n}\n\nfunction _xml_meta_attrs ( Widget widget ) {\n	let keys := widget.meta( "__xml_meta_keys" ) ?: [];\n	let out := "";\n	for ( let key in keys ) {\n		out _= _xml_attr( "meta." _ key, widget.meta(key) );\n	}\n	return out;\n}\n\nfunction _xml_style_attrs ( Widget widget ) {\n	let keys := widget.meta( "__xml_style_keys" ) ?: [];\n	let out := "";\n	for ( let key in keys ) {\n		out _= _xml_attr( "style." _ key, widget.style(key) );\n	}\n	return out;\n}\n\nfunction _xml_common_attrs ( Widget widget ) {\n	let out := "";\n	out _= _xml_attr( "id", widget.id() ) if widget.id() \u2262 null;\n	out _= _xml_bool_attr_if( "visible", widget.visible(), true );\n	out _= _xml_bool_attr_if( "disabled", not widget.enabled(), false );\n	out _= _xml_meta_attrs(widget);\n	out _= _xml_style_attrs(widget);\n	return out;\n}\n\nfunction _xml_widget_attrs ( Widget widget ) {\n	let out := _xml_common_attrs(widget);\n	if ( widget instanceof _WindowClass ) {\n		out _= _xml_attr_if( "title", widget.title(), "" );\n	}\n	else if ( widget instanceof _VBoxClass or widget instanceof _HBoxClass ) {\n		let default_align := widget instanceof _VBoxClass ? "top" : "left";\n		out _= _xml_attr_if( "align", widget.align(), default_align );\n		out _= _xml_attr_if( "gap", widget.gap(), 0 );\n		out _= _xml_attr_if( "padding", widget.padding(), 0 )\n			unless widget.padding() instanceof Array;\n	}\n	else if ( widget instanceof _FrameClass ) {\n		out _= _xml_attr_if( "label", widget.label(), "" );\n		out _= _xml_bool_attr_if( "collapsible", widget.collapsible(), false );\n		out _= _xml_bool_attr_if( "collapsed", widget.collapsed(), false );\n	}\n	else if ( widget instanceof _LabelClass ) {\n		out _= _xml_attr_if( "text", widget.text(), "" );\n		out _= _xml_attr_nonempty( "for", widget.for_id() );\n	}\n	else if ( widget instanceof _TextClass ) {\n		out _= _xml_attr_if( "value", widget.value(), "" );\n		out _= _xml_bool_attr_if( "multiline", widget.multiline(), false );\n		out _= _xml_bool_attr_if( "readonly", widget.readonly(), false );\n		out _= _xml_bool_attr_if( "wrap", widget.wrap(), true );\n	}\n	else if ( widget instanceof _RichTextClass ) {\n		out _= _xml_attr_if( "value", widget.value(), "" );\n		out _= _xml_bool_attr_if( "multiline", widget.multiline(), true );\n		out _= _xml_bool_attr_if( "readonly", widget.readonly(), true );\n	}\n	else if ( widget instanceof _ImageClass ) {\n		out _= _xml_attr_if( "src", widget.src(), "" );\n		out _= _xml_attr_if( "alt", widget.alt(), "" );\n		out _= _xml_attr_if( "fit", widget.fit(), "none" );\n	}\n	else if ( widget instanceof _InputClass ) {\n		out _= _xml_attr_if( "value", widget.value(), "" );\n		out _= _xml_attr_if( "placeholder", widget.placeholder(), "" );\n		out _= _xml_bool_attr_if( "multiline", widget.multiline(), false );\n		out _= _xml_bool_attr_if( "readonly", widget.readonly(), false );\n		out _= _xml_bool_attr_if( "password", widget.password(), false );\n		out _= _xml_bool_attr_if( "required", widget.required(), false );\n	}\n	else if ( widget instanceof _DatePickerClass ) {\n		out _= _xml_attr( "value", widget.value() );\n		out _= _xml_attr( "min", widget.min() ) if widget.min() \u2262 null;\n		out _= _xml_attr( "max", widget.max() ) if widget.max() \u2262 null;\n		out _= _xml_attr_if(\n			"first_day_of_week",\n			widget.first_day_of_week(),\n			0,\n		);\n	}\n	else if ( widget instanceof _CheckboxClass ) {\n		out _= _xml_attr_if( "label", widget.label(), "" );\n		out _= _xml_bool_attr_if( "checked", widget.checked(), false );\n		out _= _xml_bool_attr_if( "indeterminate", widget.indeterminate(), false );\n	}\n	else if ( widget instanceof _RadioClass ) {\n		out _= _xml_attr_if( "label", widget.label(), "" );\n		out _= _xml_attr_if( "value", widget.value(), "" );\n		out _= _xml_attr_nonempty( "group", widget.group() );\n		out _= _xml_bool_attr_if( "checked", widget.checked(), false );\n	}\n	else if ( widget instanceof _RadioGroupClass ) {\n		out _= _xml_attr_if( "name", widget.name(), "" );\n		out _= _xml_attr( "value", widget.value() ) if widget.value() \u2262 null;\n	}\n	else if ( widget instanceof _SelectClass ) {\n		out _= _xml_attr( "value", widget.value() ) if widget.value() \u2262 null;\n		out _= _xml_bool_attr_if( "multiple", widget.multiple(), false );\n	}\n	else if ( widget instanceof _MenuClass ) {\n		out _= _xml_attr_if( "text", widget.text(), "" );\n	}\n	else if ( widget instanceof _MenuItemClass ) {\n		out _= _xml_attr_if( "text", widget.text(), "" );\n	}\n	else if ( widget instanceof _ButtonClass ) {\n		out _= _xml_attr_if( "text", widget.text(), "" );\n		out _= _xml_attr_if( "variant", widget.variant(), "default" );\n	}\n	else if ( widget instanceof _SeparatorClass ) {\n		out _= _xml_attr_if( "orientation", widget.orientation(), "horizontal" );\n	}\n	else if ( widget instanceof _SliderClass ) {\n		out _= _xml_attr_if( "value", widget.value(), 0 );\n		out _= _xml_attr_if( "min", widget.min(), 0 );\n		out _= _xml_attr_if( "max", widget.max(), 100 );\n		out _= _xml_attr_if( "step", widget.step(), 1 );\n		out _= _xml_attr_if( "orientation", widget.orientation(), "horizontal" );\n		out _= _xml_bool_attr_if( "readonly", widget.readonly(), false );\n	}\n	else if ( widget instanceof _ProgressClass ) {\n		out _= _xml_attr_if( "value", widget.value(), 0 );\n		out _= _xml_attr_if( "min", widget.min(), 0 );\n		out _= _xml_attr_if( "max", widget.max(), 100 );\n		out _= _xml_bool_attr_if( "indeterminate", widget.indeterminate(), false );\n		out _= _xml_bool_attr_if( "show_text", widget.show_text(), false );\n	}\n	else if ( widget instanceof _TabsClass ) {\n		out _= _xml_attr( "selected", widget.selected() )\n			if widget.selected() \u2262 null;\n		out _= _xml_attr_if( "placement", widget.placement(), "top" );\n	}\n	else if ( widget instanceof _TabClass ) {\n		out _= _xml_attr_if( "title", widget.title(), "" );\n		out _= _xml_attr_if( "value", widget.value(), "" );\n		out _= _xml_attr( "icon", widget.icon() ) if widget.icon() \u2262 null;\n		out _= _xml_bool_attr_if( "selected", widget.selected(), false );\n		out _= _xml_bool_attr_if( "closable", widget.closable(), false );\n	}\n	else if ( widget instanceof _ListViewClass ) {\n		out _= _xml_attr( "selected_index", widget.selected_index() )\n			if widget.selected_index() \u2262 null;\n		out _= _xml_bool_attr_if( "multiple", widget.multiple(), false );\n	}\n	else if ( widget instanceof _TreeViewClass ) {\n		let selected_path := widget.selected_path();\n		out _= _xml_attr( "selected_path", _xml_join_ints(selected_path) )\n			if selected_path.length() > 0;\n		out _= _xml_bool_attr_if( "multiple", widget.multiple(), false );\n	}\n	return out;\n}\n\nfunction _xml_serialize_widget ( Widget widget, Number depth ) {\n	let indent := "";\n	let i := 0;\n	while ( i < depth ) {\n		indent _= "\\t";\n		i++;\n	}\n\n	let tag := _xml_tag_for_widget(widget);\n	let attrs := _xml_widget_attrs(widget);\n	attrs _= _xml_attr( "xmlns", GUI_XML_NS ) if depth = 0;\n	let children := widget.children();\n	if ( children.length() = 0 ) {\n		return indent _ "<" _ tag _ attrs _ " />";\n	}\n\n	let parts := [];\n	for ( let child in children ) {\n		parts.push( _xml_serialize_widget( child, depth + 1 ) );\n	}\n\n	return indent _ "<" _ tag _ attrs _ ">\\n"\n		_ join( "\\n", parts )\n		_ "\\n" _ indent _ "</" _ tag _ ">";\n}\n\nfunction gui_to_xml ( Widget root ) {\n	return _xml_serialize_widget( root, 0 ) _ "\\n";\n}\n';
        virtualFiles["/modules/std/gui/dialogue.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/gui/dialogue - Dialogue helpers.\n\n=head1 SYNOPSIS\n\n  from std/gui/dialogue import *;\n\n  alert("Saved");\n  let ok := confirm("Continue?");\n  let name := prompt("Name:", value: "Ada");\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Electron\nand Browser. It is not supported by zuzu-js on Node.\n\n=head1 DESCRIPTION\n\nThis module provides convenience dialogue helpers layered on top of the\nregular C<std/gui> widgets.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item C<< alert(String message, ... PairList p) >>, C<< alert_window(String message, ... PairList p) >>\n\nParameters: C<message> is display text and C<p> contains options.\nReturns: C<null> for C<alert> or C<Window> for C<alert_window>. Shows or\nbuilds an alert dialogue.\n\n=item C<< confirm(String message, ... PairList p) >>, C<< confirm_window(String message, ... PairList p) >>\n\nParameters: C<message> is display text and C<p> contains options.\nReturns: C<Boolean> for C<confirm> or C<Window> for\nC<confirm_window>. Shows or builds a confirmation dialogue.\n\n=item C<< prompt(String message, ... PairList p) >>, C<< prompt_window(String message, ... PairList p) >>\n\nParameters: C<message> is prompt text and C<p> contains options such as\nC<value>. Returns: C<String> or C<null> for C<prompt>, or C<Window> for\nC<prompt_window>. Shows or builds a text prompt.\n\n=item C<< file_open(... PairList p) >>, C<< file_save(... PairList p) >>\n\nParameters: C<p> contains dialogue options. Returns: path value or\nC<null>. Opens a file selection dialogue.\n\n=item C<< directory_open(... PairList p) >>, C<< directory_save(... PairList p) >>\n\nParameters: C<p> contains dialogue options. Returns: path value or\nC<null>. Opens a directory selection dialogue.\n\n=item C<< colour_picker(... PairList p) >>\n\nParameters: C<p> contains dialogue options. Returns: C<String> or\nC<null>. Opens a colour picker and returns a normalized colour string.\n\n=item C<< file_open_window(... PairList p) >>, C<< file_save_window(... PairList p) >>, C<< directory_open_window(... PairList p) >>, C<< directory_save_window(... PairList p) >>, C<< colour_picker_window(... PairList p) >>\n\nParameters: C<p> contains dialogue options. Returns: C<Window>. Builds\nthe corresponding GUI dialogue window.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/gui/dialogue >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/gui try import\n	EM,\n	Window,\n	VBox,\n	HBox,\n	Label,\n	Text,\n	Input,\n	Button,\n	Widget,\n	native_file_open,\n	native_file_save,\n	native_directory_open,\n	native_directory_save,\n	native_colour_picker;\nfrom std/gui/objects try import\n	meta as _objects_meta,\n	native_alert,\n	native_confirm,\n	native_prompt;\nfrom std/colour import parse_colour;\nfrom std/string import split;\nfrom std/tui import\n	colour_text,\n	directory_completions,\n	filename_completions,\n	readline;\n\nfunction _tui_string ( value ) {\n	return value \u2261 null ? "" : "" _ value;\n}\n\nfunction _gui_backend () {\n	if ( _objects_meta \u2262 null ) {\n		return _objects_meta{backend};\n	}\n	return "";\n}\n\nfunction _path_dialogue_unsupported () {\n	if ( __system__{deny_fs} ) {\n		die "GUI_DIALOGUE_FS_DENIED: file and directory dialogues require filesystem capability";\n	}\n	if ( _gui_backend() eq "browser-dom" ) {\n		die "GUI_DIALOGUE_UNSUPPORTED: file and directory dialogues are unsupported in JS/Browser";\n	}\n}\n\nfunction _tui_prompt ( String message, PairList p, String default_value ) {\n	return readline(\n		colour_text( message _ " ", "cyan" ),\n		default_value,\n		null,\n	);\n}\n\nfunction _tui_path_dialog (\n	String label,\n	String default_value,\n	completion,\n	PairList p\n) {\n	let answer := readline(\n		colour_text( p.get( "label", label ) _ " ", "cyan" ),\n		_tui_string( p.get( "value", default_value ) ),\n		completion,\n	);\n	if ( p.get( "multiple", false ) ) {\n		return split( answer, p.get( "separator", "\\n" ) );\n	}\n	return answer;\n}\n\nfunction _parse_colour_or_null ( value ) {\n	return try {\n		parse_colour( _tui_string(value) );\n	}\n	catch {\n		null;\n	};\n}\n\nfunction _colour_initial_value ( PairList p ) {\n	let raw := _tui_string( p.get( "value", "#000000" ) );\n	let parsed := _parse_colour_or_null(raw);\n	return parsed \u2262 null ? parsed : raw;\n}\n\nfunction _colour_default_value ( PairList p ) {\n	return _parse_colour_or_null( p.get( "value", "#000000" ) ) ?: "#000000";\n}\n\nfunction _tui_colour_dialog ( PairList p ) {\n	let default_value := _colour_default_value(p);\n	while ( true ) {\n		let answer := readline(\n			colour_text( p.get( "label", "Colour:" ) _ " ", "cyan" ),\n			default_value,\n			null,\n		);\n		let parsed := _parse_colour_or_null(answer);\n		if ( parsed \u2262 null ) {\n			return parsed;\n		}\n		say( colour_text( "Invalid colour; try #336699 or red.", "yellow" ) );\n	}\n}\n\nfunction _dialogue_window (\n	String kind,\n	String title,\n	Widget body,\n	Array buttons,\n	PairList p\n) {\n	let button_row := HBox(\n		id: "buttons",\n		align: "right",\n		gap: 6,\n		height: p.get( "button_row_height", 2.125 \xD7 EM ),\n		maxheight: p.get( "button_row_height", 2.125 \xD7 EM ),\n	);\n	for ( let button in buttons ) {\n		button_row.add_child(button);\n	}\n	let w := Window(\n		title: title,\n		width: p.get( "width", 360 ),\n		height: p.get( "height", 180 ),\n		resizable: p.get( "resizable", false ),\n		modal: true,\n		VBox(\n			id: p.get( "id", null ),\n			gap: p.get( "gap", 8 ),\n			padding: p.get( "padding", 12 ),\n			body,\n			button_row,\n		),\n	);\n	w.meta( "dialogue.kind", kind );\n	return w;\n}\n\nfunction _message_body ( String message, PairList p ) {\n	return Text(\n		id: p.get( "message_id", "message" ),\n		value: message,\n		readonly: true,\n		wrap: true,\n	);\n}\n\nfunction _primary_button ( PairList p, String fallback ) {\n	return Button(\n		id: p.get( "ok_id", "ok" ),\n		text: p.get( "ok_text", fallback ),\n		variant: "primary",\n		width: p.get( "button_width", 5.5 \xD7 EM ),\n		height: p.get( "button_height", 1.75 \xD7 EM ),\n		maxheight: p.get( "button_height", 1.75 \xD7 EM ),\n	);\n}\n\nfunction _cancel_button ( PairList p ) {\n	return Button(\n		id: p.get( "cancel_id", "cancel" ),\n		text: p.get( "cancel_text", "Cancel" ),\n		width: p.get( "button_width", 5.5 \xD7 EM ),\n		height: p.get( "button_height", 1.75 \xD7 EM ),\n		maxheight: p.get( "button_height", 1.75 \xD7 EM ),\n	);\n}\n\nfunction _alert_window ( String message, PairList p ) {\n	let ok := _primary_button( p, "OK" );\n	let w := _dialogue_window(\n		"alert",\n		p.get( "title", "Alert" ),\n		_message_body( message, p ),\n		[ ok ],\n		p,\n	);\n	ok.click( function () {\n		w.close(null);\n	} );\n	return w;\n}\n\nfunction alert_window ( String message, ... PairList p ) {\n	return _alert_window( message, p );\n}\n\nfunction alert ( String message, ... PairList p ) {\n	if ( p.has("auto_result") ) {\n		return null;\n	}\n	if ( __system__{deny_gui} ) {\n		say( colour_text( message, "yellow" ) );\n		return null;\n	}\n	if ( native_alert \u2262 null ) {\n		let native_result := native_alert( message, p );\n		if ( native_result ) {\n			return null;\n		}\n	}\n	return _alert_window( message, p ).call();\n}\n\nfunction _confirm_window ( String message, PairList p ) {\n	let ok := _primary_button( p, p.get( "ok_text", "OK" ) );\n	let cancel := _cancel_button(p);\n	let w := _dialogue_window(\n		"confirm",\n		p.get( "title", "Confirm" ),\n		_message_body( message, p ),\n		[ cancel, ok ],\n		p,\n	);\n	ok.click( function () {\n		w.close(true);\n	} );\n	cancel.click( function () {\n		w.close(false);\n	} );\n	return w;\n}\n\nfunction confirm_window ( String message, ... PairList p ) {\n	return _confirm_window( message, p );\n}\n\nfunction confirm ( String message, ... PairList p ) {\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result") ? true : false;\n	}\n	if ( __system__{deny_gui} ) {\n		let yes_default := p.get( "value", p.get( "default", false ) );\n		let suffix := yes_default ? " [Y/n] " : " [y/N] ";\n		let answer := readline(\n			colour_text( message _ suffix, "cyan" ),\n			yes_default ? "y" : "n",\n			null,\n		);\n		return ( answer ~ /^(?:y|yes|1|true)$/i ) ? true : false;\n	}\n	if ( native_confirm \u2262 null ) {\n		let native_result := native_confirm( message, p );\n		if ( native_result \u2262 null ) {\n			return native_result ? true : false;\n		}\n	}\n	return _confirm_window( message, p ).call() ? true : false;\n}\n\nfunction _prompt_window ( String message, PairList p ) {\n	let input := Input(\n		id: p.get( "input_id", "value" ),\n		value: p.get( "value", "" ),\n		placeholder: p.get( "placeholder", "" ),\n	);\n	let ok := _primary_button( p, p.get( "ok_text", "OK" ) );\n	let cancel := _cancel_button(p);\n	let w := _dialogue_window(\n		"prompt",\n		p.get( "title", "Prompt" ),\n		VBox(\n			gap: 6,\n			_message_body( message, p ),\n			input,\n		),\n		[ cancel, ok ],\n		p,\n	);\n	ok.click( function () {\n		w.close( input.value() );\n	} );\n	cancel.click( function () {\n		w.close(null);\n	} );\n	return w;\n}\n\nfunction prompt_window ( String message, ... PairList p ) {\n	return _prompt_window( message, p );\n}\n\nfunction prompt ( String message, ... PairList p ) {\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result");\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_prompt(\n			message,\n			p,\n			_tui_string( p.get( "value", "" ) ),\n		);\n	}\n	if ( native_prompt \u2262 null ) {\n		let native_result := native_prompt( message, p );\n		if ( _gui_backend() eq "browser-dom" ) {\n			return native_result;\n		}\n		if ( native_result \u2262 null ) {\n			return native_result;\n		}\n	}\n	return _prompt_window( message, p ).call();\n}\n\nfunction _path_dialog_window (\n	String kind,\n	String title,\n	String label,\n	String default_value,\n	PairList p\n) {\n	let input := Input(\n		id: p.get( "input_id", "path" ),\n		value: p.get( "value", default_value ),\n		placeholder: p.get( "placeholder", "" ),\n		multiline: p.get( "multiple", false ),\n	);\n	let ok := _primary_button( p, p.get( "ok_text", "OK" ) );\n	let cancel := _cancel_button(p);\n	let w := _dialogue_window(\n		kind,\n		p.get( "title", title ),\n		VBox(\n			gap: 6,\n			Label( text: p.get( "label", label ), ("for"): input.id() ),\n			input,\n		),\n		[ cancel, ok ],\n		p,\n	);\n	ok.click( function () {\n		if ( p.get( "multiple", false ) ) {\n			w.close( split( input.value(), p.get( "separator", "\\n" ) ) );\n		}\n		else {\n			w.close( input.value() );\n		}\n	} );\n	cancel.click( function () {\n		w.close(null);\n	} );\n	return w;\n}\n\nfunction file_open_window ( ... PairList p ) {\n	return _path_dialog_window( "file_open", "Open File", "File:", "", p );\n}\n\nfunction file_save_window ( ... PairList p ) {\n	return _path_dialog_window( "file_save", "Save File", "File:", "", p );\n}\n\nfunction directory_open_window ( ... PairList p ) {\n	return _path_dialog_window(\n		"directory_open",\n		"Open Directory",\n		"Directory:",\n		"",\n		p,\n	);\n}\n\nfunction directory_save_window ( ... PairList p ) {\n	return _path_dialog_window(\n		"directory_save",\n		"Save Directory",\n		"Directory:",\n		"",\n		p,\n	);\n}\n\nfunction _colour_picker_window ( PairList p ) {\n	let input := Input(\n		id: p.get( "input_id", "path" ),\n		value: _colour_initial_value(p),\n		placeholder: p.get( "placeholder", "#336699" ),\n	);\n	let ok := _primary_button( p, p.get( "ok_text", "OK" ) );\n	let cancel := _cancel_button(p);\n	let default_value := _colour_default_value(p);\n	let sync_ok := function () {\n		ok.set_enabled( _parse_colour_or_null( input.value() ) \u2262 null );\n	};\n	let w := _dialogue_window(\n		"colour_picker",\n		p.get( "title", "Choose Colour" ),\n		VBox(\n			gap: 6,\n			Label(\n				text: p.get( "label", "Colour:" ),\n				("for"): input.id(),\n			),\n			input,\n		),\n		[ cancel, ok ],\n		p,\n	);\n	sync_ok();\n	input.on( "change", sync_ok );\n	ok.click( function () {\n		let parsed := _parse_colour_or_null( input.value() );\n		if ( parsed \u2262 null ) {\n			w.close(parsed);\n		}\n	} );\n	cancel.click( function () {\n		w.close(default_value);\n	} );\n	return w;\n}\n\nfunction colour_picker_window ( ... PairList p ) {\n	return _colour_picker_window(p);\n}\n\nfunction file_open ( ... PairList p ) {\n	_path_dialogue_unsupported();\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result");\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_path_dialog( "File:", "", filename_completions, p );\n	}\n	return native_file_open(p);\n}\n\nfunction file_save ( ... PairList p ) {\n	_path_dialogue_unsupported();\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result");\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_path_dialog( "File:", "", filename_completions, p );\n	}\n	return native_file_save(p);\n}\n\nfunction directory_open ( ... PairList p ) {\n	_path_dialogue_unsupported();\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result");\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_path_dialog(\n			"Directory:",\n			"",\n			directory_completions,\n			p,\n		);\n	}\n	return native_directory_open(p);\n}\n\nfunction directory_save ( ... PairList p ) {\n	_path_dialogue_unsupported();\n	if ( p.has("auto_result") ) {\n		return p.get("auto_result");\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_path_dialog(\n			"Directory:",\n			"",\n			directory_completions,\n			p,\n		);\n	}\n	if ( native_directory_save \u2262 null ) {\n		let native_result := native_directory_save(p);\n		if ( native_result \u2262 null ) {\n			return native_result;\n		}\n		if ( _gui_backend() eq "electron-dom" ) {\n			return null;\n		}\n	}\n	return _path_dialog_window(\n		"directory_save",\n		"Save Directory",\n		"Directory:",\n		"",\n		p,\n	).call();\n}\n\nfunction colour_picker ( ... PairList p ) {\n	if ( p.has("auto_result") ) {\n		return parse_colour( _tui_string( p.get("auto_result") ) );\n	}\n	if ( __system__{deny_gui} ) {\n		return _tui_colour_dialog(p);\n	}\n	if ( native_colour_picker \u2262 null ) {\n		let native_result := native_colour_picker(p);\n		if ( native_result \u2262 null ) {\n			return parse_colour(native_result);\n		}\n		if ( _gui_backend() eq "browser-dom" ) {\n			return null;\n		}\n	}\n	if ( _gui_backend() eq "electron-dom" ) {\n		return _colour_picker_window(p).call();\n	}\n	return parse_colour( _colour_picker_window(p).call() );\n}\n';
        virtualFiles["/modules/std/uuid.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/uuid - Pure ZuzuScript UUID v1 generator.\n\n=head1 SYNOPSIS\n\n  from std/uuid import create_uuid, create_uuid_binary;\n\n  let text := create_uuid();\n  let raw := create_uuid_binary();\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module implements UUID version 1 generation using only\nZuzuScript code.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item * C<create_uuid_binary()>\n\nParameters: none. Returns: C<BinaryString>. Returns a single UUID as 16\nraw bytes.\n\n=item * C<create_uuid()>\n\nParameters: none. Returns: C<String>. Returns a single UUID as\nlowercase hexadecimal text with hyphens in the usual C<8-4-4-4-12>\nlayout.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/uuid >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/math import Math;\nfrom std/string import substr;\nfrom std/string/base64 import decode;\nfrom std/time import Time;\n\nlet _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\nlet _HEX_ALPHABET := "0123456789abcdef";\n\nfunction _div_floor ( Number n, Number d ) {\n	return floor( n / d );\n}\n\nfunction _mod ( Number n, Number d ) {\n	return n - _div_floor( n, d ) * d;\n}\n\nfunction _rand_int ( Number max ) {\n	return floor( Math.rand(max) );\n}\n\nfunction _bytes_to_binary ( Array bytes ) {\n	let out := "";\n	let i := 0;\n	let n := bytes.length();\n\n	while ( i < n ) {\n		let b0 := bytes[i];\n		let b1 := null;\n		let b2 := null;\n		if ( i + 1 < n ) {\n			b1 := bytes[i + 1];\n		}\n		if ( i + 2 < n ) {\n			b2 := bytes[i + 2];\n		}\n\n		let c0 := _div_floor( b0, 4 );\n		let c1 := _mod( b0, 4 ) * 16;\n		let c2 := 64;\n		let c3 := 64;\n\n		if ( b1 \u2262 null ) {\n			c1 += _div_floor( b1, 16 );\n			c2 := _mod( b1, 16 ) * 4;\n			if ( b2 \u2262 null ) {\n				c2 += _div_floor( b2, 64 );\n				c3 := _mod( b2, 64 );\n			}\n		}\n\n		out _= substr( _B64_ALPHABET, c0, 1 );\n		out _= substr( _B64_ALPHABET, c1, 1 );\n		if ( c2 \u2261 64 ) {\n			out _= "=";\n		}\n		else {\n			out _= substr( _B64_ALPHABET, c2, 1 );\n		}\n		if ( c3 \u2261 64 ) {\n			out _= "=";\n		}\n		else {\n			out _= substr( _B64_ALPHABET, c3, 1 );\n		}\n\n		i += 3;\n	}\n\n	return decode(out);\n}\n\nfunction _timestamp_words () {\n	// Seconds between 1582-10-15 and 1970-01-01.\n	let epoch_offset := 12219292800;\n	let seconds := new Time().epoch() + epoch_offset;\n	let ticks := _rand_int(10000000);\n\n	let words := [\n		_mod( seconds, 65536 ),\n		_mod( _div_floor( seconds, 65536 ), 65536 ),\n		_mod( _div_floor( seconds, 4294967296 ), 65536 ),\n		0,\n		0,\n	];\n\n	let scale := 10000000;\n	let i := 0;\n	let carry := 0;\n	while ( i < words.length() ) {\n		let product := words[i] * scale + carry;\n		words[i] := _mod( product, 65536 );\n		carry := _div_floor( product, 65536 );\n		i++;\n	}\n\n	let add_i := 0;\n	let add_carry := ticks;\n	while ( add_carry > 0 and add_i < words.length() ) {\n		let sum := words[add_i] + _mod( add_carry, 65536 );\n		words[add_i] := _mod( sum, 65536 );\n		add_carry := _div_floor( add_carry, 65536 ) + _div_floor( sum, 65536 );\n		add_i++;\n	}\n\n	return words;\n}\n\nfunction _create_uuid_bytes () {\n	let words := _timestamp_words();\n	let time_low := words[0] + words[1] * 65536;\n	let time_mid := words[2];\n	let time_hi_and_version := _mod( words[3], 4096 ) + 4096;\n\n	let clock_seq := _rand_int(16384);\n	let clock_seq_hi_and_reserved := _mod( _div_floor( clock_seq, 256 ), 64 ) + 128;\n	let clock_seq_low := _mod( clock_seq, 256 );\n\n	let node := [];\n	let j := 0;\n	while ( j < 6 ) {\n		node.push( _rand_int(256) );\n		j++;\n	}\n	// Multicast bit set means this is not an IEEE MAC address.\n	node[0] := node[0] | 1;\n\n	return [\n		_mod( _div_floor( time_low, 16777216 ), 256 ),\n		_mod( _div_floor( time_low, 65536 ), 256 ),\n		_mod( _div_floor( time_low, 256 ), 256 ),\n		_mod( time_low, 256 ),\n		_mod( _div_floor( time_mid, 256 ), 256 ),\n		_mod( time_mid, 256 ),\n		_mod( _div_floor( time_hi_and_version, 256 ), 256 ),\n		_mod( time_hi_and_version, 256 ),\n		clock_seq_hi_and_reserved,\n		clock_seq_low,\n		node[0],\n		node[1],\n		node[2],\n		node[3],\n		node[4],\n		node[5],\n	];\n}\n\nfunction _byte_to_hex ( Number b ) {\n	let hi := _div_floor( b, 16 );\n	let lo := _mod( b, 16 );\n	return substr( _HEX_ALPHABET, hi, 1 ) _ substr( _HEX_ALPHABET, lo, 1 );\n}\n\nfunction _bytes_to_uuid_text ( Array bytes ) {\n	let out := "";\n	let i := 0;\n	while ( i < 16 ) {\n		out _= _byte_to_hex( bytes[i] );\n		if ( i \u2261 3 or i \u2261 5 or i \u2261 7 or i \u2261 9 ) {\n			out _= "-";\n		}\n		i++;\n	}\n	return out;\n}\n\nfunction create_uuid_binary () {\n	return _bytes_to_binary( _create_uuid_bytes() );\n}\n\nfunction create_uuid () {\n	return _bytes_to_uuid_text( _create_uuid_bytes() );\n}\n';
        virtualFiles["/modules/std/dump.zzm"] = `=encoding utf8

=head1 NAME

std/dump - Structured value dumper for ZuzuScript.

=head1 SYNOPSIS

  from std/dump import Dumper;

  let text := Dumper.dump(
    { nums: [ 1, 2, 3 ] },
    { pretty: true, sort_keys: true }
  );

=head1 IMPLEMENTATION SUPPORT

This module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

This module provides a pure-Zuzu C<Dumper> class which serializes
Zuzu values into code-like text.

If a value cannot be realistically dumped (for example a function),
C<Dumper> emits a warning and inserts C<null> in that location.

=head1 EXPORTS

=head2 Classes

=over

=item C<Dumper>

Pure-Zuzu structured value dumper.

=over

=item C<< Dumper.dump(value, options?) >>

Parameters: C<value> is any ZuzuScript value and C<options> is an
optional dictionary. Returns: C<String>. Serializes C<value> into
code-like text.

=back

=back

=head1 COPYRIGHT AND LICENCE

B<< std/dump >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/internals import class_name, object_slots, ansi_esc, ref_id;
from std/string import join, substr;

let _ANSI_RESET := ansi_esc() _ "[0m";
let _ANSI_NUMBER := ansi_esc() _ "[33m";
let _ANSI_STRING := ansi_esc() _ "[32m";
let _ANSI_BOOL := ansi_esc() _ "[35m";
let _ANSI_NULL := ansi_esc() _ "[90m";
let _ANSI_PUNC := ansi_esc() _ "[36m";
let _ANSI_KEYWORD := ansi_esc() _ "[34m";

function _is_true (value) {
	return value ? true: false;
}

function _warn_unless_quiet ( String msg, Dict cfg ) {
	warn msg if not cfg{quiet};
}

function _indent_pad ( depth, cfg ) {
	return "" if not cfg{pretty};
	let out := "";
	let i := 0;
	while ( i < depth ) {
		out _= "  ";
		i++;
	}

	return out;
}

function _colourize ( String text, String tone, Dict cfg ) {
	return text if not cfg{colour};
	return tone _ text _ _ANSI_RESET;
}

function _punc ( String text, Dict cfg ) {
	return _colourize( text, _ANSI_PUNC, cfg );
}

function _quote ( String text, Dict cfg ) {
	let s := text;
	s := "" if s \u2261 null;
	let out := "";
	let i := 0;
	let n := length s;

	while ( i < n ) {
		let ch := substr( s, i, 1 );
		if ( ch \u2261 "\\\\" ) {
			out _= "\\\\\\\\";
		}
		else if ( ch \u2261 "\\"" ) {
			out _= "\\\\\\"";
		}
		else if ( ch \u2261 "\\n" ) {
			out _= "\\\\n";
		}
		else if ( ch \u2261 "\\r" ) {
			out _= "\\\\r";
		}
		else if ( ch \u2261 "\\t" ) {
			out _= "\\\\t";
		}
		else {
			out _= ch;
		}
		i++;
	}

	return _colourize( "\\"" _ out _ "\\"", _ANSI_STRING, cfg );
}

function _keys_for ( Dict d, Dict cfg ) {
	return cfg{sort_keys} ? d.sorted_keys(): d.keys();
}

function _null_literal ( Dict cfg ) {
	return _colourize( "null", _ANSI_NULL, cfg );
}

function _seen_check_and_mark ( value, String label, Dict cfg, Dict state ) {
	let id := ref_id(value);
	if ( id \u2262 null and state{seen}.exists(id) ) {
		_warn_unless_quiet( "Dumper: recursive " _ label _ " detected; dumping null", cfg );
		return true;
	}
	if ( id \u2262 null ) {
		state{seen}.set( id, true );
	}

	return false;
}

function _dump_value ( value, Dict cfg, Dict state, Number depth ) {
	if ( value instanceof Null ) {
		return _null_literal(cfg);
	}
	if ( value instanceof Boolean ) {
		return _colourize( value ? "true": "false", _ANSI_BOOL, cfg );
	}
	if ( value instanceof Number ) {
		return _colourize( "" _ value, _ANSI_NUMBER, cfg );
	}
	if ( value instanceof String ) {
		return _quote( value, cfg );
	}

	if ( value instanceof Array ) {
		return _null_literal(cfg) if _seen_check_and_mark( value, "array", cfg, state );
		if ( value.length() \u2261 0 ) {
			return _punc( "[", cfg ) _ _punc( "]", cfg );
		}
		let pretty := cfg{pretty};
		let sep := pretty ? _punc( ",\\n", cfg ): _punc(",", cfg );
		let parts := [];
		for ( let item in value ) {
			parts.push( _dump_value( item, cfg, state, depth + 1 ) );
		}
		if ( not pretty ) {
			return _punc( "[", cfg ) _ join( sep, parts ) _ _punc( "]", cfg );
		}
		let inner := [];
		for ( let p in parts ) {
			inner.push( _indent_pad( depth + 1, cfg ) _ p );
		}
		return _punc( "[\\n", cfg ) _ join( sep, inner ) _ _punc( "\\n", cfg ) _ _indent_pad( depth, cfg ) _
		    _punc( "]", cfg );
	}

	if ( value instanceof Dict ) {
		return _null_literal(cfg) if _seen_check_and_mark( value, "dict", cfg, state );
		let keys := _keys_for( value, cfg );
		if ( keys.length() \u2261 0 ) {
			return _punc( "{" , cfg ) _ _punc( "}", cfg );
		}
		let pretty := cfg{pretty};
		let sep := pretty ? _punc( ",\\n", cfg ): _punc(",", cfg );
		let colon := pretty ? _punc( ": ", cfg ): _punc(":", cfg );
		let entries := [];
		for ( let key in keys ) {
			let dumped := _dump_value( value.get(key), cfg, state, depth + 1 );
			entries.push( _quote( key, cfg ) _ colon _ dumped );
		}
		if ( not pretty ) {
			return _punc( "{" , cfg ) _ join( sep, entries ) _ _punc( "}", cfg );
		}
		let inner := [];
		for ( let e in entries ) {
			inner.push( _indent_pad( depth + 1, cfg ) _ e );
		}
		return _punc( "{\\n", cfg ) _ join( sep, inner ) _ _punc( "\\n", cfg ) _ _indent_pad( depth, cfg ) _
		    _punc( "}", cfg );
	}

	if ( value instanceof PairList ) {
		return _null_literal(cfg) if _seen_check_and_mark( value, "pairlist", cfg, state );
		if ( value.empty ) {
			return _punc( "{{" , cfg ) _ _punc( "}}", cfg );
		}
		let pretty := cfg{pretty};
		let sep := pretty ? _punc( ",\\n", cfg ): _punc(",", cfg );
		let colon := pretty ? _punc( ": ", cfg ): _punc(":", cfg );
		let entries := [];
		value.for_each_pair( function (p) {
			let dumped := _dump_value( p.value, cfg, state, depth + 1 );
			entries.push( _quote( p.key, cfg ) _ colon _ dumped );
		} );
		if ( not pretty ) {
			return _punc( "{{" , cfg ) _ join( sep, entries ) _ _punc( "}}", cfg );
		}
		let inner := [];
		for ( let e in entries ) {
			inner.push( _indent_pad( depth + 1, cfg ) _ e );
		}
		return _punc( "{{\\n", cfg ) _ join( sep, inner ) _ _punc( "\\n", cfg ) _ _indent_pad( depth, cfg ) _
		    _punc( "}}", cfg );
	}

	if ( value instanceof Set or value instanceof Bag ) {
		let is_set := value instanceof Set;
		return _null_literal(cfg)
			if _seen_check_and_mark( value, is_set ? "set" : "bag", cfg, state );
		let left := is_set ? "<<": "<<<";
		let right := is_set ? ">>": ">>>";
		let sep := cfg{pretty} ? _punc( ", ", cfg ): _punc(",", cfg );
		let items := [];
		for ( let item in value ) {
			items.push( _dump_value( item, cfg, state, depth + 1 ) );
		}
		return _punc( left, cfg ) _ join( sep, items ) _ _punc( right, cfg );
	}

	if ( value instanceof Pair ) {
		let pair_value := value{pair};
		if ( not( pair_value instanceof Array ) or pair_value.length() < 2 ) {
			_warn_unless_quiet( "Dumper: invalid Pair shape; using null", cfg );
			return _null_literal(cfg);
		}
		let first := _dump_value( pair_value[0], cfg, state, depth + 1 );
		let second := _dump_value( pair_value[1], cfg, state, depth + 1 );
		let body := _punc( "[", cfg ) _ first _ _punc(",", cfg ) _ second _ _punc( "]", cfg );
		let kw_new := _colourize( "new", _ANSI_KEYWORD, cfg );
		return kw_new _ " Pair" _ _punc("(", cfg ) _ "pair" _ _punc(":", cfg ) _ body _ _punc(")", cfg );
	}

	if (
		value instanceof Function or
		value instanceof Class or
		typeof value \u2261 "Regexp" or
		typeof value \u2261 "Method"
	) {
		let t := typeof value;
		_warn_unless_quiet( "Dumper: value of type '" _ t _ "' is not dumpable; using null", cfg, );
		return _null_literal(cfg);
	}
	return _null_literal(cfg) if _seen_check_and_mark( value, "object", cfg, state );
	let cname := class_name(value);
	let slots := object_slots(value);
	if ( cname \u2261 null or not( slots instanceof Dict ) ) {
		_warn_unless_quiet( "Dumper: object internals unavailable; dumping null", cfg );
		return _null_literal(cfg);
	}
	let keys := _keys_for( slots, cfg );
	let colon := cfg{pretty} ? _punc( ": ", cfg ): _punc(":", cfg );
	let args := [];
	for ( let key in keys ) {
		args.push( key _ colon _ _dump_value( slots.get(key), cfg, state, depth + 1 ) );
	}
	let kw_new := _colourize( "new", _ANSI_KEYWORD, cfg );
	if ( args.length() \u2261 0 ) {
		return kw_new _ " " _ cname _ _punc( "()", cfg );
	}
	if ( not cfg{pretty} ) {
		return kw_new _ " " _ cname _ _punc("(", cfg ) _ join( _punc(",", cfg ), args ) _ _punc(")", cfg );
	}
	let inner := [];
	for ( let arg in args ) {
		inner.push( _indent_pad( depth + 1, cfg ) _ arg );
	}
	return kw_new _ " " _ cname _ _punc( "(\\n", cfg ) _ join( _punc( ",\\n", cfg ), inner ) _ _punc( "\\n",
	    cfg ) _ _indent_pad( depth, cfg ) _ _punc(")", cfg );
}

class Dumper {

	static method dump ( value, options? ) {
		let cfg := { pretty: false, sort_keys: false, colour: false, quiet: false };
		if ( options instanceof Dict ) {
			cfg{pretty} := _is_true( options{pretty} ) if "pretty" in options;
			cfg{sort_keys} := _is_true( options{sort_keys} ) if "sort_keys" in options;
			cfg{colour} := _is_true( options{colour} ) if "colour" in options;
			cfg{quiet} := _is_true( options{quiet} ) if "quiet" in options;
		}
		return _dump_value( value, cfg, { seen: {} }, 0 );
	}

}
`;
        virtualFiles["/modules/std/data/cbor.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/cbor - CBOR encoding and decoding for ZuzuScript.\n\n=head1 SYNOPSIS\n\n  from std/data/cbor import CBOR, TaggedValue;\n\n  let codec := new CBOR();\n  let bytes := codec.encode({ answer: 42 });\n  let value := codec.decode(bytes);\n\n  // Decode CBOR maps to Zuzu PairLists instead of Dicts.\n  // This preserves key order and allows duplicate keys.\n  codec := new CBOR( pairlists: true );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and\nElectron. It is partially supported by zuzu-js in the browser: in-memory\nCBOR encode/decode coverage passes, but file-backed load/dump coverage is\nunsupported because browser filesystem capability is unavailable.\n\n=head1 DESCRIPTION\n\nPure-Zuzu implementation of CBOR (RFC 8949).\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< TaggedValue({ tag: Number, value: value }) >>\n\nConstructs a tagged CBOR value. Returns: C<TaggedValue>. Stores the CBOR\ntag number and associated value.\n\n=item C<< CBOR({ pairlists?: Boolean }) >>\n\nConstructs a CBOR codec. Returns: C<CBOR>. The C<pairlists> option makes\ndecoded maps return as C<PairList> values instead of C<Dict> values.\n\n=over\n\n=item C<< codec.encode(value) >>\n\nParameters: C<value> is any CBOR-encodable ZuzuScript value. Returns:\nC<BinaryString>. Encodes C<value> as CBOR bytes.\n\n=item C<< codec.encode_binarystring(value) >>\n\nAlias for C<codec.encode(value)>.\n\n=item C<< codec.decode(BinaryString raw) >>\n\nParameters: C<raw> is CBOR data. Returns: value. Decodes CBOR bytes into\nthe equivalent ZuzuScript value.\n\n=item C<< codec.decode_binarystring(BinaryString raw) >>\n\nAlias for C<codec.decode(raw)>.\n\n=item C<< codec.load(Path path) >>\n\nParameters: C<path> is a C<std/io> C<Path>. Returns: value. Reads CBOR\nbytes from C<path> and decodes them.\n\n=item C<< codec.dump(Path path, value) >>\n\nParameters: C<path> is a C<std/io> C<Path> and C<value> is any\nCBOR-encodable value. Returns: C<null>. Encodes C<value> and writes CBOR\nbytes to C<path>.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/cbor >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import substr, index;\nfrom std/string/base64 import encode, decode;\nfrom std/time import Time;\n\n\nlet _B64_ALPHABET  := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\n\n// Set to "PairList" to return CBOR objects as Zuzu PairLists.\nlet _DECODE_MAP_AS := "Dict";\n\nclass TaggedValue {\n	let Number tag;\n	let value;\n}\n\nfunction _div_floor ( Number n, Number d ) {\n	return floor( n / d ); // fix syntax highlighting\n}\n\nfunction _mod ( Number n, Number d ) {\n	return n - _div_floor( n, d ) * d;\n}\n\nfunction _bytes_to_binary ( Array bytes ) {\n	let out := "";\n	let i := 0;\n	let n := bytes.length();\n\n	while ( i < n ) {\n		let b0 := bytes[i];\n		let b1 := null;\n		let b2 := null;\n		if ( i + 1 < n ) {\n			b1 := bytes[i + 1];\n		}\n		if ( i + 2 < n ) {\n			b2 := bytes[i + 2];\n		}\n\n		let c0 := _div_floor( b0, 4 );\n		let c1 := _mod( b0, 4 ) * 16;\n		let c2 := 64;\n		let c3 := 64;\n\n		if ( b1 \u2262 null ) {\n			c1 += _div_floor( b1, 16 );\n			c2 := _mod( b1, 16 ) * 4;\n			if ( b2 \u2262 null ) {\n				c2 += _div_floor( b2, 64 );\n				c3 := _mod( b2, 64 );\n			}\n		}\n\n		out _= substr( _B64_ALPHABET, c0, 1 );\n		out _= substr( _B64_ALPHABET, c1, 1 );\n		if ( c2 \u2261 64 ) {\n			out _= "=";\n		}\n		else {\n			out _= substr( _B64_ALPHABET, c2, 1 );\n		}\n		if ( c3 \u2261 64 ) {\n			out _= "=";\n		}\n		else {\n			out _= substr( _B64_ALPHABET, c3, 1 );\n		}\n		i += 3;\n	}\n\n	return decode(out);\n}\n\nfunction _binary_to_bytes ( BinaryString raw ) {\n	let b64 := encode(raw);\n	let out := [];\n	let i := 0;\n	let n := length b64;\n\n	while ( i < n ) {\n		let c0 := index( _B64_ALPHABET, substr( b64, i, 1 ) );\n		let c1 := index( _B64_ALPHABET, substr( b64, i + 1, 1 ) );\n		let ch2 := substr( b64, i + 2, 1 );\n		let ch3 := substr( b64, i + 3, 1 );\n		let c2 := -1;\n		let c3 := -1;\n		if ( ch2 \u2262 "=" ) {\n			c2 := index( _B64_ALPHABET, ch2 );\n		}\n		if ( ch3 \u2262 "=" ) {\n			c3 := index( _B64_ALPHABET, ch3 );\n		}\n\n		out.push( c0 * 4 + _div_floor( c1, 16 ) );\n\n		if ( c2 >= 0 ) {\n			out.push( _mod( c1, 16 ) * 16 + _div_floor( c2, 4 ) );\n		}\n		if ( c3 >= 0 ) {\n			out.push( _mod( c2, 4 ) * 64 + c3 );\n		}\n\n		i += 4;\n	}\n\n	return out;\n}\n\nfunction _is_int ( value ) {\n	if ( not( value instanceof Number ) ) {\n		return false;\n	}\n\n	return _mod( value, 1 ) \u2261 0;\n}\n\nfunction _emit_uint ( Array out, Number major, Number n ) {\n	if ( n < 24 ) {\n		out.push( major * 32 + n );\n		return;\n	}\n	if ( n < 256 ) {\n		out.push( major * 32 + 24 );\n		out.push(n);\n		return;\n	}\n	if ( n < 65536 ) {\n		out.push( major * 32 + 25 );\n		out.push( _mod( _div_floor( n, 256 ), 256 ) );\n		out.push( _mod( n, 256 ) );\n		return;\n	}\n	if ( n < 4294967296 ) {\n		out.push( major * 32 + 26 );\n		out.push( _mod( _div_floor( n, 16777216 ), 256 ) );\n		out.push( _mod( _div_floor( n, 65536 ), 256 ) );\n		out.push( _mod( _div_floor( n, 256 ), 256 ) );\n		out.push( _mod( n, 256 ) );\n		return;\n	}\n\n	let hi := _div_floor( n, 4294967296 );\n	let lo := _mod( n, 4294967296 );\n	out.push( major * 32 + 27 );\n	out.push( _mod( _div_floor( hi, 16777216 ), 256 ) );\n	out.push( _mod( _div_floor( hi, 65536 ), 256 ) );\n	out.push( _mod( _div_floor( hi, 256 ), 256 ) );\n	out.push( _mod( hi, 256 ) );\n	out.push( _mod( _div_floor( lo, 16777216 ), 256 ) );\n	out.push( _mod( _div_floor( lo, 65536 ), 256 ) );\n	out.push( _mod( _div_floor( lo, 256 ), 256 ) );\n	out.push( _mod( lo, 256 ) );\n}\n\nfunction _encode_value ( Array out, value ) {\n	if ( value \u2261 null ) {\n		out.push(246);\n		return;\n	}\n	if ( value \u2261 true ) {\n		out.push(245);\n		return;\n	}\n	if ( value \u2261 false ) {\n		out.push(244);\n		return;\n	}\n\n	if ( value instanceof Number ) {\n		die "CBOR.encode currently supports only integer Number values" if not _is_int(value);\n		if ( value >= 0 ) {\n			_emit_uint( out, 0, value );\n		}\n		else {\n			_emit_uint( out, 1, -1 - value );\n		}\n		return;\n	}\n\n	if ( value instanceof BinaryString ) {\n		let b := _binary_to_bytes(value);\n		_emit_uint( out, 2, b.length() );\n		let i := 0;\n		while ( i < b.length() ) {\n			out.push( b[i] );\n			i++;\n		}\n		return;\n	}\n\n	if ( value instanceof String ) {\n		let b := _binary_to_bytes( to_binary(value) );\n		_emit_uint( out, 3, b.length() );\n		let i := 0;\n		while ( i < b.length() ) {\n			out.push( b[i] );\n			i++;\n		}\n		return;\n	}\n\n	if ( value instanceof Array ) {\n		_emit_uint( out, 4, value.length() );\n		let i := 0;\n		while ( i < value.length() ) {\n			_encode_value( out, value[i] );\n			i++;\n		}\n		return;\n	}\n\n	if ( value instanceof Set ) {\n		_emit_uint( out, 6, 258 );\n		_encode_value( out, value.sortstr() );\n		return;\n	}\n\n	if ( value instanceof Bag ) {\n		_encode_value( out, value.sortstr() );\n		return;\n	}\n\n	if ( value instanceof PairList ) {\n		let pairs := value.to_Array();\n		_emit_uint( out, 5, pairs.length() );\n		let i := 0;\n		while ( i < pairs.length() ) {\n			let pair := pairs[i]{pair};\n			_encode_value( out, pair[0] );\n			_encode_value( out, pair[1] );\n			i++;\n		}\n		return;\n	}\n\n	if ( value instanceof Dict ) {\n		let keys := value.sorted_keys();\n		_emit_uint( out, 5, keys.length() );\n		let i := 0;\n		while ( i < keys.length() ) {\n			let k := keys[i];\n			_encode_value( out, k );\n			_encode_value( out, value.get(k) );\n			i++;\n		}\n		return;\n	}\n\n	if ( value instanceof TaggedValue ) {\n		_emit_uint( out, 6, value { tag } );\n		_encode_value( out, value { value } );\n		return;\n	}\n	if ( value instanceof Time ) {\n		_emit_uint( out, 6, 0 );\n		_encode_value( out, value.epoch() );\n		return;\n	}\n\n	die `CBOR cannot encode value of type ${typeof value}`;\n}\n\nfunction _read_uint ( Array bytes, Number ai, Number pos ) {\n	if ( ai < 24 ) {\n		return [ ai, pos ];\n	}\n	if ( ai \u2261 24 ) {\n		return [ bytes[pos], pos + 1 ];\n	}\n	if ( ai \u2261 25 ) {\n		return [ bytes[pos] * 256 + bytes[pos + 1], pos + 2 ];\n	}\n	if ( ai \u2261 26 ) {\n		return [ bytes[pos] * 16777216 + bytes[pos + 1] * 65536 + bytes[pos + 2] * 256 + bytes[pos + 3], pos + 4 ];\n	}\n	if ( ai \u2261 27 ) {\n		let hi := bytes[pos] * 16777216 + bytes[pos + 1] * 65536 + bytes[pos + 2] * 256 + bytes[pos + 3];\n		let lo := bytes[pos + 4] * 16777216 + bytes[pos + 5] * 65536 + bytes[pos + 6] * 256 + bytes[pos + 7];\n		return [ hi * 4294967296 + lo, pos + 8 ];\n	}\n\n	die `Unsupported CBOR additional info: ${ai}`;\n}\n\nfunction _decode_at ( Array bytes, Number pos ) {\n	let head := bytes[pos];\n	let major := _div_floor( head, 32 );\n	let ai := _mod( head, 32 );\n	let parsed := _read_uint( bytes, ai, pos + 1 );\n	let arg := parsed[0];\n	let p := parsed[1];\n\n	if ( major \u2261 0 ) {\n		return [ arg, p ];\n	}\n	if ( major \u2261 1 ) {\n		return [ -1 - arg, p ];\n	}\n	if ( major \u2261 2 ) {\n		let chunk := [];\n		let i := 0;\n		while ( i < arg ) {\n			chunk.push( bytes[p + i] );\n			i++;\n		}\n		return [ _bytes_to_binary(chunk), p + arg ];\n	}\n	if ( major \u2261 3 ) {\n		let chunk := [];\n		let i := 0;\n		while ( i < arg ) {\n			chunk.push( bytes[p + i] );\n			i++;\n		}\n		return [ to_string( _bytes_to_binary(chunk) ), p + arg ];\n	}\n	if ( major \u2261 4 ) {\n		let arr := [];\n		let i := 0;\n		let q := p;\n		while ( i < arg ) {\n			let item := _decode_at( bytes, q );\n			arr.push( item[0] );\n			q := item[1];\n			i++;\n		}\n		return [ arr, q ];\n	}\n	if ( major \u2261 5 ) {\n		let d := _DECODE_MAP_AS eq "PairList" ? new PairList() : new Dict();\n		let i := 0;\n		let q := p;\n		while ( i < arg ) {\n			let k := _decode_at( bytes, q );\n			let v := _decode_at( bytes, k[1] );\n			d.add( k[0], v[0] ) unless _DECODE_MAP_AS eq "Dict" and d.exists( k[0] );\n			q := v[1];\n			i++;\n		}\n		return [ d, q ];\n	}\n	if ( major \u2261 6 ) {\n		let tagged := _decode_at( bytes, p );\n		if ( arg \u2261 0 and tagged[0] instanceof Number ) {\n			return [ new Time( tagged[0] ), tagged[1] ];\n		}\n		if ( arg \u2261 258 and tagged[0] instanceof Array ) {\n			return [ tagged[0].to_Set(), tagged[1] ];\n		}\n		return [ new TaggedValue( tag: arg, value: tagged[0] ), tagged[1] ];\n	}\n	if ( major \u2261 7 ) {\n		if ( ai \u2261 20 ) {\n			return [ false, pos + 1 ];\n		}\n		if ( ai \u2261 21 ) {\n			return [ true, pos + 1 ];\n		}\n		if ( ai \u2261 22 ) {\n			return [ null, pos + 1 ];\n		}\n		die `Unsupported CBOR simple/float value (ai=${ai})`;\n	}\n\n	die `Unsupported CBOR major type: ${major}`;\n}\n\nclass CBOR {\n	let pairlists := false;\n\n	method encode ( value ) {\n		let out := [];\n		_encode_value( out, value );\n		return _bytes_to_binary(out);\n	}\n\n	method encode_binarystring ( value ) {\n		return self.encode(value);\n	}\n\n	method decode ( BinaryString raw ) {\n		_DECODE_MAP_AS := pairlists ? "PairList" : "Dict";\n		let bytes := _binary_to_bytes(raw);\n		let parsed := _decode_at( bytes, 0 );\n		die "Trailing bytes after CBOR value" if parsed[1] < bytes.length();\n		return parsed[0];\n	}\n\n	method decode_binarystring ( BinaryString raw ) {\n		return self.decode(raw);\n	}\n\n	method load ( path ) {\n		from std/io import Path;\n		die "CBOR.load is denied by runtime policy" if __system__{deny_fs};\n		die "CBOR.load expects a std/io Path object" if not( path instanceof Path );\n		return self.decode( path.slurp() );\n	}\n\n	method dump ( path, value ) {\n		from std/io import Path;\n		die "CBOR.dump is denied by runtime policy" if __system__{deny_fs};\n		die "CBOR.dump expects a std/io Path object" if not( path instanceof Path );\n		path.spew( self.encode(value) );\n		return path;\n	}\n}\n';
        virtualFiles["/modules/std/data/kdl.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/kdl - KDL parsing and serialization for ZuzuScript.\n\n=head1 SYNOPSIS\n\n  from std/data/kdl import KDL;\n\n  let kdl := new KDL();\n  let doc := kdl.decode("""\n    package name="zuzu" { version "0.1.0" }\n  """);\n  let text := kdl.encode(doc);\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and\nElectron. It is partially supported by zuzu-js in the browser: in-memory\nKDL parsing and serialization coverage passes, but fixture and load/dump\ncoverage is unsupported because browser filesystem capability is\nunavailable.\n\n=head1 DESCRIPTION\n\nThis module provides a pure-Zuzu implementation of the KDL document\nmodel and parser, with a user-facing API modelled on C<std/data/json>.\n\n=head1 EXPORTS\n\nThe parser returns explicit KDL model objects rather than generic Dict\nand Array structures.\n\n=head2 C<KDLDocument>\n\nC<KDLDocument> represents a complete parsed KDL document.\n\nConstructor fields:\n\n=over\n\n=item * C<nodes>\n\nAn Array of top-level C<KDLNode> objects. Defaults to an empty Array.\n\n=back\n\nMethods:\n\n=over\n\n=item C<nodes()>\n\nParameters: none. Returns: C<Array>. Returns the Array of top-level\nC<KDLNode> objects.\n\n=item C<to_Iterator()>\n\nParameters: none. Returns: C<Function>. Returns an iterator over the\ndocument\'s top-level nodes.\n\n=back\n\n=head2 C<KDLNode>\n\nC<KDLNode> represents one KDL node.\n\nConstructor fields:\n\n=over\n\n=item * C<name>\n\nThe node name as a String.\n\n=item * C<type_annotation>\n\nThe node type annotation as a String, or C<null> when unannotated.\n\n=item * C<args>\n\nAn Array of unnamed argument C<KDLValue> objects. Defaults to an empty\nArray.\n\n=item * C<props>\n\nA C<PairList> mapping property names to C<KDLValue> objects. Defaults\nto an empty C<PairList>, and preserves duplicate property names.\n\n=item * C<children>\n\nAn Array of child C<KDLNode> objects. Defaults to an empty Array.\n\n=back\n\nMethods:\n\n=over\n\n=item C<name()>\n\nParameters: none. Returns: C<String>. Returns the node name.\n\n=item C<type_annotation()>\n\nParameters: none. Returns: C<String> or C<null>. Returns the node type\nannotation.\n\n=item C<args()>\n\nParameters: none. Returns: C<Array>. Returns the unnamed argument\nC<KDLValue> objects.\n\n=item C<props()>\n\nParameters: none. Returns: C<PairList>. Returns the named property\nC<KDLValue> objects.\n\n=item C<children()>\n\nParameters: none. Returns: C<Array>. Returns the child C<KDLNode>\nobjects.\n\n=item C<to_Iterator()>\n\nParameters: none. Returns: C<Function>. Returns an iterator over the\nnode\'s arguments followed by its child nodes.\n\n=back\n\n=head2 C<KDLValue>\n\nC<KDLValue> represents an unnamed argument or named property value.\n\nConstructor fields:\n\n=over\n\n=item * C<type>\n\nThe KDL value type: C<null>, C<boolean>, C<number>, or C<string>.\nSome conversion helpers may create opaque C<KDLValue> objects with\nother type names; those are not KDL primitives.\n\n=item * C<kind>\n\nFor numbers, one of C<integer>, C<float>, or C<string>. C<string> is\nused for KDL number keywords such as C<#inf> that do not have a native\nJSON-like numeric value.\n\n=item * C<value>\n\nThe raw native value.\n\n=item * C<type_annotation>\n\nThe value type annotation as a String, or C<null> when unannotated.\n\n=item * C<canonical_number>\n\nThe canonical numeric spelling used by canonical serialization, or\nC<null>.\n\n=back\n\nMethods:\n\n=over\n\n=item C<type()>\n\nParameters: none. Returns: C<String>. Returns the value type.\n\n=item C<kind()>\n\nParameters: none. Returns: C<String> or C<null>. Returns the numeric\nkind for number values.\n\n=item C<value()>\n\nParameters: none. Returns: value. Returns the raw native value.\n\n=item C<type_annotation()>\n\nParameters: none. Returns: C<String> or C<null>. Returns the value type\nannotation.\n\n=item C<canonical_number()>\n\nParameters: none. Returns: C<String> or C<null>. Returns the canonical\nnumeric spelling.\n\n=item C<is_null()>, C<is_boolean()>, C<is_number()>, C<is_string()>\n\nParameters: none. Returns: C<Boolean>. Predicate methods for the four\nKDL primitive value types.\n\n=item C<is_true()>, C<is_false()>\n\nParameters: none. Returns: C<Boolean>. Predicate methods for boolean\nC<#true> and C<#false> values.\n\n=item C<to_Number()>\n\nParameters: none. Returns: C<Number>. Returns the native number, or\nthrows when the value is not a finite native number.\n\n=item C<to_String()>\n\nParameters: none. Returns: C<String>. Coerces the value to a string.\n\n=item C<to_Boolean()>\n\nParameters: none. Returns: C<Boolean>. Coerces the value to a boolean.\n\n=item C<native_value()>\n\nParameters: none. Returns: value. Returns the raw native value, with KDL\nC<#null> represented as C<null>.\n\n=back\n\n=head2 C<KDL>\n\nC<KDL> is the codec class for KDL text.\n\n=over\n\n=item C<< codec.decode(String text) >>\n\nParameters: C<text> is KDL text. Returns: C<KDLDocument>. Parses KDL\ntext.\n\n=item C<< codec.decode_binarystring(BinaryString bytes) >>\n\nParameters: C<bytes> is UTF-8 KDL bytes. Returns: C<KDLDocument>.\nParses KDL bytes.\n\n=item C<< codec.encode(value) >>\n\nParameters: C<value> is a C<KDLDocument>, C<KDLNode>, or compatible\nvalue. Returns: C<String>. Serializes KDL data to text.\n\n=item C<< codec.encode_binarystring(value) >>\n\nParameters: C<value> is a C<KDLDocument>, C<KDLNode>, or compatible\nvalue. Returns: C<BinaryString>. Serializes KDL data to UTF-8 bytes.\n\n=item C<< codec.load(path) >>\n\nParameters: C<path> is a C<std/io> C<Path>. Returns: C<KDLDocument>.\nReads and parses a KDL file.\n\n=item C<< codec.dump(path, value) >>\n\nParameters: C<path> is a C<std/io> C<Path> and C<value> is KDL data.\nReturns: C<null>. Serializes and writes a KDL file.\n\n=back\n\n=head1 ZPATH\n\nC<KDLDocument>, C<KDLNode>, and C<KDLValue> objects can be queried with\nC<std/path/z>. A KDL document\'s top-level nodes are exposed as children.\nA KDL node exposes its arguments first, then its child nodes, as ZPath\nchildren. KDL properties are exposed as ZPath attributes.\n\n  from std/data/kdl import KDL;\n  from std/path/z import ZPath;\n\n  let doc := ( new KDL() ).decode( """\n  (pkg)package "zuzu" (email)"dev@example.test" version="0.1.0" {\n    foo "first"\n    bar "middle"\n    foo "second"\n    foo "third"\n  }\n  """ );\n\n  // The package node\'s first child is its first argument.\n  say( ( new ZPath( path: "/package/#0" ) ).first(doc) );       // zuzu\n\n  // Properties are attributes.\n  say( ( new ZPath( path: "/package/@version" ) ).first(doc) ); // 0.1.0\n\n  // Child nodes can be selected by name and zero-based occurrence.\n  say( ( new ZPath( path: "/package/foo#2/#0" ) ).first(doc) ); // third\n\n  // tag() exposes type annotations on nodes and values.\n  say( ( new ZPath( path: "tag(/package)" ) ).first(doc) );     // pkg\n  say( ( new ZPath( path: "tag(/package/#1)" ) ).first(doc) );  // email\n\n  // local-name() exposes the node name, like it does for XML elements.\n  say( ( new ZPath( path: "local-name(/package)" ) ).first(doc) );\n  say( ( new ZPath( path: "/package/foo#2/local-name()" ) ).first(doc) );\n\n=head1 COMPATIBILITY\n\nThe parser is recursive descent and covers the usual KDL 2.0 document\nmodel: nodes, arguments, properties, annotations, comments, slashdash,\nstrings, booleans, nulls, numbers, and children.\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/kdl >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import substr, index, chr, ord, sprint;\n\n\nfunction _kdl_starts_with ( String text, Number pos, String prefix ) {\n	return substr( text, pos, length prefix ) \u2261 prefix;\n}\n\nfunction _kdl_is_newline ( String ch ) {\n	return ch \u2261 "\\n" or ch \u2261 "\\r" or ch \u2261 chr(11)\n		or ch \u2261 chr(133) or ch \u2261 chr(8232) or ch \u2261 chr(8233);\n}\n\nfunction _kdl_is_ws ( String ch ) {\n	return false if ch \u2261 "";\n	let code := ord(ch);\n	return ch \u2261 " " or ch \u2261 "\\t" or ch \u2261 chr(12)\n		or code \u2261 160 or code \u2261 5760 or code \u2261 8239\n		or code \u2261 8287 or code \u2261 12288\n		or ( code >= 8192 and code <= 8202 );\n}\n\nfunction _kdl_is_line_space ( String ch ) {\n	return _kdl_is_ws(ch) or _kdl_is_newline(ch);\n}\n\nfunction _kdl_is_digit ( String ch ) {\n	return ch ~ /^[0-9]$/;\n}\n\nfunction _kdl_is_hex_digit ( String ch ) {\n	return ch ~ /^[0-9a-fA-F]$/;\n}\n\nfunction _kdl_hex_value ( String ch ) {\n	if ( _kdl_is_digit(ch) ) {\n		return ch + 0;\n	}\n	if ( index( "abcdef", ch ) >= 0 ) {\n		return 10 + index( "abcdef", ch );\n	}\n	if ( index( "ABCDEF", ch ) >= 0 ) {\n		return 10 + index( "ABCDEF", ch );\n	}\n	die `Invalid hexadecimal digit \'${ch}\'`;\n}\n\nfunction _kdl_from_hex ( String raw ) {\n	let n := 0;\n	let i := 0;\n	while ( i < length raw ) {\n		n := n * 16 + _kdl_hex_value( substr( raw, i, 1 ) );\n		i++;\n	}\n	return n;\n}\n\nfunction _kdl_clean_number ( String token ) {\n	let out := "";\n	let i := 0;\n	while ( i < length token ) {\n		let ch := substr( token, i, 1 );\n		out _= ch if ch \u2262 "_";\n		i++;\n	}\n	return out;\n}\n\nfunction _kdl_parse_radix ( String token, Number radix ) {\n	let sign := 1;\n	let i := 0;\n	if ( substr( token, 0, 1 ) \u2261 "-" ) {\n		sign := -1;\n		i := 1;\n	}\n	else if ( substr( token, 0, 1 ) \u2261 "+" ) {\n		i := 1;\n	}\n	i += 2;\n\n	let n := 0;\n	while ( i < length token ) {\n		let ch := substr( token, i, 1 );\n		if ( ch \u2262 "_" ) {\n			let v := radix \u2261 16 ? _kdl_hex_value(ch) : ch + 0;\n			die `Invalid digit \'${ch}\' for radix ${radix}` if v >= radix;\n			n := n * radix + v;\n		}\n		i++;\n	}\n	return sign * n;\n}\n\nfunction _kdl_strip_decimal_zeroes ( String raw ) {\n	let i := 0;\n	while ( i < length raw - 1 and substr( raw, i, 1 ) \u2261 "0" ) {\n		i++;\n	}\n	return substr( raw, i, length raw - i );\n}\n\nfunction _kdl_decimal_mul_add ( String raw, Number factor, Number add ) {\n	let out := "";\n	let carry := add;\n	let i := length raw - 1;\n	while ( i >= 0 ) {\n		let n := ( substr( raw, i, 1 ) + 0 ) * factor + carry;\n		out := "" _ ( n mod 10 ) _ out;\n		carry := floor( n / 10 );\n		i--;\n	}\n	while ( carry > 0 ) {\n		out := "" _ ( carry mod 10 ) _ out;\n		carry := floor( carry / 10 );\n	}\n	return _kdl_strip_decimal_zeroes(out);\n}\n\nfunction _kdl_decimal_from_radix ( String token, Number radix ) {\n	let sign := "";\n	let i := 0;\n	if ( substr( token, 0, 1 ) \u2261 "-" ) {\n		sign := "-";\n		i := 1;\n	}\n	else if ( substr( token, 0, 1 ) \u2261 "+" ) {\n		i := 1;\n	}\n	i += 2;\n\n	let out := "0";\n	while ( i < length token ) {\n		out := _kdl_decimal_mul_add(\n			out,\n			radix,\n			_kdl_hex_value( substr( token, i, 1 ) ),\n		);\n		i++;\n	}\n	return sign _ out if sign \u2262 "" and out \u2262 "0";\n	return out;\n}\n\nfunction _kdl_canonical_decimal_int ( String token ) {\n	let sign := "";\n	let i := 0;\n	if ( substr( token, 0, 1 ) \u2261 "-" ) {\n		sign := "-";\n		i := 1;\n	}\n	else if ( substr( token, 0, 1 ) \u2261 "+" ) {\n		i := 1;\n	}\n	let body := _kdl_strip_decimal_zeroes(\n		substr( token, i, length token - i )\n	);\n	return sign _ body if sign \u2262 "" and body \u2262 "0";\n	return body;\n}\n\nfunction _kdl_canonical_float ( String token ) {\n	let epos := index( token, "e" );\n	epos := index( token, "E" ) if epos < 0;\n	return token if epos < 0;\n\n	let mantissa := substr( token, 0, epos );\n	let exponent := substr( token, epos + 1, length token - epos - 1 );\n	if ( substr( exponent, 0, 1 ) \u2262 "+"\n		and substr( exponent, 0, 1 ) \u2262 "-"\n	) {\n		exponent := "+" _ exponent;\n	}\n	return mantissa _ "E" _ exponent;\n}\n\nfunction _kdl_find_multiline_close (\n	String text,\n	String close,\n	Number start,\n	Boolean raw,\n) {\n	let found := index( text, close, start );\n	while ( found >= 0 ) {\n		if ( raw or found = 0 or substr( text, found - 1, 1 ) \u2262 "\\\\" ) {\n			return found;\n		}\n		found := index( text, close, found + 1 );\n	}\n	return -1;\n}\n\nfunction _kdl_reserved_ident ( String text ) {\n	return text \u2261 "true" or text \u2261 "false" or text \u2261 "null"\n		or text \u2261 "inf" or text \u2261 "-inf" or text \u2261 "nan";\n}\n\nfunction _kdl_ident_break ( String ch ) {\n	return ch \u2261 "" or _kdl_is_line_space(ch)\n		or ch \u2261 "\\\\" or ch \u2261 "/" or ch \u2261 "(" or ch \u2261 ")"\n		or ch \u2261 "{" or ch \u2261 "}" or ch \u2261 ";" or ch \u2261 "["\n		or ch \u2261 "]" or ch \u2261 "\\"" or ch \u2261 "#" or ch \u2261 "=";\n}\n\nfunction _kdl_forbidden_codepoint ( Number code ) {\n	return code < 32 or code \u2261 127 or code \u2261 65279\n		or code \u2261 8206 or code \u2261 8207\n		or ( code >= 8234 and code <= 8238 )\n		or ( code >= 8294 and code <= 8297 );\n}\n\nfunction _kdl_is_plain_ident ( String text ) {\n	if ( text \u2261 "" or _kdl_reserved_ident(text) ) {\n		return false;\n	}\n	let first := substr( text, 0, 1 );\n	let second := substr( text, 1, 1 );\n	if ( _kdl_is_digit(first) ) {\n		return false;\n	}\n	if ( ( first \u2261 "+" or first \u2261 "-" ) and _kdl_is_digit(second) ) {\n		return false;\n	}\n	if ( first \u2261 "." and _kdl_is_digit(second) ) {\n		return false;\n	}\n	let i := 0;\n	while ( i < length text ) {\n		return false if _kdl_ident_break( substr( text, i, 1 ) );\n		i++;\n	}\n	return true;\n}\n\nfunction _kdl_escape_string ( String text ) {\n	let out := "";\n	let i := 0;\n	while ( i < length text ) {\n		let ch := substr( text, i, 1 );\n		if ( ch \u2261 "\\\\" ) { out _= "\\\\\\\\"; }\n		else if ( ch \u2261 "\\"" ) { out _= "\\\\\\""; }\n		else if ( ch \u2261 chr(8) ) { out _= "\\\\b"; }\n		else if ( ch \u2261 chr(12) ) { out _= "\\\\f"; }\n		else if ( ch \u2261 "\\n" ) { out _= "\\\\n"; }\n		else if ( ch \u2261 "\\r" ) { out _= "\\\\r"; }\n		else if ( ch \u2261 "\\t" ) { out _= "\\\\t"; }\n		else if ( ord(ch) < 32 ) {\n			out _= "\\\\u{" _ sprint( "%x", ord(ch) ) _ "}";\n		}\n		else { out _= ch; }\n		i++;\n	}\n	return out;\n}\n\nfunction _kdl_name ( String text ) {\n	return _kdl_is_plain_ident(text) ? text : `"${_kdl_escape_string(text)}"`;\n}\n\nfunction _kdl_indent ( Number level, Boolean canonical := false ) {\n	let out := "";\n	let i := 0;\n	let unit := canonical ? "    " : "\\t";\n	while ( i < level ) {\n		out _= unit;\n		i++;\n	}\n	return out;\n}\n\nfunction _kdl_canonical_props ( PairList props ) {\n	let latest := {};\n	for ( let pair in props.to_Array() ) {\n		let kv := pair{pair};\n		latest{(kv[0])} := kv[1];\n	}\n\n	let out := [];\n	for ( let key in latest.sorted_keys() ) {\n		out.push( [ key, latest{(key)} ] );\n	}\n	return out;\n}\n\nclass KDLValue {\n	let String type := "null";\n	let kind := null;\n	let value := null;\n	let type_annotation := null;\n	let canonical_number := null;\n\n	method type () { return type; }\n	method kind () { return kind; }\n	method value () { return value; }\n	method type_annotation () { return type_annotation; }\n	method canonical_number () { return canonical_number; }\n\n	method is_null () { return type \u2261 "null"; }\n	method is_boolean () { return type \u2261 "boolean"; }\n	method is_number () { return type \u2261 "number"; }\n	method is_string () { return type \u2261 "string"; }\n	method is_true () { return type \u2261 "boolean" and value; }\n	method is_false () { return type \u2261 "boolean" and not value; }\n\n	method to_Number () {\n		die "KDLValue is not a number" if type \u2262 "number";\n		die "KDL keyword number has no native numeric value" if kind \u2261 "string";\n		return value;\n	}\n\n	method to_String () {\n		return "" if type \u2261 "null";\n		return "" _ value;\n	}\n\n	method to_Boolean () {\n		if ( type \u2261 "boolean" ) { return value; }\n		if ( type \u2261 "null" ) { return false; }\n		if ( type \u2261 "number" ) {\n			return kind \u2262 "string" and value \u2262 0;\n		}\n		return value \u2262 "";\n	}\n\n	method native_value () {\n		return null if type \u2261 "null";\n		return value;\n	}\n}\n\nclass KDLNode {\n	let name := "";\n	let type_annotation := null;\n	let args := [];\n	let props := null;\n	let children := [];\n\n	method __build__ () {\n		props := new PairList() if props \u2261 null;\n		args := [] if args \u2261 null;\n		children := [] if children \u2261 null;\n	}\n\n	method name () { return name; }\n	method type_annotation () { return type_annotation; }\n	method args () { return args; }\n	method props () { return props; }\n	method children () { return children; }\n\n	method to_Iterator () {\n		let values := [];\n		for ( let arg in args ) {\n			values.push(arg);\n		}\n		for ( let child in children ) {\n			values.push(child);\n		}\n		return values.to_Iterator();\n	}\n}\n\nclass KDLDocument {\n	let nodes := [];\n\n	method __build__ () {\n		nodes := [] if nodes \u2261 null;\n	}\n\n	method nodes () { return nodes; }\n\n	method to_Iterator () {\n		return nodes.to_Iterator();\n	}\n}\n\nclass _KDLParser {\n	let String text := "";\n	let Number pos := 0;\n\n	method _eof () {\n		return pos >= length text;\n	}\n\n	method _peek () {\n		return "" if self._eof();\n		return substr( text, pos, 1 );\n	}\n\n	method _take () {\n		let ch := self._peek();\n		pos++;\n		return ch;\n	}\n\n	method _error ( String message ) {\n		die `KDL parse error at offset ${pos}: ${message}`;\n	}\n\n	method _skip_newline () {\n		if ( _kdl_starts_with( text, pos, "\\r\\n" ) ) {\n			pos += 2;\n			return true;\n		}\n		if ( _kdl_is_newline( self._peek() ) ) {\n			pos++;\n			return true;\n		}\n		return false;\n	}\n\n	method _skip_line_comment () {\n		return false if not _kdl_starts_with( text, pos, "//" );\n		pos += 2;\n		while ( not self._eof() and not _kdl_is_newline( self._peek() ) ) {\n			pos++;\n		}\n		self._skip_newline();\n		return true;\n	}\n\n	method _skip_block_comment () {\n		return false if not _kdl_starts_with( text, pos, "/*" );\n		pos += 2;\n		let depth := 1;\n		while ( depth > 0 ) {\n			self._error("Unterminated block comment") if self._eof();\n			if ( _kdl_starts_with( text, pos, "/*" ) ) {\n				depth++;\n				pos += 2;\n			}\n			else if ( _kdl_starts_with( text, pos, "*/" ) ) {\n				depth--;\n				pos += 2;\n			}\n			else {\n				pos++;\n			}\n		}\n		return true;\n	}\n\n	method _skip_line_space () {\n		let moved := false;\n		let keep := true;\n		while ( keep and not self._eof() ) {\n			keep := false;\n			if ( _kdl_is_ws( self._peek() ) ) {\n				pos++;\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_newline() ) {\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_line_comment() ) {\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_block_comment() ) {\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_escline() ) {\n				moved := true;\n				keep := true;\n			}\n		}\n		return moved;\n	}\n\n	method _skip_node_space () {\n		let moved := false;\n		let keep := true;\n		while ( keep and not self._eof() ) {\n			keep := false;\n			if ( _kdl_is_ws( self._peek() ) ) {\n				pos++;\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_block_comment() ) {\n				moved := true;\n				keep := true;\n			}\n			else if ( self._skip_escline() ) {\n				moved := true;\n				keep := true;\n			}\n		}\n		return moved;\n	}\n\n	method _skip_escline () {\n		return false if self._peek() \u2262 "\\\\";\n		let save := pos;\n		pos++;\n		let keep := true;\n		while ( keep and not self._eof() ) {\n			keep := false;\n			while ( _kdl_is_ws( self._peek() ) ) {\n				pos++;\n				keep := true;\n			}\n			if ( self._skip_block_comment() ) {\n				keep := true;\n			}\n		}\n		if ( self._skip_line_comment() or self._skip_newline() or self._eof() ) {\n			return true;\n		}\n		pos := save;\n		return false;\n	}\n\n	method _parse_document () {\n		if ( _kdl_starts_with( text, pos, chr(65279) ) ) {\n			pos++;\n		}\n		let nodes := self._parse_nodes(false);\n		self._skip_line_space();\n		self._error("Unexpected trailing input") if not self._eof();\n		return new KDLDocument( nodes: nodes );\n	}\n\n	method _parse_nodes ( Boolean in_children ) {\n		let nodes := [];\n		while (true) {\n			self._skip_line_space();\n			if ( self._eof() ) {\n				return nodes;\n			}\n			if ( in_children and self._peek() \u2261 "}" ) {\n				return nodes;\n			}\n			if ( _kdl_starts_with( text, pos, "/-" ) ) {\n				self._consume_slashdash();\n				self._parse_node(true);\n			}\n			else {\n				let node := self._parse_node(false);\n				nodes.push(node) if node \u2262 null;\n			}\n		}\n		return nodes;\n	}\n\n	method _consume_slashdash () {\n		self._error("Expected slashdash") if not _kdl_starts_with( text, pos, "/-" );\n		pos += 2;\n		self._skip_line_space();\n	}\n\n	method _parse_type_annotation () {\n		return null if self._peek() \u2262 "(";\n		pos++;\n		self._skip_node_space();\n		let name := self._parse_string();\n		self._skip_node_space();\n		self._error("Expected \')\' after type annotation") if self._peek() \u2262 ")";\n		pos++;\n		self._skip_node_space();\n		return name;\n	}\n\n	method _parse_node ( Boolean discard ) {\n		let annotation := self._parse_type_annotation();\n		self._skip_node_space();\n		let name := self._parse_string();\n		let args := [];\n		let props := new PairList();\n		let children := [];\n		let slashdash_child_before_entry := false;\n\n		while (true) {\n			let had_space := self._skip_node_space();\n			if ( self._eof() ) {\n				return discard ? null : new KDLNode(\n					name: name,\n					type_annotation: annotation,\n					args: args,\n					props: props,\n					children: children,\n				);\n			}\n\n			let ch := self._peek();\n			if ( ch \u2261 ";" ) {\n				pos++;\n				return discard ? null : new KDLNode(\n					name: name,\n					type_annotation: annotation,\n					args: args,\n					props: props,\n					children: children,\n				);\n			}\n			if ( ch \u2261 "}" ) {\n				return discard ? null : new KDLNode(\n					name: name,\n					type_annotation: annotation,\n					args: args,\n					props: props,\n					children: children,\n				);\n			}\n			if ( _kdl_is_newline(ch) ) {\n				self._skip_newline();\n				return discard ? null : new KDLNode(\n					name: name,\n					type_annotation: annotation,\n					args: args,\n					props: props,\n					children: children,\n				);\n			}\n			if ( _kdl_starts_with( text, pos, "//" ) ) {\n				self._skip_line_comment();\n				return discard ? null : new KDLNode(\n					name: name,\n					type_annotation: annotation,\n					args: args,\n					props: props,\n					children: children,\n				);\n			}\n			if ( _kdl_starts_with( text, pos, "/-" ) ) {\n				self._consume_slashdash();\n				if ( self._peek() \u2261 "{" ) {\n					self._parse_children();\n					slashdash_child_before_entry := true;\n				}\n				else {\n					self._parse_entry(true, args, props);\n				}\n				next;\n			}\n			if ( ch \u2261 "{" ) {\n				self._error("Child block must be the final node field")\n					if children.length() > 0;\n				children := self._parse_children();\n				next;\n			}\n			self._error("Expected whitespace before node field")\n				if not had_space;\n			self._error("Child block must be the final node field")\n				if children.length() > 0;\n			self._error("Discarded child block must not precede node fields")\n				if slashdash_child_before_entry;\n			self._parse_entry(discard, args, props);\n		}\n	}\n\n	method _parse_children () {\n		self._error("Expected \'{\'") if self._peek() \u2262 "{";\n		pos++;\n		let kids := self._parse_nodes(true);\n		self._skip_line_space();\n		self._error("Expected \'}\' after child block") if self._peek() \u2262 "}";\n		pos++;\n		return kids;\n	}\n\n	method _parse_entry ( Boolean discard, Array args, PairList props ) {\n		if ( self._peek() \u2261 "(" ) {\n			let value := self._parse_value();\n			args.push(value) if not discard;\n			return;\n		}\n\n		if ( self._peek() \u2261 "#" or self._starts_number() ) {\n			let value := self._parse_value();\n			args.push(value) if not discard;\n			return;\n		}\n\n		let key := self._parse_string();\n		let after_key := pos;\n		self._skip_node_space();\n		if ( self._peek() \u2261 "=" ) {\n			pos++;\n			self._skip_node_space();\n			let value := self._parse_value();\n			props.add( key, value ) if not discard;\n			return;\n		}\n		pos := after_key;\n\n		let value := new KDLValue( type: "string", value: key );\n		args.push(value) if not discard;\n		return;\n	}\n\n	method _parse_value () {\n		let annotation := self._parse_type_annotation();\n		self._skip_node_space();\n\n		if ( self._peek() \u2261 "#" ) {\n			return self._parse_hash_value(annotation);\n		}\n		if ( self._starts_number() ) {\n			return self._parse_number(annotation);\n		}\n		return new KDLValue(\n			type: "string",\n			value: self._parse_string(),\n			type_annotation: annotation,\n		);\n	}\n\n	method _starts_number () {\n		let ch := self._peek();\n		let nxt := substr( text, pos + 1, 1 );\n		return _kdl_is_digit(ch)\n			or ( ( ch \u2261 "+" or ch \u2261 "-" ) and _kdl_is_digit(nxt) );\n	}\n\n	method _read_token () {\n		let start := pos;\n		while ( not self._eof() ) {\n			let ch := self._peek();\n			last if _kdl_ident_break(ch);\n			pos++;\n		}\n		return substr( text, start, pos - start );\n	}\n\n	method _parse_hash_value ( annotation ) {\n		if ( _kdl_starts_with( text, pos, "#true" ) ) {\n			pos += 5;\n			return new KDLValue(\n				type: "boolean",\n				value: true,\n				type_annotation: annotation,\n			);\n		}\n		if ( _kdl_starts_with( text, pos, "#false" ) ) {\n			pos += 6;\n			return new KDLValue(\n				type: "boolean",\n				value: false,\n				type_annotation: annotation,\n			);\n		}\n		if ( _kdl_starts_with( text, pos, "#null" ) ) {\n			pos += 5;\n			return new KDLValue(\n				type: "null",\n				value: null,\n				type_annotation: annotation,\n			);\n		}\n		if ( _kdl_starts_with( text, pos, "#inf" ) ) {\n			pos += 4;\n			return new KDLValue(\n				type: "number",\n				kind: "string",\n				value: "#inf",\n				type_annotation: annotation,\n			);\n		}\n		if ( _kdl_starts_with( text, pos, "#-inf" ) ) {\n			pos += 5;\n			return new KDLValue(\n				type: "number",\n				kind: "string",\n				value: "#-inf",\n				type_annotation: annotation,\n			);\n		}\n		if ( _kdl_starts_with( text, pos, "#nan" ) ) {\n			pos += 4;\n			return new KDLValue(\n				type: "number",\n				kind: "string",\n				value: "#nan",\n				type_annotation: annotation,\n			);\n		}\n		return new KDLValue(\n			type: "string",\n			value: self._parse_raw_string(),\n			type_annotation: annotation,\n		);\n	}\n\n	method _parse_number ( annotation ) {\n		let token := self._read_token();\n		self._error( `Invalid number \'${token}\'` )\n			if token ~ /^[+-]?0[xob]_/i or token ~ /\\._/;\n		let clean := _kdl_clean_number(token);\n		if ( clean ~ /^[+-]?0x[0-9a-fA-F]+$/ ) {\n			return new KDLValue(\n				type: "number",\n				kind: "integer",\n				value: _kdl_parse_radix( clean, 16 ),\n				canonical_number: _kdl_decimal_from_radix( clean, 16 ),\n				type_annotation: annotation,\n			);\n		}\n		if ( clean ~ /^[+-]?0o[0-7]+$/ ) {\n			return new KDLValue(\n				type: "number",\n				kind: "integer",\n				value: _kdl_parse_radix( clean, 8 ),\n				canonical_number: _kdl_decimal_from_radix( clean, 8 ),\n				type_annotation: annotation,\n			);\n		}\n		if ( clean ~ /^[+-]?0b[01]+$/ ) {\n			return new KDLValue(\n				type: "number",\n				kind: "integer",\n				value: _kdl_parse_radix( clean, 2 ),\n				canonical_number: _kdl_decimal_from_radix( clean, 2 ),\n				type_annotation: annotation,\n			);\n		}\n		if ( clean ~ /^[+-]?[0-9]+$/ ) {\n			return new KDLValue(\n				type: "number",\n				kind: "integer",\n				value: clean + 0,\n				canonical_number: _kdl_canonical_decimal_int(clean),\n				type_annotation: annotation,\n			);\n		}\n		if ( clean ~ /^[+-]?[0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?$/ ) {\n			return new KDLValue(\n				type: "number",\n				kind: "float",\n				value: clean + 0,\n				canonical_number: _kdl_canonical_float(clean),\n				type_annotation: annotation,\n			);\n		}\n		self._error( `Invalid number \'${token}\'` );\n	}\n\n	method _parse_string () {\n		if ( self._peek() \u2261 "#" ) {\n			return self._parse_raw_string();\n		}\n		if ( self._peek() \u2261 "\\"" ) {\n			return self._parse_quoted_string();\n		}\n		return self._parse_identifier_string();\n	}\n\n	method _parse_identifier_string () {\n		let ident := self._read_token();\n		self._error("Expected string") if ident \u2261 "";\n		self._error( `Reserved KDL identifier \'${ident}\'` )\n			if _kdl_reserved_ident(ident);\n		self._error( `Invalid KDL identifier \'${ident}\'` )\n			if substr( ident, 0, 1 ) \u2261 "."\n				and _kdl_is_digit( substr( ident, 1, 1 ) );\n		let i := 0;\n		while ( i < length ident ) {\n			let code := ord( substr( ident, i, 1 ) );\n			self._error( `Forbidden codepoint in KDL identifier \'${ident}\'` )\n				if _kdl_forbidden_codepoint(code);\n			i++;\n		}\n		return ident;\n	}\n\n	method _parse_quoted_string () {\n		if ( _kdl_starts_with( text, pos, "\\"\\"\\"" ) ) {\n			return self._parse_multiline_string( "", false );\n		}\n		pos++;\n		let out := "";\n		while ( not self._eof() ) {\n			let ch := self._take();\n			if ( ch \u2261 "\\"" ) {\n				return out;\n			}\n			if ( ch \u2261 "\\\\" ) {\n				out _= self._parse_escape();\n			}\n			else {\n				self._error("Newline in quoted string") if _kdl_is_newline(ch);\n				out _= ch;\n			}\n		}\n		self._error("Unterminated quoted string");\n	}\n\n	method _parse_escape () {\n		self._error("Unterminated string escape") if self._eof();\n		let ch := self._take();\n		if ( ch \u2261 "\\"" ) { return "\\""; }\n		if ( ch \u2261 "\\\\" ) { return "\\\\"; }\n		if ( ch \u2261 "b" ) { return chr(8); }\n		if ( ch \u2261 "f" ) { return chr(12); }\n		if ( ch \u2261 "n" ) { return "\\n"; }\n		if ( ch \u2261 "r" ) { return "\\r"; }\n		if ( ch \u2261 "s" ) { return " "; }\n		if ( ch \u2261 "t" ) { return "\\t"; }\n		if ( _kdl_is_line_space(ch) ) {\n			while ( _kdl_is_line_space(ch) ) {\n				if ( _kdl_is_newline(ch) ) {\n					self._skip_newline();\n				}\n				ch := self._peek();\n				pos++ if _kdl_is_ws(ch);\n			}\n			return "";\n		}\n		if ( ch \u2261 "u" ) {\n			self._error("Expected \'{\' in Unicode escape") if self._peek() \u2262 "{";\n			pos++;\n			let start := pos;\n			while ( not self._eof() and self._peek() \u2262 "}" ) {\n				self._error("Invalid Unicode escape") if not _kdl_is_hex_digit( self._peek() );\n				pos++;\n			}\n			self._error("Unterminated Unicode escape") if self._peek() \u2262 "}";\n			let raw := substr( text, start, pos - start );\n			self._error("Unicode escape must contain 1 to 6 hex digits")\n				if length raw < 1 or length raw > 6;\n			pos++;\n			let code := _kdl_from_hex(raw);\n			return chr(code);\n		}\n		self._error( `Invalid string escape \'\\\\${ch}\'` );\n	}\n\n	method _parse_raw_string () {\n		let hashes := "";\n		while ( self._peek() \u2261 "#" ) {\n			hashes _= "#";\n			pos++;\n		}\n		self._error("Expected raw string quotes") if self._peek() \u2262 "\\"";\n		if ( _kdl_starts_with( text, pos, "\\"\\"\\"" ) ) {\n			return self._parse_multiline_string( hashes, true );\n		}\n		pos++;\n		let close := "\\"" _ hashes;\n		let end := index( text, close, pos );\n		self._error("Unterminated raw string") if end < 0;\n		let out := substr( text, pos, end - pos );\n		self._error("Newline in raw string") if out ~ /[\\r\\n\\v]/;\n		pos := end + length close;\n		return out;\n	}\n\n	method _parse_multiline_string ( String hashes, Boolean raw ) {\n		pos += 3;\n		self._error("Expected newline after multiline string opener")\n			if not self._skip_newline();\n		let close := "\\"\\"\\"" _ hashes;\n		let end := _kdl_find_multiline_close( text, close, pos, raw );\n		self._error("Unterminated multiline string") if end < 0;\n		let body := substr( text, pos, end - pos );\n		pos := end + length close;\n\n		let last_nl := -1;\n		let i := length body - 1;\n		while ( i >= 0 and last_nl < 0 ) {\n			if ( substr( body, i, 1 ) \u2261 "\\n" ) {\n				last_nl := i;\n			}\n			i--;\n		}\n		return "" if last_nl < 0;\n			let content := substr( body, 0, last_nl );\n			let indent := substr( body, last_nl + 1, length body - last_nl - 1 );\n			if ( not raw ) {\n				let bs := 0;\n				while ( bs < length indent\n					and _kdl_is_ws( substr( indent, bs, 1 ) )\n				) {\n					bs++;\n				}\n				if ( bs < length indent and substr( indent, bs, 1 ) \u2261 "\\\\" ) {\n					let k := bs + 1;\n					let only_ws := true;\n					while ( k < length indent ) {\n						only_ws := false\n							if not _kdl_is_ws( substr( indent, k, 1 ) );\n						k++;\n					}\n					indent := substr( indent, 0, bs ) if only_ws;\n				}\n			}\n			if ( indent \u2261 "" ) {\n				let min_indent := null;\n				let scan := 0;\n				let scan_start := 0;\n				while ( scan <= length content ) {\n					if ( scan \u2261 length content\n						or substr( content, scan, 1 ) \u2261 "\\n"\n					) {\n						let raw_line := substr(\n							content,\n							scan_start,\n							scan - scan_start,\n						);\n						if ( not( raw_line ~ /^\\s*$/ ) ) {\n							let width := 0;\n							while ( width < length raw_line\n								and _kdl_is_ws( substr( raw_line, width, 1 ) )\n							) {\n								width++;\n							}\n							min_indent := width\n								if min_indent \u2261 null or width < min_indent;\n						}\n						scan_start := scan + 1;\n					}\n					scan++;\n				}\n				if ( min_indent \u2262 null and min_indent > 0 ) {\n					indent := "";\n					let si := 0;\n					while ( si < min_indent ) {\n						indent _= " ";\n						si++;\n					}\n				}\n			}\n			let out := "";\n		i := 0;\n		let line_start := 0;\n			let emitted := false;\n			let continued := false;\n			let last_line_continued_with_text := false;\n			while ( i <= length content ) {\n			if ( i \u2261 length content or substr( content, i, 1 ) \u2261 "\\n" ) {\n				let line := substr( content, line_start, i - line_start );\n				if ( line ~ /^\\s*$/ ) {\n					line := "";\n				}\n					else if ( continued ) {\n						if ( length indent > 0\n							and substr( line, 0, length indent ) \u2261 indent\n						) {\n							line := substr(\n								line,\n								length indent,\n								length line - length indent,\n							);\n						}\n					}\n					else if ( length indent > 0 and substr( line, 0, length indent ) \u2261 indent ) {\n						line := substr( line, length indent, length line - length indent );\n					}\n					else if ( length indent > 0 ) {\n						let k := 0;\n						while ( k < length line\n							and _kdl_is_ws( substr( line, k, 1 ) )\n						) {\n							k++;\n						}\n						let ok_escape_prefix := false;\n						if ( not raw and substr( line, k, 1 ) \u2261 "\\\\" ) {\n							k++;\n							ok_escape_prefix := true;\n							while ( k < length line ) {\n								ok_escape_prefix := false\n									if not _kdl_is_ws( substr( line, k, 1 ) );\n								k++;\n							}\n						}\n						self._error("Multiline string indentation mismatch")\n							if not ok_escape_prefix;\n					}\n\n				let line_continues := false;\n				if ( not raw ) {\n					let j := length line - 1;\n					while ( j >= 0 and _kdl_is_ws( substr( line, j, 1 ) ) ) {\n						j--;\n					}\n					if ( j >= 0 and substr( line, j, 1 ) \u2261 "\\\\" ) {\n						let slashes := 0;\n						while ( j - slashes >= 0\n							and substr( line, j - slashes, 1 ) \u2261 "\\\\"\n						) {\n							slashes++;\n						}\n						if ( slashes mod 2 = 1 ) {\n							line_continues := true;\n							line := substr( line, 0, j );\n						}\n					}\n				}\n				self._error("Invalid final multiline whitespace escape")\n					if line_continues and line \u2261 "" and indent \u2261 "";\n\n				out _= "\\n"\n					if emitted and not continued\n						and not ( line_continues and line \u2261 "" );\n				out _= raw ? line : self._unescape_multiline_line(line);\n				emitted := true;\n				continued := line_continues;\n				last_line_continued_with_text := line_continues and line \u2262 "";\n				line_start := i + 1;\n			}\n			i++;\n		}\n		self._error("Invalid final multiline whitespace escape")\n			if last_line_continued_with_text;\n		return out;\n	}\n\n	method _unescape_multiline_line ( String line ) {\n		let out := "";\n		let i := 0;\n		while ( i < length line ) {\n			let ch := substr( line, i, 1 );\n			if ( ch \u2262 "\\\\" ) {\n				out _= ch;\n				i++;\n				next;\n			}\n\n			i++;\n			self._error("Unterminated string escape") if i >= length line;\n			ch := substr( line, i, 1 );\n			if ( ch \u2261 "\\"" ) { out _= "\\""; }\n			else if ( ch \u2261 "\\\\" ) { out _= "\\\\"; }\n			else if ( ch \u2261 "b" ) { out _= chr(8); }\n			else if ( ch \u2261 "f" ) { out _= chr(12); }\n			else if ( ch \u2261 "n" ) { out _= "\\n"; }\n			else if ( ch \u2261 "r" ) { out _= "\\r"; }\n			else if ( ch \u2261 "s" ) { out _= " "; }\n			else if ( ch \u2261 "t" ) { out _= "\\t"; }\n			else if ( _kdl_is_ws(ch) ) {\n				while ( i < length line and _kdl_is_ws( substr( line, i, 1 ) ) ) {\n					i++;\n				}\n				i--;\n			}\n			else if ( ch \u2261 "u" ) {\n				self._error("Expected \'{\' in Unicode escape")\n					if substr( line, i + 1, 1 ) \u2262 "{";\n				i += 2;\n				let start := i;\n				while ( i < length line and substr( line, i, 1 ) \u2262 "}" ) {\n					self._error("Invalid Unicode escape")\n						if not _kdl_is_hex_digit( substr( line, i, 1 ) );\n					i++;\n				}\n				self._error("Unterminated Unicode escape")\n					if i >= length line;\n				let raw := substr( line, start, i - start );\n				self._error("Unicode escape must contain 1 to 6 hex digits")\n					if length raw < 1 or length raw > 6;\n				let code := _kdl_from_hex(raw);\n				out _= chr(code);\n			}\n			else {\n				self._error( `Invalid string escape \'\\\\${ch}\'` );\n			}\n			i++;\n		}\n		return out;\n	}\n}\n\nfunction _kdl_value ( value ) {\n	if ( value instanceof KDLValue ) {\n		return value;\n	}\n	if ( value \u2261 null ) {\n		return new KDLValue( type: "null", value: null );\n	}\n	if ( value instanceof Boolean ) {\n		return new KDLValue( type: "boolean", value: value );\n	}\n	if ( value instanceof Number ) {\n		return new KDLValue( type: "number", kind: "float", value: value );\n	}\n	return new KDLValue( type: "string", value: "" _ value );\n}\n\nfunction _kdl_encode_value ( value, Boolean canonical := false ) {\n	let v := _kdl_value(value);\n	let prefix := "";\n	if ( v.type_annotation() \u2262 null ) {\n		prefix := "(" _ _kdl_name( v.type_annotation() ) _ ")";\n	}\n	if ( v.is_null() ) { return prefix _ "#null"; }\n	if ( v.is_boolean() ) {\n		return prefix _ ( v.native_value() ? "#true" : "#false" );\n	}\n	if ( v.is_number() ) {\n		if ( canonical and v.canonical_number() \u2262 null ) {\n			return prefix _ v.canonical_number();\n		}\n		return prefix _ ( v.kind() \u2261 "string" ? v.value() : "" _ v.value() );\n	}\n	if ( v.is_string() ) {\n		if ( canonical and _kdl_is_plain_ident( v.native_value() ) ) {\n			return prefix _ v.native_value();\n		}\n		return prefix _ "\\"" _ _kdl_escape_string( v.native_value() ) _ "\\"";\n	}\n\n	let native := v.native_value();\n	try {\n		if ( native can "to_String" ) {\n			let text := native.to_String();\n			if ( canonical and _kdl_is_plain_ident(text) ) {\n				return prefix _ text;\n			}\n			return prefix _ "\\"" _ _kdl_escape_string(text) _ "\\"";\n		}\n	}\n	catch {\n	}\n\n	die `Cannot serialize KDLValue of type \'${v.type()}\'`;\n}\n\nfunction _kdl_encode_node (\n	KDLNode node,\n	Number level,\n	Boolean canonical := false,\n) {\n	let out := _kdl_indent( level, canonical );\n	if ( node.type_annotation() \u2262 null ) {\n		out _= "(" _ _kdl_name( node.type_annotation() ) _ ")";\n	}\n	out _= _kdl_name( node.name() );\n	for ( let arg in node.args() ) {\n		out _= " " _ _kdl_encode_value( arg, canonical );\n	}\n	if ( canonical ) {\n		for ( let kv in _kdl_canonical_props( node.props() ) ) {\n			out _= " " _ _kdl_name(kv[0]) _ "="\n				_ _kdl_encode_value( kv[1], canonical );\n		}\n	}\n	else {\n		for ( let pair in node.props().to_Array() ) {\n			let kv := pair{pair};\n			out _= " " _ _kdl_name(kv[0]) _ "="\n				_ _kdl_encode_value( kv[1], canonical );\n		}\n	}\n	if ( node.children().length() > 0 ) {\n		out _= " {\\n";\n		let i := 0;\n		while ( i < node.children().length() ) {\n			out _= _kdl_encode_node(\n				node.children()[i],\n				level + 1,\n				canonical,\n			);\n			out _= "\\n";\n			i++;\n		}\n		out _= _kdl_indent( level, canonical ) _ "}";\n	}\n	return out;\n}\n\nfunction _kdl_encode_document ( KDLDocument doc, Boolean canonical := false ) {\n	let out := "";\n	let i := 0;\n	while ( i < doc.nodes().length() ) {\n		out _= "\\n" if i > 0;\n		out _= _kdl_encode_node( doc.nodes()[i], 0, canonical );\n		i++;\n	}\n	out _= "\\n" if canonical;\n	return out;\n}\n\nclass KDL {\n	let Boolean canonical := false;\n\n	method decode ( String text ) {\n		return new _KDLParser( text: text, pos: 0 )._parse_document();\n	}\n\n	method decode_binarystring ( BinaryString raw ) {\n		return self.decode( to_string(raw) );\n	}\n\n	method encode ( value ) {\n		if ( value instanceof KDLDocument ) {\n			return _kdl_encode_document( value, canonical );\n		}\n		if ( value instanceof KDLNode ) {\n			return _kdl_encode_node( value, 0, canonical );\n		}\n		if ( value instanceof Array ) {\n			return _kdl_encode_document(\n				new KDLDocument( nodes: value ),\n				canonical,\n			);\n		}\n		die "KDL.encode expects a KDLDocument, KDLNode, or Array of KDLNode";\n	}\n\n	method encode_binarystring ( value ) {\n		return to_binary( self.encode(value) );\n	}\n\n	method load ( path ) {\n		from std/io import Path;\n		die "KDL.load is denied by runtime policy" if __system__{deny_fs};\n		die "KDL.load expects a std/io Path object" if not( path instanceof Path );\n		return self.decode_binarystring( path.slurp() );\n	}\n\n	method dump ( path, value ) {\n		from std/io import Path;\n		die "KDL.dump is denied by runtime policy" if __system__{deny_fs};\n		die "KDL.dump expects a std/io Path object" if not( path instanceof Path );\n		path.spew( self.encode_binarystring(value) );\n		return path;\n	}\n}\n';
        virtualFiles["/modules/std/data/kdl/json.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/kdl/json - JSON-in-KDL structure conversion.\n\n=head1 SYNOPSIS\n\n  from std/data/kdl import KDL;\n  from std/data/kdl/json import kdl_to_json, json_to_kdl;\n\n  let kdl_doc := ( new KDL() ).decode( """- foo=1 bar=#true""" );\n  let data := kdl_to_json(kdl_doc);\n  let roundtrip := json_to_kdl(data);\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module implements the JSON-in-KDL (JiK) mapping for parsed Zuzu\nobjects. C<kdl_to_json> accepts a C<KDLDocument> or C<KDLNode> and\nreturns native Zuzu data structures. C<json_to_kdl> accepts native\nJSON-like data structures and returns a C<KDLDocument>.\n\nC<kdl_to_json(value, pairlists: true)> maps object-like JiK nodes to\nC<PairList> values instead of C<Dict> values, preserving key order and\nduplicate keys.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item C<< kdl_to_json(value, ... PairList opts) >>\n\nParameters: C<value> is a C<KDLDocument>, C<KDLNode>, or compatible KDL\nvalue and C<opts> may include C<pairlists>. Returns: value. Converts\nJSON-in-KDL structures into native JSON-like ZuzuScript data.\n\n=item C<< json_to_kdl(value) >>\n\nParameters: C<value> is a JSON-like ZuzuScript value. Returns:\nC<KDLDocument>. Converts native JSON-like data into JSON-in-KDL nodes.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/kdl/json >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/data/kdl import KDLDocument, KDLNode, KDLValue;\nfrom std/data/kdl/xml import xml_to_kdl;\nfrom std/time import Time;\n\n\nfunction _jik_has_props ( KDLNode node ) {\n	return node.props().to_Array().length() > 0;\n}\n\nfunction _jik_literal_value ( value ) {\n	die "JSON-in-KDL literal must be a KDLValue"\n		if not( value instanceof KDLValue );\n	if ( value.is_number() and value.kind() \u2261 "string" ) {\n		die "JSON-in-KDL does not support non-finite KDL number keywords";\n	}\n	return value.native_value();\n}\n\nfunction _jik_is_time_native ( value ) {\n	return value instanceof Time;\n}\n\nfunction _jik_pad2 ( value ) {\n	let text := "" _ value;\n	return length text < 2 ? "0" _ text : text;\n}\n\nfunction _jik_pad4 ( value ) {\n	let text := "" _ value;\n	while ( length text < 4 ) {\n		text := "0" _ text;\n	}\n	return text;\n}\n\nfunction _jik_time_text ( value ) {\n	return _jik_pad4( value.year() )\n		_ "-" _ _jik_pad2( value.mon() )\n		_ "-" _ _jik_pad2( value.day_of_month() )\n		_ "T" _ _jik_pad2( value.hour() )\n		_ ":" _ _jik_pad2( value.min() )\n		_ ":" _ _jik_pad2( value.sec() );\n}\n\nfunction _jik_value ( value ) {\n	if ( value instanceof KDLValue ) {\n		return value;\n	}\n	if ( value \u2261 null ) {\n		return new KDLValue( type: "null", value: null );\n	}\n\n	if ( value instanceof Boolean ) {\n		return new KDLValue( type: "boolean", value: value );\n	}\n	if ( value instanceof Number ) {\n		return new KDLValue( type: "number", kind: "float", value: value );\n	}\n	if ( value instanceof String or value instanceof BinaryString ) {\n		return new KDLValue( type: "string", value: "" _ value );\n	}\n	if ( _jik_is_time_native(value) ) {\n		return new KDLValue(\n			type: "string",\n			value: _jik_time_text(value),\n			type_annotation: "date-time",\n		);\n	}\n\n	return new KDLValue( type: typeof value, value: value );\n}\n\nfunction _jik_is_array_native ( value ) {\n	return value instanceof Array or value instanceof Set or value instanceof Bag;\n}\n\nfunction _jik_is_object_native ( value ) {\n	return value instanceof Dict or value instanceof PairList;\n}\n\nfunction _jik_is_kdl_native ( value ) {\n	return value instanceof KDLDocument or value instanceof KDLNode;\n}\n\nfunction _jik_is_xml_native ( value ) {\n	try {\n		if ( value can nodeType ) {\n			return true if value.nodeType() \u2262 null;\n		}\n	}\n	catch {\n	}\n\n	try {\n		return false if not( value can documentElement );\n		value.documentElement();\n		return true;\n	}\n	catch {\n	}\n\n	return false;\n}\n\nfunction _jik_is_opaque_literal_native ( value ) {\n	return not _jik_is_array_native(value)\n		and not _jik_is_object_native(value)\n		and not _jik_is_kdl_native(value)\n		and not _jik_is_xml_native(value);\n}\n\nfunction _jik_is_literal_native ( value ) {\n	return value \u2261 null\n		or value instanceof Boolean\n		or value instanceof Number\n		or value instanceof String\n		or value instanceof BinaryString\n		or _jik_is_time_native(value)\n		or value instanceof KDLValue\n		or _jik_is_opaque_literal_native(value);\n}\n\nfunction _jik_sorted_array ( value ) {\n	if ( value instanceof Set or value instanceof Bag ) {\n		return value.sortstr();\n	}\n	return value;\n}\n\nfunction _jik_pairs ( obj ) {\n	let out := [];\n	if ( obj instanceof PairList ) {\n		for ( let p in obj.to_Array() ) {\n			out.push( p{pair} );\n		}\n		return out;\n	}\n\n	for ( let key in obj.sorted_keys() ) {\n		out.push( [ key, obj.get(key) ] );\n	}\n	return out;\n}\n\nfunction _jik_native_to_node;\nfunction _jik_native_to_nodes;\n\nfunction _jik_xml_nodes ( value ) {\n	return xml_to_kdl(value).nodes();\n}\n\nfunction _jik_kdl_nodes ( value ) {\n	if ( value instanceof KDLDocument ) {\n		return value.nodes();\n	}\n	return [ value ];\n}\n\nfunction _jik_structural_nodes ( value, String name := "-" ) {\n	let nodes := _jik_is_kdl_native(value)\n		? _jik_kdl_nodes(value)\n		: _jik_xml_nodes(value);\n\n	if ( name \u2261 "-" ) {\n		return nodes.length() = 0 ? [ new KDLNode( name: name ) ] : nodes;\n	}\n	return [ new KDLNode( name: name, children: nodes ) ];\n}\n\nfunction _jik_make_array_node ( value, String name := "-" ) {\n	let items := _jik_sorted_array(value);\n	let all_literals := true;\n	for ( let item in items ) {\n		all_literals := false unless _jik_is_literal_native(item);\n	}\n\n	let annotate := items.length() < 2;\n	if ( all_literals ) {\n		return new KDLNode(\n			name: name,\n			type_annotation: annotate ? "array" : null,\n			args: items.map( fn item -> _jik_value(item) ),\n		);\n	}\n\n	let children := [];\n	for ( let item in items ) {\n		for ( let child in _jik_native_to_nodes( item, "-" ) ) {\n			children.push(child);\n		}\n	}\n\n	return new KDLNode(\n		name: name,\n		type_annotation: annotate ? "array" : null,\n		children: children,\n	);\n}\n\nfunction _jik_object_needs_annotation ( Array pairs, Boolean pairlist ) {\n	if ( pairs.length() = 0 ) {\n		return true;\n	}\n	if ( pairlist ) {\n		return pairs.all( fn pair -> pair[0] \u2261 "-" );\n	}\n	return pairs.length() = 1 and pairs[0][0] \u2261 "-"\n		and not _jik_is_literal_native( pairs[0][1] );\n}\n\nfunction _jik_make_object_node ( value, String name := "-" ) {\n	let pairs := _jik_pairs(value);\n	let pairlist := value instanceof PairList;\n	let props := new PairList();\n	let children := [];\n\n	if ( pairlist ) {\n		for ( let pair in pairs ) {\n			for ( let child in _jik_native_to_nodes( pair[1], pair[0] ) ) {\n				children.push(child);\n			}\n		}\n	}\n	else {\n		for ( let pair in pairs ) {\n			if ( _jik_is_literal_native( pair[1] ) ) {\n				props.add( pair[0], _jik_value( pair[1] ) );\n			}\n			else {\n				for ( let child in _jik_native_to_nodes( pair[1], pair[0] ) ) {\n					children.push(child);\n				}\n			}\n		}\n	}\n\n	return new KDLNode(\n		name: name,\n		type_annotation: _jik_object_needs_annotation( pairs, pairlist )\n			? "object"\n			: null,\n		props: props,\n		children: children,\n	);\n}\n\nfunction _jik_native_to_node ( value, String name := "-" ) {\n	if ( _jik_is_literal_native(value) ) {\n		return new KDLNode( name: name, args: [ _jik_value(value) ] );\n	}\n	if ( _jik_is_array_native(value) ) {\n		return _jik_make_array_node( value, name );\n	}\n	if ( _jik_is_object_native(value) ) {\n		return _jik_make_object_node( value, name );\n	}\n	if ( _jik_is_kdl_native(value) or _jik_is_xml_native(value) ) {\n		let nodes := _jik_structural_nodes( value, name );\n		return nodes.length() = 1 ? nodes[0] : new KDLNode(\n			name: name,\n			children: nodes,\n		);\n	}\n	die `Cannot convert ${typeof value} to JSON-in-KDL`;\n}\n\nfunction _jik_native_to_nodes ( value, String name := "-" ) {\n	if ( _jik_is_kdl_native(value) or _jik_is_xml_native(value) ) {\n		return _jik_structural_nodes( value, name );\n	}\n	return [ _jik_native_to_node( value, name ) ];\n}\n\nfunction _jik_node_has_only_dash_children ( KDLNode node ) {\n	return node.children().all( fn child -> child.name() \u2261 "-" );\n}\n\nfunction _jik_node_kind ( KDLNode node ) {\n	let annotation := node.type_annotation();\n	if ( annotation \u2261 "array" or annotation \u2261 "object" ) {\n		return annotation;\n	}\n	if ( _jik_has_props(node) ) {\n		return "object";\n	}\n	if ( node.children().length() > 0 ) {\n		if ( _jik_node_has_only_dash_children(node) ) {\n			return "array";\n		}\n		return "object";\n	}\n	if ( node.args().length() = 1 ) {\n		return "literal";\n	}\n	if ( node.args().length() > 1 ) {\n		return "array";\n	}\n	die "Empty JSON-in-KDL node must be annotated as array or object";\n}\n\nfunction _jik_node_to_native;\n\nfunction _jik_array_from_node ( KDLNode node, PairList opts ) {\n	die "JSON-in-KDL array node cannot contain properties"\n		if _jik_has_props(node);\n	die "Empty JSON-in-KDL array node must be annotated as array"\n		if node.args().length() = 0\n			and node.children().length() = 0\n			and node.type_annotation() \u2262 "array";\n	die "JSON-in-KDL array child nodes must be named \'-\'"\n		unless _jik_node_has_only_dash_children(node);\n\n	let out := [];\n	for ( let arg in node.args() ) {\n		out.push( _jik_literal_value(arg) );\n	}\n	for ( let child in node.children() ) {\n		out.push( _jik_node_to_native( child, opts ) );\n	}\n	return out;\n}\n\nfunction _jik_store_object_item ( obj, String key, value, Boolean pairlists ) {\n	if ( pairlists ) {\n		obj.add( key, value );\n		return;\n	}\n	die `Duplicate JSON-in-KDL object key \'${key}\'` if obj.exists(key);\n	obj.set( key, value );\n}\n\nfunction _jik_object_from_node ( KDLNode node, PairList opts ) {\n	die "JSON-in-KDL object node cannot contain unnamed arguments"\n		if node.args().length() > 0;\n	die "Empty JSON-in-KDL object node must be annotated as object"\n		if not _jik_has_props(node)\n			and node.children().length() = 0\n			and node.type_annotation() \u2262 "object";\n\n	let pairlists := opts.get( "pairlists", false );\n	let out := pairlists ? new PairList() : {};\n\n	for ( let pair in node.props().to_Array() ) {\n		let kv := pair{pair};\n		_jik_store_object_item(\n			out,\n			kv[0],\n			_jik_literal_value( kv[1] ),\n			pairlists,\n		);\n	}\n	for ( let child in node.children() ) {\n		_jik_store_object_item(\n			out,\n			child.name(),\n			_jik_node_to_native( child, opts ),\n			pairlists,\n		);\n	}\n	return out;\n}\n\nfunction _jik_node_to_native ( KDLNode node, PairList opts ) {\n	let kind := _jik_node_kind(node);\n	if ( kind \u2261 "literal" ) {\n		die "JSON-in-KDL literal node must contain one argument only"\n			if node.args().length() \u2262 1\n				or _jik_has_props(node)\n				or node.children().length() > 0;\n		return _jik_literal_value( node.args()[0] );\n	}\n	if ( kind \u2261 "array" ) {\n		return _jik_array_from_node( node, opts );\n	}\n	if ( kind \u2261 "object" ) {\n		return _jik_object_from_node( node, opts );\n	}\n	die `Unknown JSON-in-KDL node kind \'${kind}\'`;\n}\n\nfunction kdl_to_json ( value, ... PairList opts ) {\n	if ( value instanceof KDLNode ) {\n		return _jik_node_to_native( value, opts );\n	}\n	if ( value instanceof KDLDocument ) {\n		die "JSON-in-KDL document must contain exactly one top-level node"\n			if value.nodes().length() \u2262 1;\n		return _jik_node_to_native( value.nodes()[0], opts );\n	}\n	die "kdl_to_json expects a KDLDocument or KDLNode";\n}\n\nfunction json_to_kdl ( value ) {\n	if ( value instanceof KDLDocument ) {\n		return value;\n	}\n	if ( value instanceof KDLNode ) {\n		return value;\n	}\n	return new KDLDocument( nodes: [ _jik_native_to_node(value) ] );\n}\n';
        virtualFiles["/modules/std/data/kdl/xml.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/kdl/xml - XML-in-KDL structure conversion.\n\n=head1 SYNOPSIS\n\n  from std/data/kdl import KDL;\n  from std/data/kdl/xml import kdl_to_xml, xml_to_kdl;\n  from std/data/xml import XML;\n\n  let kdl_doc := ( new KDL() ).decode(\n    "a href=\\"http://example.com\\" \\"here\'s a link\\""\n  );\n  let xml_doc := kdl_to_xml(kdl_doc);\n  let roundtrip := xml_to_kdl(xml_doc);\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module implements the XML-in-KDL (XiK) mapping for parsed Zuzu\nobjects. C<kdl_to_xml> accepts a C<KDLDocument> or C<KDLNode> and\nreturns an C<XMLDocument>. C<xml_to_kdl> accepts an C<XMLDocument> or\nC<XMLNode> and returns a C<KDLDocument>.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item C<< kdl_to_xml(value) >>\n\nParameters: C<value> is a C<KDLDocument>, C<KDLNode>, or compatible KDL\nvalue. Returns: C<XMLDocument>. Converts XML-in-KDL structures into an\nXML document.\n\n=item C<< xml_to_kdl(value) >>\n\nParameters: C<value> is an C<XMLDocument>, C<XMLNode>, or compatible XML\nvalue. Returns: C<KDLDocument>. Converts XML data into XML-in-KDL nodes.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/kdl/xml >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/data/kdl import KDLDocument, KDLNode, KDLValue;\nfrom std/data/xml import XML;\nfrom std/data/xml/escape import escape_xml;\nfrom std/string import index, substr;\n\nfunction _xik_starts_with ( String text, String prefix ) {\n	return substr( text, 0, length prefix ) \u2261 prefix;\n}\n\nfunction _xik_has_props ( KDLNode node ) {\n	return node.props().to_Array().length() > 0;\n}\n\nfunction _xik_string_value ( value, String context ) {\n	die `${context} must be a KDLValue` if not( value instanceof KDLValue );\n	die `${context} must be a string value` if not value.is_string();\n	return value.native_value();\n}\n\nfunction _xik_single_string_arg ( KDLNode node, String context ) {\n	die `${context} must contain one string argument`\n		if node.args().length() \u2262 1;\n	return _xik_string_value( node.args()[0], context );\n}\n\nfunction _xik_no_props_or_children ( KDLNode node, String context ) {\n	die `${context} cannot contain properties` if _xik_has_props(node);\n	die `${context} cannot contain children`\n		if node.children().length() > 0;\n}\n\nfunction _xik_attr_text ( PairList props ) {\n	let out := "";\n	for ( let pair in props.to_Array() ) {\n		let kv := pair{pair};\n		let key := kv[0];\n		let value := _xik_string_value(\n			kv[1],\n			`XML-in-KDL attribute \'${key}\'`,\n		);\n		out _= ` ${key}="${escape_xml(value)}"`;\n	}\n	return out;\n}\n\nfunction _xik_comment_text ( KDLNode node ) {\n	_xik_no_props_or_children( node, "XML-in-KDL comment node" );\n	let text := _xik_single_string_arg( node, "XML-in-KDL comment node" );\n	die "XML-in-KDL comment cannot contain \'--\'" if index( text, "--" ) >= 0;\n	die "XML-in-KDL comment cannot end with \'-\'"\n		if length text > 0 and substr( text, length text - 1, 1 ) \u2261 "-";\n	return "<!--" _ text _ "-->";\n}\n\nfunction _xik_doctype_text ( KDLNode node ) {\n	_xik_no_props_or_children( node, "XML-in-KDL doctype node" );\n	let text := _xik_single_string_arg( node, "XML-in-KDL doctype node" );\n	die "XML-in-KDL doctype cannot contain \'>\'" if index( text, ">" ) >= 0;\n	return "<!DOCTYPE " _ text _ ">";\n}\n\nfunction _xik_pi_text ( KDLNode node ) {\n	die "XML-in-KDL processing instruction cannot contain children"\n		if node.children().length() > 0;\n\n	let target := substr( node.name(), 1, length node.name() - 1 );\n	die "XML-in-KDL processing instruction has an empty target"\n		if target \u2261 "";\n\n	let content := "";\n	if ( node.args().length() > 0 ) {\n		_xik_no_props_or_children(\n			node,\n			"XML-in-KDL unstructured processing instruction",\n		);\n		content := _xik_single_string_arg(\n			node,\n			"XML-in-KDL unstructured processing instruction",\n		);\n	}\n	else {\n		content := _xik_attr_text( node.props() );\n		content := substr( content, 1, length content - 1 )\n			if length content > 0;\n	}\n\n	die "XML-in-KDL processing instruction cannot contain \'?>\'"\n		if index( content, "?>" ) >= 0;\n\n	return content \u2261 "" ? `<?${target}?>` : `<?${target} ${content}?>`;\n}\n\nfunction _xik_text_node_text ( KDLNode node ) {\n	_xik_no_props_or_children( node, "XML-in-KDL text node" );\n	return escape_xml( _xik_single_string_arg( node, "XML-in-KDL text node" ) );\n}\n\nfunction _xik_node_text;\n\nfunction _xik_element_text ( KDLNode node ) {\n	die `XML-in-KDL element \'${node.name()}\' cannot have type annotations`\n		if node.type_annotation() \u2262 null;\n\n	let args := node.args();\n	let children := node.children();\n	die `XML-in-KDL element \'${node.name()}\' cannot contain multiple arguments`\n		if args.length() > 1;\n	die `XML-in-KDL element \'${node.name()}\' cannot mix text argument and children`\n		if args.length() > 0 and children.length() > 0;\n\n	let attrs := _xik_attr_text( node.props() );\n	if ( args.length() = 0 and children.length() = 0 ) {\n		return `<${node.name()}${attrs}/>`;\n	}\n\n	let body := "";\n	if ( args.length() = 1 ) {\n		body := escape_xml(\n			_xik_string_value(\n				args[0],\n				`XML-in-KDL element \'${node.name()}\' text argument`,\n			),\n		);\n	}\n	else {\n		for ( let child in children ) {\n			body _= _xik_node_text(child);\n		}\n	}\n\n	return `<${node.name()}${attrs}>${body}</${node.name()}>`;\n}\n\nfunction _xik_node_text ( KDLNode node ) {\n	let name := node.name();\n	if ( name \u2261 "-" ) {\n		return _xik_text_node_text(node);\n	}\n	if ( name \u2261 "!" ) {\n		return _xik_comment_text(node);\n	}\n	if ( name \u2261 "!doctype" ) {\n		return _xik_doctype_text(node);\n	}\n	if ( _xik_starts_with( name, "?" ) ) {\n		return _xik_pi_text(node);\n	}\n	return _xik_element_text(node);\n}\n\nfunction _xik_is_element_node ( KDLNode node ) {\n	let name := node.name();\n	return name \u2262 "-" and name \u2262 "!" and name \u2262 "!doctype"\n		and not _xik_starts_with( name, "?" );\n}\n\nfunction kdl_to_xml ( value ) {\n	let nodes;\n	if ( value instanceof KDLDocument ) {\n		nodes := value.nodes();\n	}\n	else if ( value instanceof KDLNode ) {\n		nodes := [ value ];\n	}\n	else {\n		die "kdl_to_xml expects a KDLDocument or KDLNode";\n	}\n\n	let element_count := 0;\n	let out := "";\n	for ( let node in nodes ) {\n		element_count++ if _xik_is_element_node(node);\n		out _= _xik_node_text(node);\n	}\n\n	die "XML-in-KDL document must contain exactly one top-level element"\n		if element_count \u2262 1;\n\n	return XML.parse(out);\n}\n\nfunction _xik_kdl_value ( String text ) {\n	return new KDLValue( type: "string", value: text );\n}\n\nfunction _xik_xml_attrs_to_kdl ( xml_node ) {\n	let props := new PairList();\n	for ( let attr in xml_node.attributes() ) {\n		props.add( attr.nodeName(), _xik_kdl_value( attr.nodeValue() ) );\n	}\n	return props;\n}\n\nfunction _xik_xml_text_to_kdl ( xml_node ) {\n	return new KDLNode(\n		name: "-",\n		args: [ _xik_kdl_value( xml_node.nodeValue() ?: "" ) ],\n	);\n}\n\nfunction _xik_xml_comment_to_kdl ( xml_node ) {\n	return new KDLNode(\n		name: "!",\n		args: [ _xik_kdl_value( xml_node.nodeValue() ?: "" ) ],\n	);\n}\n\nfunction _xik_xml_node_to_kdl;\n\nfunction _xik_xml_pi_to_kdl ( xml_node ) {\n	return new KDLNode(\n		name: "?" _ xml_node.nodeName(),\n		args: [ _xik_kdl_value( xml_node.nodeValue() ?: "" ) ],\n	);\n}\n\nfunction _xik_xml_doctype_to_kdl ( xml_node ) {\n	return new KDLNode(\n		name: "!doctype",\n		args: [ _xik_kdl_value( xml_node.nodeValue() ?: xml_node.nodeName() ) ],\n	);\n}\n\nfunction _xik_xml_element_to_kdl ( xml_node ) {\n	let child_nodes := xml_node.childNodes();\n	let text_only := child_nodes.length() > 0;\n	let text := "";\n\n	for ( let child in child_nodes ) {\n		let kind := 0 + child.nodeType();\n		if ( kind = 3 or kind = 4 ) {\n			text _= child.nodeValue() ?: "";\n		}\n		else {\n			text_only := false;\n		}\n	}\n\n	if ( text_only ) {\n		return new KDLNode(\n			name: xml_node.nodeName(),\n			props: _xik_xml_attrs_to_kdl(xml_node),\n			args: [ _xik_kdl_value(text) ],\n		);\n	}\n\n	let children := [];\n	for ( let child in child_nodes ) {\n		let kdl_child := _xik_xml_node_to_kdl(child);\n		children.push(kdl_child) if kdl_child \u2262 null;\n	}\n\n	return new KDLNode(\n		name: xml_node.nodeName(),\n		props: _xik_xml_attrs_to_kdl(xml_node),\n		children: children,\n	);\n}\n\nfunction _xik_xml_node_to_kdl ( xml_node ) {\n	switch ( 0 + xml_node.nodeType() ) {\n		case 1:\n			return _xik_xml_element_to_kdl(xml_node);\n		case 3, 4:\n			return _xik_xml_text_to_kdl(xml_node);\n		case 7:\n			return _xik_xml_pi_to_kdl(xml_node);\n		case 8:\n			return _xik_xml_comment_to_kdl(xml_node);\n		case 10:\n			return _xik_xml_doctype_to_kdl(xml_node);\n	}\n	return null;\n}\n\nfunction _xik_xml_document_nodes ( xml_doc ) {\n	let raw_nodes := null;\n	try {\n		raw_nodes := xml_doc.childNodes();\n	}\n	catch {\n		try {\n			raw_nodes := xml_doc.findnodes("/node()");\n		}\n		catch {\n			let root := xml_doc.documentElement();\n			raw_nodes := root \u2261 null ? [] : [ root ];\n		}\n	}\n\n	if ( raw_nodes.length() = 0 ) {\n		let root := xml_doc.documentElement();\n		raw_nodes := root \u2261 null ? [] : [ root ];\n	}\n\n	let nodes := [];\n	for ( let raw in raw_nodes ) {\n		let node := _xik_xml_node_to_kdl(raw);\n		nodes.push(node) if node \u2262 null;\n	}\n	return nodes;\n}\n\nfunction xml_to_kdl ( value ) {\n	let node_type := null;\n	try {\n		node_type := 0 + value.nodeType();\n	}\n	catch {\n	}\n\n	if ( node_type \u2262 null ) {\n		if ( node_type = 9 ) {\n			return new KDLDocument( nodes: _xik_xml_document_nodes(value) );\n		}\n\n		let node := _xik_xml_node_to_kdl(value);\n		die "xml_to_kdl cannot convert this XML node type" if node \u2261 null;\n		return new KDLDocument( nodes: [ node ] );\n	}\n\n	try {\n		value.documentElement();\n		return new KDLDocument( nodes: _xik_xml_document_nodes(value) );\n	}\n	catch {\n		die "xml_to_kdl expects an XMLDocument or XMLNode";\n	}\n}\n';
        virtualFiles["/modules/std/path/jsonpointer.zzm"] = `=encoding utf8

=head1 NAME

std/path/jsonpointer - RFC 6901 JSON Pointer selectors.

=head1 SYNOPSIS

  from std/path/jsonpointer import JSONPointer;

  let data := {
    users: [
      { name: "Ada" },
      { name: "Bob" },
    ],
  };

  let pointer := new JSONPointer( path: "/users/0/name" );
  say( pointer.first(data) );

=head1 IMPLEMENTATION SUPPORT

This module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

C<JSONPointer> implements JSON Pointer as defined by RFC 6901. It
provides the same path API shape as C<std/path/simple> and C<std/path/z>:
C<get>, C<select>, C<query>, C<first>, C<exists>, assignment methods,
reference methods, and lexical path-operator registration via C<use>.

Syntactically valid pointers that do not resolve return no matches for
read APIs.

=head1 EXPORTS

=head2 Classes

=over

=item C<< JSONPointer({ path: String }) >>

Constructs a JSON Pointer selector. Returns: C<JSONPointer>.

=over

=item C<< JSONPointer.use() >>

Parameters: none. Returns: C<null>. Makes this path class the lexical
implementation for C<@>, C<@@>, and C<@?>.

=item C<< pointer.expression() >>

Parameters: none. Returns: C<String>. Returns the original pointer
expression.

=item C<< pointer.get(value) >>, C<< pointer.select(value) >>,
C<< pointer.query(value) >>

Parameters: C<value> is the query root. Returns: C<Array>. Evaluates the
pointer and returns selected values.

=item C<< pointer.first(value, fallback?) >>

Parameters: C<value> is the query root and C<fallback> is optional.
Returns: value. Returns the selected value, or C<fallback>/C<null> when
there is no match.

=item C<< pointer.exists(value) >>

Parameters: C<value> is the query root. Returns: C<Boolean>. Returns
true when the pointer resolves to a concrete value.

=item C<< pointer.assign_first(target, value, op := ":=", weak := false) >>

Parameters: C<target> is the query root, C<value> is the assignment
value, C<op> is an assignment operator, and C<weak> is accepted for path
API compatibility. Returns: value. Updates the selected location.

=item C<< pointer.assign_all(target, value, op := ":=", weak := false) >>

Parameters: same as C<assign_first>. Returns: value. Updates the
selected location when it exists.

=item C<< pointer.assign_maybe(target, value, op := ":=", weak := false) >>

Parameters: same as C<assign_first>. Returns: C<Boolean>. Updates the
selected location when it exists.

=item C<< pointer.ref_first(target) >>

Parameters: C<target> is the query root. Returns: C<Function>. Returns a
reference-like getter/setter for the selected location.

=item C<< pointer.ref_all(target) >>

Parameters: C<target> is the query root. Returns: C<Array>. Returns a
single reference-like getter/setter when the pointer resolves, otherwise
an empty array.

=item C<< pointer.ref_maybe(target) >>

Parameters: C<target> is the query root. Returns: C<Function> or
C<null>. Returns a reference-like getter/setter when the pointer
resolves.

=back

=back

=head2 Functions

=over

=item C<< extract_pointer_from_url(url) >>

Parameters: C<url> is a C<String>. Returns: C<Dict>. Splits a URL into
C<baseurl> and C<pointer>. If the URL contains C<#>, C<baseurl> is the
text before C<#> and C<pointer> is the URI-fragment percent-decoded JSON
Pointer. If the URL has no C<#>, C<baseurl> is the full URL and
C<pointer> is C<null>.

=back

=head1 SEE ALSO

Specification: L<https://www.rfc-editor.org/rfc/rfc6901>.

=head1 COPYRIGHT AND LICENCE

B<< std/path/jsonpointer >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/string import index, ord, replace, substr;
from std/string/base64 import decode as _base64_decode;

let _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	_ "abcdefghijklmnopqrstuvwxyz0123456789+/";

function _jsonpointer_div_floor ( Number n, Number d ) {
	return floor( n / d );
}

function _jsonpointer_mod ( Number n, Number d ) {
	return n - _jsonpointer_div_floor( n, d ) * d;
}

function _jsonpointer_bytes_to_binary ( Array bytes ) {
	let out := "";
	let i := 0;
	let n := bytes.length();

	while ( i < n ) {
		let b0 := bytes[i];
		let b1 := null;
		let b2 := null;
		if ( i + 1 < n ) {
			b1 := bytes[i + 1];
		}
		if ( i + 2 < n ) {
			b2 := bytes[i + 2];
		}

		let c0 := _jsonpointer_div_floor( b0, 4 );
		let c1 := _jsonpointer_mod( b0, 4 ) * 16;
		let c2 := 64;
		let c3 := 64;

		if ( not( b1 == null ) ) {
			c1 += _jsonpointer_div_floor( b1, 16 );
			c2 := _jsonpointer_mod( b1, 16 ) * 4;
			if ( not( b2 == null ) ) {
				c2 += _jsonpointer_div_floor( b2, 64 );
				c3 := _jsonpointer_mod( b2, 64 );
			}
		}

		out _= substr( _B64_ALPHABET, c0, 1 );
		out _= substr( _B64_ALPHABET, c1, 1 );
		out _= c2 == 64 ? "=" : substr( _B64_ALPHABET, c2, 1 );
		out _= c3 == 64 ? "=" : substr( _B64_ALPHABET, c3, 1 );
		i += 3;
	}

	return _base64_decode(out);
}

function _jsonpointer_hex_value ( String ch ) {
	if ( ch ~ /[0-9]/ ) {
		return 0 + ch;
	}

	let lower := lc(ch);
	return 10 + index( "abcdef", lower );
}

function _jsonpointer_percent_decode ( String text ) {
	let bytes := [];
	let i := 0;
	let n := length text;

	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if (
			ch \u2261 "%"
			and i + 2 < n
			and substr( text, i + 1, 1 ) ~ /[0-9A-Fa-f]/
			and substr( text, i + 2, 1 ) ~ /[0-9A-Fa-f]/
		) {
			bytes.push(
				_jsonpointer_hex_value( substr( text, i + 1, 1 ) ) * 16
				+ _jsonpointer_hex_value( substr( text, i + 2, 1 ) ),
			);
			i += 3;
			next;
		}

		let code := ord(ch);
		die "JSONPointer URL fragment contains non-ASCII literal character"
			if code > 127;
		bytes.push(code);
		i++;
	}

	return to_string( _jsonpointer_bytes_to_binary(bytes) );
}

function _jsonpointer_decode_token ( String raw ) {
	let out := replace( raw, "~1", "/", "g" );
	out := replace( out, "~0", "~", "g" );
	return out;
}

function _jsonpointer_parse ( String raw ) {
	die "JSONPointer parse error: pointer must be empty or start with '/'"
		if raw \u2262 "" and substr( raw, 0, 1 ) \u2262 "/";

	let steps := [];
	return steps if raw \u2261 "";

	let i := 1;
	let start := 1;
	let n := length raw;

	while ( i <= n ) {
		if ( i \u2261 n or substr( raw, i, 1 ) \u2261 "/" ) {
			let token := substr( raw, start, i - start );
			let j := 0;
			while ( j < length token ) {
				if ( substr( token, j, 1 ) \u2261 "~" ) {
					die "JSONPointer parse error: invalid '~' escape"
						if j + 1 >= length token;
					let esc := substr( token, j + 1, 1 );
					die "JSONPointer parse error: invalid '~' escape"
						if esc \u2262 "0" and esc \u2262 "1";
					j += 2;
					next;
				}
				j++;
			}
			steps.push( _jsonpointer_decode_token(token) );
			start := i + 1;
		}
		i++;
	}

	return steps;
}

function extract_pointer_from_url ( String url ) {
	let hash := index( url, "#" );
	if ( hash < 0 ) {
		return {
			baseurl: url,
			pointer: null,
		};
	}

	let pointer := _jsonpointer_percent_decode( substr( url, hash + 1 ) );
	_jsonpointer_parse(pointer);

	return {
		baseurl: substr( url, 0, hash ),
		pointer: pointer,
	};
}

class JSONPointer {
	let String path;
	let Array _steps := [];

	static method use () {
		from std/internals import setupperprop;
		setupperprop( 1, "paths", self );
	}

	method __build__ () {
		_steps := _jsonpointer_parse(path);
	}

	method expression () {
		return path;
	}

	method _node ( value, parent, key ) {
		return {
			value: value,
			parent: parent,
			key: key,
		};
	}

	method _evaluate_nodes ( value ) {
		let current := [ self._node( value, null, null ) ];

		for ( let step in _steps ) {
			let next_nodes := [];

			for ( let node in current ) {
				let v := node{value};

				if ( v instanceof Dict ) {
					if ( v.exists(step) ) {
						next_nodes.push( self._node( v.get(step), node, step ) );
					}
					next;
				}

				if ( v instanceof PairList ) {
					let found := v.get_all(step);
					if ( found.length() \u2261 1 ) {
						next_nodes.push( self._node( found[0], node, step ) );
					}
					next;
				}

				if ( v instanceof Array ) {
					if ( step ~ /^(0|[1-9][0-9]*)$/ ) {
						let idx := int(step);
						if ( idx < v.length() ) {
							next_nodes.push( self._node( v[idx], node, idx ) );
						}
					}
					next;
				}
			}

			current := next_nodes;
		}

		return current;
	}

	method _evaluate ( value ) {
		return self._evaluate_nodes(value).map( fn n -> n{value} );
	}

	method get ( value ) {
		return self._evaluate(value);
	}

	method select ( value ) {
		return self._evaluate(value);
	}

	method query ( value ) {
		return self._evaluate(value);
	}

	method first ( value, fallback? ) {
		let out := self._evaluate(value);
		return out.length() \u2261 0 ? fallback : out[0];
	}

	method exists ( value ) {
		return self._evaluate(value).length() > 0;
	}

	method _ref_for_node ( Dict node ) {
		let parent := node{parent};
		die "JSONPointer assignment target has no parent node"
			if parent \u2261 null;

		let container := parent{value};
		let key := node{key};

		if ( container instanceof Array ) {
			die "JSONPointer assignment expects numeric array index"
				if not( key instanceof Number );
			return \\ container[key];
		}

		if ( container instanceof Dict ) {
			die "JSONPointer assignment expects string dict key"
				if not( key instanceof String );
			return \\ container{(key)};
		}

		if ( container instanceof PairList ) {
			die "JSONPointer assignment expects string pairlist key"
				if not( key instanceof String );
			return \\ container{(key)};
		}

		die "JSONPointer assignment target container '"
			_ typeof container
			_ "' is not assignable";
	}

	method _apply_assignment_ref ( ref, value, op := ":=", weak := false ) {
		die "JSONPointer weak assignment is not supported"
			if weak;

		if ( op \u2261 ":=" ) {
			return ref(value);
		}

		let current := ref();

		if ( op \u2261 "+=" ) {
			current += value;
		}
		else if ( op \u2261 "-=" ) {
			current -= value;
		}
		else if ( op \u2261 "*=" or op \u2261 "\xD7=" ) {
			current *= value;
		}
		else if ( op \u2261 "/=" or op \u2261 "\xF7=" ) {
			current /= value;
		}
		else if ( op \u2261 "**=" ) {
			current **= value;
		}
		else if ( op \u2261 "_=" ) {
			current _= value;
		}
		else if ( op \u2261 "?:=" ) {
			current ?:= value;
		}
		else if ( op \u2261 "~=" ) {
			current ~= value[0] -> value[1](m);
		}
		else {
			die \`Unsupported path assignment operator '\${op}'\`;
		}

		ref(current);
		return current;
	}

	method _assign_all_result ( value, op, last_result ) {
		return op \u2261 "~=" ? last_result : value;
	}

	method assign_first ( target, value, op := ":=", weak := false ) {
		let nodes := self._evaluate_nodes(target);
		die "JSONPointer assignment found no matches"
			if nodes.length() \u2261 0;
		return self._apply_assignment_ref(
			self._ref_for_node( nodes[0] ),
			value,
			op,
			weak,
		);
	}

	method assign_all ( target, value, op := ":=", weak := false ) {
		let nodes := self._evaluate_nodes(target);
		if ( nodes.length() \u2261 0 ) {
			return self._assign_all_result( value, op, value );
		}

		let last_result := value;
		for ( let node in nodes ) {
			last_result := self._apply_assignment_ref(
				self._ref_for_node(node),
				value,
				op,
				weak,
			);
		}

		return self._assign_all_result( value, op, last_result );
	}

	method assign_maybe ( target, value, op := ":=", weak := false ) {
		let nodes := self._evaluate_nodes(target);
		if ( nodes.length() \u2261 0 ) {
			return false;
		}

		self._apply_assignment_ref(
			self._ref_for_node( nodes[0] ),
			value,
			op,
			weak,
		);
		return true;
	}

	method ref_first ( target ) {
		let nodes := self._evaluate_nodes(target);
		die "JSONPointer assignment found no matches"
			if nodes.length() \u2261 0;
		return self._ref_for_node( nodes[0] );
	}

	method ref_all ( target ) {
		let out := [];
		for ( let node in self._evaluate_nodes(target) ) {
			out.push( self._ref_for_node(node) );
		}
		return out;
	}

	method ref_maybe ( target ) {
		let nodes := self._evaluate_nodes(target);
		return nodes.length() \u2261 0 ? null : self._ref_for_node( nodes[0] );
	}
}
`;
        virtualFiles["/modules/std/data/json/schema.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/json/schema - JSON Schema 2020-12 validation.\n\n=head1 SYNOPSIS\n\n  from std/data/json/schema import\n    JSONSchema,\n    RequiredPropertyError,\n    TypeMismatchError,\n    validate,\n    valid;\n\n  let person_schema := {\n    type: "object",\n    required: [ "name" ],\n    properties: {\n      name: { type: "string" },\n      age:  { type: "integer", minimum: 0 },\n    },\n  };\n\n  say( valid( person_schema, { name: "Ada", age: 37 } ) );\n\n  let result := validate( person_schema, { age: -1 } );\n  for ( let error in result.errors() ) {\n    if ( error instanceof RequiredPropertyError ) {\n      say( error.instanceLocation() _ ": " _ error.error() );\n    }\n  }\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis Pure Zuzu module is supported by all implementations of ZuzuScript.\nNetwork reference loading needs C<std/net/http>, so it is available only in\nruntimes that provide that module.\n\n=head1 DESCRIPTION\n\nI<std/data/json/schema> validates native Zuzu values against JSON Schema\n2020-12 schemas. It is intended for already-decoded JSON data: schemas and\ninstances are normally C<Dict>, C<Array>, strings, numbers, booleans, and\nC<null>.\n\nThe validator also accepts some native collection types where the JSON model\nhas a clear equivalent. C<PairList> is treated as an object and preserves\nduplicate keys for keywords that need to inspect them. C<Set> and C<Bag> are\ntreated as array-like values when order is not important, though ordered\ntuple validation is meaningful only for C<Array>.\n\nValidation can be requested in two forms. Boolean validation short-circuits\nafter the first failure and returns C<true> or C<false>. Full validation\ncollects errors and returns a C<ValidationResult> whose errors are proper\nZuzu objects with methods such as C<keywordLocation()>,\nC<instanceLocation()>, and C<error()>.\n\n=head1 EXPORTS\n\n=head2 Functions\n\n=over\n\n=item C<< valid( schema, instance, options := {} ) >>\n\nReturns C<true> when C<instance> satisfies C<schema>, otherwise C<false>.\nThis mode is the cheapest validation mode and stops as soon as a failure is\nknown.\n\n=item C<< validate( schema, instance, options := {} ) >>\n\nReturns a C<ValidationResult>. This mode attempts to collect every\nindependent validation error it can find.\n\n=back\n\n=head2 Classes\n\n=over\n\n=item C<JSONSchema>\n\nCompiled schema wrapper. Construct with C<< new JSONSchema( schema: ... ) >>\nor pass C<options> as a named field.\n\nCommon methods:\n\n=over\n\n=item C<< is_valid( instance ) >>\n\nBoolean validation with short-circuiting.\n\n=item C<< validate( instance ) >>\n\nFull validation returning a C<ValidationResult>.\n\n=back\n\n=item C<ValidationResult>\n\nThe structured result returned by C<validate>. C<valid()> returns the boolean\nstatus. C<errors()> returns an array of C<ValidationError> objects.\nC<to_Dict()> converts to a Basic-style output shape.\n\n=item C<ValidationError>\n\nBase class for validation errors. The canonical methods are\nC<keywordLocation()>, C<absoluteKeywordLocation()>, C<instanceLocation()>,\nC<error()>, C<keyword()>, C<details()>, and C<to_Dict()>.\n\nErrors are grouped under C<MissingValueError>, C<UnexpectedValueError>, and\nC<WrongValueError>. The module exports specific subclasses for individual\nkeywords such as C<RequiredPropertyError>, C<TypeMismatchError>,\nC<MaximumError>, C<PatternError>, C<AdditionalPropertiesError>,\nC<OneOfError>, and C<ReferenceResolutionError>.\n\n=item C<SubschemaError>\n\nError class used for the message C<A subschema had errors.>. Its\nC<suberrors()> method returns weak links to the errors produced inside the\nsubschema.\n\n=item C<SchemaRegistry>\n\nRegistry for schema resources, anchors, and references. It is usually\nmanaged by C<JSONSchema>, but may be supplied in C<options> when several\nschemas share references.\n\n=item C<HTTPResourceLoader>\n\nReference loader for HTTP and HTTPS resources. It is used only when supplied\ndirectly or when C<allow_network> is true.\n\n=item C<FormatRegistry>\n\nRegistry of C<format> validators. A custom registry may be passed with the\nC<formats> or C<format_registry> option.\n\n=item C<RelativeJSONPointer>\n\nParser and evaluator for Relative JSON Pointers. This class is exported\nbecause JSON Schema uses the syntax for the C<relative-json-pointer> format\nand because it is useful with schema-adjacent data tools.\n\n=back\n\n=head1 OPTIONS\n\nThe C<options> value may be a C<Dict> or C<PairList>.\n\n=over\n\n=item C<base_uri>\n\nBase URI used when registering the root schema and resolving relative\nreferences.\n\n=item C<registry>\n\nA C<SchemaRegistry> to use for C<$ref> and C<$dynamicRef>.\n\n=item C<loader>\n\nA callable or object with a C<load(uri)> method used to fetch missing schema\nresources.\n\n=item C<allow_network>\n\nWhen true and no loader is supplied, C<JSONSchema> creates an\nC<HTTPResourceLoader>.\n\n=item C<formats> or C<format_registry>\n\nA C<FormatRegistry> used for C<format> checks.\n\n=item C<format_assert>\n\nWhen false, C<format> is treated as an annotation and does not make\nvalidation fail.\n\n=item C<unknown_format>\n\nControls unknown formats. The default is C<fail>; C<ignore> treats unknown\nformats as annotations.\n\n=back\n\n=head1 KNOWN OPTIONAL FIXTURE GAPS\n\nThe validator covers all required JSON Schema draft 2020-12 fixture files\nand many optional fixture files. The following optional fixture files are not\nyet promoted to the expected-passing set.\n\n=over\n\n=item F<optional/cross-draft.json>\n\nReferences into older schema drafts are resolved, but draft-specific\nvalidation semantics for referenced historic drafts are not yet applied.\n\n=item F<optional/float-overflow.json>\n\nVery large numeric values still use the host numeric model, so overflow and\nprecision edge cases for C<multipleOf> are not fully handled.\n\n=item F<optional/ecmascript-regex.json>\n\nThe JavaScript runtime passes this fixture, but the Perl and Rust runtimes do\nnot yet emulate enough ECMAScript regular-expression semantics.\n\n=item F<optional/format/duration.json>\n\nThe C<duration> format checker accepts basic duration shapes, but does not\nyet implement the full RFC 3339 duration grammar.\n\n=item F<optional/format/hostname.json>\n\nHostname validation is intentionally conservative and does not yet fully\nvalidate A-label, Punycode, and IDNA edge cases.\n\n=item F<optional/format/idn-hostname.json>\n\nInternationalized hostname validation does not yet implement the full IDNA\nUnicode category, normalization, and bidirectional-text rules.\n\n=item F<optional/format/ipv6.json>\n\nIPv6 validation is still simplified and misses some invalid compression and\ngroup-length edge cases.\n\n=item F<optional/format/time.json>\n\nTime validation handles common RFC 3339 forms, but still has some leap-second\nand timezone-offset edge cases.\n\n=item F<optional/format/uri.json>\n\nURI validation is stricter than a plain string check, but still accepts some\ninvalid authority, userinfo, character, and port cases.\n\n=back\n\n=head1 PORTABILITY\n\nThe module is pure ZuzuScript. Behaviour that depends on regular expression\ndetails or HTTP support may vary with the host runtime.\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/json/schema >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/data/json/schema/core import HTTPResourceLoader, SchemaRegistry;\nfrom std/data/json/schema/format import FormatRegistry;\nfrom std/data/json/schema/output import\n	AdditionalItemsError,\n	AdditionalPropertiesError,\n	AllOfError,\n	AnyOfError,\n	ConstMismatchError,\n	ContentEncodingError,\n	ContentMediaTypeError,\n	DependentRequiredPropertyError,\n	EnumMismatchError,\n	ExclusiveMaximumError,\n	ExclusiveMinimumError,\n	FalseSchemaError,\n	FormatError,\n	IfThenElseError,\n	MaxContainsError,\n	MaximumError,\n	MaxItemsError,\n	MaxLengthError,\n	MaxPropertiesError,\n	MinContainsError,\n	MinimumError,\n	MinItemsError,\n	MinLengthError,\n	MinPropertiesError,\n	MissingValueError,\n	MultipleOfError,\n	NotMatchedError,\n	OneOfError,\n	PatternError,\n	PropertyNamesError,\n	ReferenceResolutionError,\n	RequiredPropertyError,\n	SubschemaError,\n	TypeMismatchError,\n	UnevaluatedItemsError,\n	UnevaluatedPropertiesError,\n	UnexpectedValueError,\n	UniqueItemsError,\n	UnknownFormatError,\n	ValidationError,\n	ValidationResult,\n	WrongValueError;\nfrom std/data/json/schema/relative_pointer import RelativeJSONPointer;\nfrom std/data/json/schema/validation import JSONSchema, validate, valid;\n';
        virtualFiles["/modules/std/data/json/schema/core.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/json/schema/core - JSON Schema resources and reference registry.\n\n=head1 SYNOPSIS\n\n  from std/data/json/schema/core import SchemaRegistry;\n\n  let registry := new SchemaRegistry();\n  registry.register( address_schema, "https://example.test/address" );\n\n  let subschema := registry.resolve(\n    "https://example.test/address#/properties/postcode",\n  );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis Pure Zuzu module is supported by all implementations of ZuzuScript.\nC<HTTPResourceLoader> requires C<std/net/http> and dies at construction time\nwhen that module is unavailable.\n\n=head1 DESCRIPTION\n\nThis module contains the resource and reference support used by\nI<std/data/json/schema>. It registers schemas under base URIs, indexes\nC<$id>, C<$anchor>, and C<$dynamicAnchor>, and resolves references to either\nwhole resources or JSON Pointer fragments.\n\nMost callers should use C<JSONSchema> from I<std/data/json/schema>. Import\nthis module directly when schemas need to share a registry or when reference\nloading needs to be customised.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<SchemaRegistry>\n\nStores schema resources and resolves references.\n\n=over\n\n=item C<< register( schema, uri := "" ) >>\n\nRegisters C<schema> at C<uri>, indexes nested C<$id> values and anchors, and\nreturns the registry.\n\n=item C<< set_loader( loader ) >>\n\nSets the loader used for missing resources. A loader may be a callable or an\nobject with a C<load(uri)> method. Loaded strings are decoded as JSON before\nbeing registered.\n\n=item C<< resolve( ref, base := "" ) >>\n\nResolves C<ref> against C<base>. Empty fragments return the resource.\nAnchor fragments use the registry\'s anchor index. Pointer fragments are\nresolved with I<std/path/jsonpointer>. Failure to find a resource or target\nthrows an exception.\n\n=back\n\n=item C<HTTPResourceLoader>\n\nSimple HTTP and HTTPS loader. C<load(uri)> fetches C<uri> with\nC<std/net/http> and returns the response content after requiring a successful\nresponse.\n\n=back\n\n=head2 Functions\n\n=over\n\n=item C<< jschema_uri_resolve( base, ref ) >>\n\nResolves the URI reference C<ref> against C<base> for the subset of URI\nresolution needed by this validator.\n\n=item C<< jschema_url_split( url ) >>\n\nReturns a C<Dict> with C<baseurl> and C<fragment>. C<fragment> is C<null>\nwhen C<url> has no C<#>.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/json/schema/core >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/data/json import JSON;\nfrom std/internals import ref_id;\nfrom std/net/http try import UserAgent as _HTTPUserAgent;\nfrom std/path/jsonpointer import JSONPointer;\nfrom std/string import index, join, ord, split, substr;\nfrom std/string/base64 import decode as _base64_decode;\nfrom std/data/json/schema/model import\n	jschema_is_object,\n	jschema_object_entries,\n	jschema_object_get,\n	jschema_object_has;\n\nfunction jschema_url_split ( String url ) {\n	let hash := index( url, "#" );\n	if ( hash < 0 ) {\n		return {\n			baseurl: url,\n			fragment: null,\n		};\n	}\n	return {\n		baseurl: substr( url, 0, hash ),\n		fragment: substr( url, hash + 1 ),\n	};\n}\n\nlet _JSCHEMA_B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\n	_ "abcdefghijklmnopqrstuvwxyz0123456789+/";\n\nfunction _jschema_div_floor ( Number n, Number d ) {\n	return floor( n / d );\n}\n\nfunction _jschema_mod ( Number n, Number d ) {\n	return n - _jschema_div_floor( n, d ) * d;\n}\n\nfunction _jschema_bytes_to_binary ( Array bytes ) {\n	let out := "";\n	let i := 0;\n	let n := bytes.length();\n\n	while ( i < n ) {\n		let b0 := bytes[i];\n		let b1 := null;\n		let b2 := null;\n		if ( i + 1 < n ) {\n			b1 := bytes[i + 1];\n		}\n		if ( i + 2 < n ) {\n			b2 := bytes[i + 2];\n		}\n\n		let c0 := _jschema_div_floor( b0, 4 );\n		let c1 := _jschema_mod( b0, 4 ) * 16;\n		let c2 := 64;\n		let c3 := 64;\n\n		if ( not( b1 == null ) ) {\n			c1 += _jschema_div_floor( b1, 16 );\n			c2 := _jschema_mod( b1, 16 ) * 4;\n			if ( not( b2 == null ) ) {\n				c2 += _jschema_div_floor( b2, 64 );\n				c3 := _jschema_mod( b2, 64 );\n			}\n		}\n\n		out _= substr( _JSCHEMA_B64_ALPHABET, c0, 1 );\n		out _= substr( _JSCHEMA_B64_ALPHABET, c1, 1 );\n		out _= c2 == 64 ? "=" : substr( _JSCHEMA_B64_ALPHABET, c2, 1 );\n		out _= c3 == 64 ? "=" : substr( _JSCHEMA_B64_ALPHABET, c3, 1 );\n		i += 3;\n	}\n\n	return _base64_decode(out);\n}\n\nfunction _jschema_hex_value ( String ch ) {\n	if ( ch ~ /[0-9]/ ) {\n		return 0 + ch;\n	}\n\n	return 10 + index( "abcdef", lc(ch) );\n}\n\nfunction jschema_percent_decode ( String text ) {\n	let bytes := [];\n	let i := 0;\n	let n := length text;\n\n	while ( i < n ) {\n		let ch := substr( text, i, 1 );\n		if (\n			ch \u2261 "%"\n			and i + 2 < n\n			and substr( text, i + 1, 1 ) ~ /[0-9A-Fa-f]/\n			and substr( text, i + 2, 1 ) ~ /[0-9A-Fa-f]/\n		) {\n			bytes.push(\n				_jschema_hex_value( substr( text, i + 1, 1 ) ) * 16\n				+ _jschema_hex_value( substr( text, i + 2, 1 ) ),\n			);\n			i += 3;\n			next;\n		}\n\n		let code := ord(ch);\n		die "JSON Schema URI fragment contains non-ASCII literal character"\n			if code > 127;\n		bytes.push(code);\n		i++;\n	}\n\n	return to_string( _jschema_bytes_to_binary(bytes) );\n}\n\nfunction _jschema_uri_query_split ( String uri ) {\n	let query := index( uri, "?" );\n	if ( query < 0 ) {\n		return {\n			path: uri,\n			query: "",\n		};\n	}\n	return {\n		path: substr( uri, 0, query ),\n		query: substr( uri, query ),\n	};\n}\n\nfunction _jschema_uri_parts ( String uri ) {\n	let m := uri ~ /^([A-Za-z][A-Za-z0-9+.-]*:\\/\\/[^\\/?#]*)(.*)$/;\n	if ( m ) {\n		return {\n			prefix: m[1],\n			path_query: m[2],\n		};\n	}\n\n	m := uri ~ /^([A-Za-z][A-Za-z0-9+.-]*:)(.*)$/;\n	if ( m ) {\n		return {\n			prefix: m[1],\n			path_query: m[2],\n		};\n	}\n\n	return {\n		prefix: "",\n		path_query: uri,\n	};\n}\n\nfunction _jschema_remove_dot_segments ( String path ) {\n	let absolute := length path > 0 and substr( path, 0, 1 ) eq "/";\n	let trailing := length path > 1 and substr( path, length path - 1, 1 ) eq "/";\n	let out := [];\n\n	for ( let segment in split( path, "/" ) ) {\n		if ( segment eq "" or segment eq "." ) {\n			next;\n		}\n		if ( segment eq ".." ) {\n			if (\n				out.length() > 0\n				and out[out.length() - 1] ne ".."\n			) {\n				out.pop();\n			}\n			else if ( not absolute ) {\n				out.push(segment);\n			}\n			next;\n		}\n		out.push(segment);\n	}\n\n	let result := join( "/", out );\n	if ( absolute ) {\n		result := "/" _ result;\n	}\n	if ( trailing and result ne "/" ) {\n		result _= "/";\n	}\n	if ( result eq "" and absolute ) {\n		return "/";\n	}\n	return result;\n}\n\nfunction jschema_uri_resolve ( String base, String ref ) {\n	let split_ref := jschema_url_split(ref);\n	let ref_base := split_ref{baseurl};\n	let fragment := split_ref{fragment} \u2261 null\n		? ""\n		: "#" _ split_ref{fragment};\n\n	if ( ref ~ /^[A-Za-z][A-Za-z0-9+.-]*:/ ) {\n		let absolute_parts := _jschema_uri_parts(ref_base);\n		let absolute_query := _jschema_uri_query_split(\n			absolute_parts{path_query},\n		);\n		return absolute_parts{prefix}\n			_ _jschema_remove_dot_segments(absolute_query{path})\n			_ absolute_query{query}\n			_ fragment;\n	}\n	if ( substr( ref, 0, 1 ) eq "#" ) {\n		return jschema_url_split(base){baseurl} _ ref;\n	}\n	if ( base eq "" ) {\n		return ref;\n	}\n\n	let split_base := jschema_url_split(base){baseurl};\n	if ( ref_base eq "" ) {\n		return split_base _ fragment;\n	}\n\n	let base_parts := _jschema_uri_parts(split_base);\n	let base_query := _jschema_uri_query_split(base_parts{path_query});\n	let ref_query := _jschema_uri_query_split(ref_base);\n\n	if ( substr( ref_base, 0, 1 ) eq "?" ) {\n		return base_parts{prefix} _ base_query{path} _ ref_base _ fragment;\n	}\n\n	if ( substr( ref_query{path}, 0, 1 ) eq "/" ) {\n		return base_parts{prefix}\n			_ _jschema_remove_dot_segments(ref_query{path})\n			_ ref_query{query}\n			_ fragment;\n	}\n\n	let slash := -1;\n	let i := 0;\n	while ( i < length base_query{path} ) {\n		if ( substr( base_query{path}, i, 1 ) eq "/" ) {\n			slash := i;\n		}\n		i++;\n	}\n\n	let base_dir := slash >= 0 ? substr( base_query{path}, 0, slash + 1 ) : "";\n	return base_parts{prefix}\n		_ _jschema_remove_dot_segments( base_dir _ ref_query{path} )\n		_ ref_query{query}\n		_ fragment;\n}\n\nclass HTTPResourceLoader {\n	let _ua := null;\n\n	method __build__ () {\n		die "std/net/http UserAgent is unavailable in this runtime"\n			if _HTTPUserAgent \u2261 null;\n		_ua := new _HTTPUserAgent();\n	}\n\n	method load ( String uri ) {\n		die `JSON Schema network loader only supports HTTP(S): ${uri}`\n			unless uri ~ /^https?:/;\n		return _ua.get(uri).expect_success().content();\n	}\n}\n\nclass SchemaRegistry {\n	let _resources := {};\n	let _anchors := {};\n	let _dynamic_anchors := {};\n	let _schema_bases := [];\n	let _loader := null;\n	let Boolean allow_network := false;\n	let _json := null;\n\n	method __build__ () {\n		_json := new JSON();\n	}\n\n	method set_loader ( loader ) {\n		_loader := loader;\n		return self;\n	}\n\n	method register ( schema, String uri := "" ) {\n		_resources.set( uri, schema );\n		self._index_schema( schema, uri );\n		return self;\n	}\n\n	method _index_subschema ( schema, String base ) {\n		if ( jschema_is_object(schema) ) {\n			self._index_schema( schema, base );\n		}\n	}\n\n	method _index_subschema_array ( value, String base ) {\n		if ( not( value instanceof Array ) ) {\n			return;\n		}\n		for ( let item in value ) {\n			self._index_subschema( item, base );\n		}\n	}\n\n	method _index_subschema_map ( value, String base ) {\n		if ( not jschema_is_object(value) ) {\n			return;\n		}\n		for ( let entry in jschema_object_entries(value) ) {\n			self._index_subschema( entry[1], base );\n		}\n	}\n\n	method _index_schema ( schema, String base ) {\n		if ( not jschema_is_object(schema) ) {\n			return;\n		}\n		let current_base := base;\n\n		if (\n			jschema_object_has( schema, "$id" )\n			and jschema_object_get( schema, "$id" ) instanceof String\n		) {\n			current_base := jschema_uri_resolve(\n				current_base,\n				jschema_object_get( schema, "$id" ),\n			);\n			_resources.set( current_base, schema );\n		}\n		_schema_bases.push( {\n			id: ref_id(schema),\n			base: current_base,\n		} );\n		if (\n			jschema_object_has( schema, "$anchor" )\n			and jschema_object_get( schema, "$anchor" ) instanceof String\n		) {\n			_anchors.set(\n				current_base _ "#" _ jschema_object_get( schema, "$anchor" ),\n				schema,\n			);\n		}\n		if (\n			jschema_object_has( schema, "$dynamicAnchor" )\n			and jschema_object_get( schema, "$dynamicAnchor" ) instanceof String\n		) {\n			_anchors.set(\n				current_base _ "#" _ jschema_object_get( schema, "$dynamicAnchor" ),\n				schema,\n			);\n			_dynamic_anchors.set(\n				current_base _ "#" _ jschema_object_get( schema, "$dynamicAnchor" ),\n				schema,\n			);\n		}\n\n		self._index_subschema_map( jschema_object_get( schema, "$defs" ), current_base );\n		self._index_subschema_map( jschema_object_get( schema, "definitions" ), current_base );\n		self._index_subschema_map( jschema_object_get( schema, "properties" ), current_base );\n		self._index_subschema_map( jschema_object_get( schema, "patternProperties" ), current_base );\n		self._index_subschema_map( jschema_object_get( schema, "dependentSchemas" ), current_base );\n\n		if ( jschema_is_object( jschema_object_get( schema, "dependencies" ) ) ) {\n			for ( let entry in jschema_object_entries( jschema_object_get( schema, "dependencies" ) ) ) {\n				self._index_subschema( entry[1], current_base );\n			}\n		}\n\n		self._index_subschema_array( jschema_object_get( schema, "allOf" ), current_base );\n		self._index_subschema_array( jschema_object_get( schema, "anyOf" ), current_base );\n		self._index_subschema_array( jschema_object_get( schema, "oneOf" ), current_base );\n		self._index_subschema_array( jschema_object_get( schema, "prefixItems" ), current_base );\n\n		self._index_subschema( jschema_object_get( schema, "not" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "if" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "then" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "else" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "items" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "contains" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "additionalProperties" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "unevaluatedItems" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "unevaluatedProperties" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "propertyNames" ), current_base );\n		self._index_subschema( jschema_object_get( schema, "contentSchema" ), current_base );\n	}\n\n	method _load_resource ( String uri ) {\n		if ( _loader \u2261 null ) {\n			return null;\n		}\n\n		let loaded;\n		if ( _loader can load ) {\n			loaded := _loader.load(uri);\n		}\n		else {\n			loaded := _loader(uri);\n		}\n		if ( loaded instanceof String ) {\n			loaded := _json.decode(loaded);\n		}\n		else if ( loaded instanceof BinaryString ) {\n			loaded := _json.decode_binarystring(loaded);\n		}\n		self.register( loaded, uri );\n		return loaded;\n	}\n\n	method resolve_info ( String ref, String base := "" ) {\n		let absolute_uri := jschema_uri_resolve( base, ref );\n		let split := jschema_url_split(absolute_uri);\n		let resource_uri := split{baseurl};\n		let fragment := split{fragment} \u2261 null\n			? null\n			: jschema_percent_decode(split{fragment});\n\n		let resource := _resources.exists(resource_uri)\n			? _resources.get(resource_uri)\n			: self._load_resource(resource_uri);\n		if ( resource \u2261 null ) {\n			die `JSON Schema reference not found: ${absolute_uri}`;\n		}\n\n		let target := resource;\n		if ( fragment \u2262 null and fragment ne "" ) {\n			let anchor_uri := resource_uri _ "#" _ fragment;\n			if ( _anchors.exists(anchor_uri) ) {\n				target := _anchors.get(anchor_uri);\n			}\n			else {\n				die `JSON Schema reference fragment is not a JSON Pointer: ${absolute_uri}`\n					unless substr( fragment, 0, 1 ) eq "/";\n\n				target := new JSONPointer( path: fragment ).first( resource, null );\n				die `JSON Schema reference target not found: ${absolute_uri}`\n					if target \u2261 null;\n			}\n		}\n\n		return {\n			target: target,\n			absolute_uri: absolute_uri,\n			resource_uri: resource_uri,\n			fragment: fragment,\n		};\n	}\n\n	method resolve ( String ref, String base := "" ) {\n		return self.resolve_info( ref, base ){target};\n	}\n\n	method dynamic_anchor ( String resource_uri, String name ) {\n		let key := resource_uri _ "#" _ name;\n		return _dynamic_anchors.exists(key)\n			? _dynamic_anchors.get(key)\n			: null;\n	}\n\n	method has_dynamic_anchor ( String resource_uri, String name ) {\n		return _dynamic_anchors.exists( resource_uri _ "#" _ name );\n	}\n\n	method schema_base ( schema, fallback := null ) {\n		let id := ref_id(schema);\n		for ( let entry in _schema_bases ) {\n			if ( entry{id} \u2261 id ) {\n				return entry{base};\n			}\n		}\n		return fallback;\n	}\n}\n';
        virtualFiles["/modules/std/data/json/schema/format.zzm"] = `=encoding utf8

=head1 NAME

std/data/json/schema/format - JSON Schema format validators.

=head1 SYNOPSIS

  from std/data/json/schema/format import FormatRegistry;

  let formats := new FormatRegistry();
  formats.register( "slug", fn value -> value ~ /^[a-z0-9-]+$/ );

  say( formats.check( "slug", "release-2026" ) );

=head1 IMPLEMENTATION SUPPORT

This Pure Zuzu module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

I<std/data/json/schema/format> provides the C<format> registry used by the
JSON Schema validator. A registry maps format names to callables. A callable
receives the instance value and returns true when the value satisfies the
format.

The default registry includes validators for the standard JSON Schema
formats: C<date-time>, C<date>, C<time>, C<duration>, C<email>,
C<idn-email>, C<hostname>, C<idn-hostname>, C<ipv4>, C<ipv6>, C<uri>,
C<uri-reference>, C<iri>, C<iri-reference>, C<uuid>, C<json-pointer>,
C<relative-json-pointer>, and C<regex>.

Format checking is controlled by the validator. By default C<format> is
annotation-only; pass C<< format_assert: true >> to C<JSONSchema> to make it
assertive.

=head1 EXPORTS

=head2 Classes

=over

=item C<FormatRegistry>

Registry of named format validators.

=over

=item C<< register( name, validator ) >>

Registers C<validator> under C<name> and returns the registry. The validator
may be any callable value.

=item C<< has( name ) >>

Returns true when a validator has been registered for C<name>.

=item C<< check( name, value ) >>

Returns the result of the named validator. Unknown names return C<false>;
the higher-level validator decides whether an unknown format is ignored or
reported as an error.

=back

=back

=head1 PORTABILITY

Some validators rely on the host runtime's regular expression engine. The
validators are intentionally conservative and do not attempt full RFC-grade
parsing for every format.

=head1 COPYRIGHT AND LICENCE

B<< std/data/json/schema/format >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/internals import to_Regexp_with_flags;
from std/path/jsonpointer import JSONPointer;
from std/data/json/schema/relative_pointer import valid_relative_json_pointer;
from std/string import index, ord, substr, split;

function _fmt_ipv4_ok;
function _fmt_ipv6_ok;
function _fmt_uri_reference_ok;
function _fmt_regex_hex;

function _fmt_regex ( String pattern ) {
	return fn value -> value instanceof String
		and value ~ to_Regexp_with_flags(pattern, "u");
}

function _fmt_date_parts_ok ( String value ) {
	let m := value ~ /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
	if ( not m ) { return false; }
	let month := int(m[2]);
	let day := int(m[3]);
	if ( month < 1 or month > 12 ) { return false; }
	let max := 31;
	if ( month in [ 4, 6, 9, 11 ] ) {
		max := 30;
	}
	else if ( month == 2 ) {
		let year := int(m[1]);
		let leap := ( year mod 400 == 0 )
			or ( year mod 4 == 0 and year mod 100 != 0 );
		max := leap ? 29 : 28;
	}
	return day >= 1 and day <= max;
}

function _fmt_time_ok ( String value ) {
	let m := value ~ /^([0-9]{2}):([0-9]{2}):([0-9]{2})(?:\\.[0-9]+)?(?:[Zz]|([+-])([0-9]{2}):([0-9]{2}))$/;
	if ( not m ) { return false; }
	let hour := int(m[1]);
	let minute := int(m[2]);
	let second := int(m[3]);
	let has_offset := m[4] instanceof String and m[4] ne "";
	if ( hour > 23 or minute > 59 ) { return false; }
	if ( second > 60 ) { return false; }
	if ( has_offset ) {
		if ( int(m[5]) > 23 or int(m[6]) > 59 ) { return false; }
	}
	if ( second == 60 and minute != 59 ) { return false; }
	if ( second == 60 and not has_offset and hour != 23 ) { return false; }
	return true;
}

function _fmt_date_time_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	let m := value ~ /^([0-9]{4}-[0-9]{2}-[0-9]{2})[Tt]([0-9]{2}:[0-9]{2}:[0-9]{2}(?:\\.[0-9]+)?(?:[Zz]|[+-][0-9]{2}:[0-9]{2}))$/;
	return m and _fmt_date_parts_ok(m[1]) and _fmt_time_ok(m[2]);
}

function _fmt_date_ok ( value ) {
	return value instanceof String and _fmt_date_parts_ok(value);
}

function _fmt_time_value_ok ( value ) {
	return value instanceof String and _fmt_time_ok(value);
}

function _fmt_duration_ok ( value ) {
	return value instanceof String
		and length value > 1
		and value ~ /^P[0-9YMWDTHS.,+-]+$/;
}

function _fmt_hostname_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( length value > 253 ) { return false; }
	if ( value eq "" ) { return false; }
	for ( let label in split( value, "." ) ) {
		if ( label eq "" or length label > 63 ) { return false; }
		if ( not( label ~ /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/ ) ) {
			return false;
		}
	}
	return true;
}

function _fmt_email_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	let address;
	try {
		from std/mail import Address;
		address := Address.parse(value);
	}
	catch {
		return false;
	}
	if ( address.display_name() \u2262 null ) { return false; }
	let domain := address.domain();
	if ( substr( domain, 0, 1 ) eq "[" ) {
		let inner := substr( domain, 1, length domain - 2 );
		if ( substr( inner, 0, 5 ) eq "IPv6:" ) {
			return _fmt_ipv6_ok( substr( inner, 5 ) );
		}
		return _fmt_ipv4_ok(inner);
	}
	return _fmt_hostname_ok(domain);
}

function _fmt_idn_hostname_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( length value > 253 ) { return false; }
	if ( value eq "" or value ~ /\\s/ ) { return false; }
	for ( let label in split( value, "." ) ) {
		if ( label eq "" or length label > 63 ) { return false; }
		if ( substr( label, 0, 1 ) eq "-" ) { return false; }
		if ( substr( label, length label - 1, 1 ) eq "-" ) { return false; }
	}
	return true;
}

function _fmt_idn_email_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	let m := value ~ /^([^@\\s]+)@([^@\\s]+)$/;
	return m and _fmt_idn_hostname_ok(m[2]);
}

function _fmt_ipv4_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( value ~ /[\\r\\n]/ ) { return false; }
	if ( value eq "" or substr( value, 0, 1 ) eq "." ) { return false; }
	if ( substr( value, length value - 1, 1 ) eq "." ) { return false; }
	let parts := split( value, "." );
	if ( parts.length() != 4 ) { return false; }
	for ( let part in parts ) {
		if ( not( part ~ /^(0|[1-9][0-9]*)$/ ) ) { return false; }
		let n := int(part);
		if ( n > 255 ) { return false; }
	}
	return true;
}

function _fmt_ipv6_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( not( value ~ /^[0-9A-Fa-f:.]+$/ ) ) { return false; }
	if ( value ~ /::/ ) { return true; }
	return split( value, ":" ).length() == 8;
}

function _fmt_uri_ok ( value ) {
	return value instanceof String
		and value ~ /^[A-Za-z][A-Za-z0-9+.-]*:[^\\s]*$/
		and _fmt_uri_reference_ok(value);
}

function _fmt_uri_chars_ok ( String value, Boolean allow_non_ascii ) {
	if ( value ~ /[\\s\\\\]/ ) { return false; }
	let i := 0;
	while ( i < length value ) {
		let ch := substr( value, i, 1 );
		let cp := ord(ch);
		if ( ch eq "%" ) {
			if ( not _fmt_regex_hex( value, i + 1, 2 ) ) {
				return false;
			}
			i += 3;
			next;
		}
		if ( not allow_non_ascii and cp > 127 ) {
			return false;
		}
		i++;
	}
	return true;
}

function _fmt_uri_reference_ok ( value ) {
	return value instanceof String and _fmt_uri_chars_ok( value, false );
}

function _fmt_last_index ( String value, String needle ) {
	let found := -1;
	let i := 0;
	while ( i < length value ) {
		if ( substr( value, i, length needle ) eq needle ) {
			found := i;
		}
		i++;
	}
	return found;
}

function _fmt_authority_from_iri ( String value ) {
	let scheme := index( value, ":" );
	if ( scheme < 0 or substr( value, scheme + 1, 2 ) ne "//" ) {
		return null;
	}
	let start := scheme + 3;
	let end := start;
	while ( end < length value ) {
		let ch := substr( value, end, 1 );
		if ( ch eq "/" or ch eq "?" or ch eq "#" ) {
			last;
		}
		end++;
	}
	return substr( value, start, end - start );
}

function _fmt_colon_count ( String value ) {
	let count := 0;
	let i := 0;
	while ( i < length value ) {
		if ( substr( value, i, 1 ) eq ":" ) {
			count++;
		}
		i++;
	}
	return count;
}

function _fmt_iri_authority_ok ( String authority ) {
	if ( authority eq "" or authority ~ /[\\s\\\\]/ ) { return false; }
	let hostport := authority;
	let at := _fmt_last_index( authority, "@" );
	if ( at >= 0 ) {
		hostport := substr( authority, at + 1 );
	}
	if ( hostport eq "" ) { return false; }
	if ( substr( hostport, 0, 1 ) eq "[" ) {
		let close := index( hostport, "]" );
		if ( close < 0 ) { return false; }
		let literal := substr( hostport, 1, close - 1 );
		let rest := substr( hostport, close + 1 );
		if ( not _fmt_ipv6_ok(literal) ) { return false; }
		return rest eq "" or rest ~ /^:[0-9]+$/;
	}
	return _fmt_colon_count(hostport) <= 1;
}

function _fmt_iri_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( not _fmt_uri_chars_ok( value, true ) ) { return false; }
	if ( not( value ~ /^[A-Za-z][A-Za-z0-9+.-]*:/ ) ) { return false; }
	let authority := _fmt_authority_from_iri(value);
	return authority \u2261 null or _fmt_iri_authority_ok(authority);
}

function _fmt_iri_reference_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	if ( not _fmt_uri_chars_ok( value, true ) ) { return false; }
	if ( value ~ /^[A-Za-z][A-Za-z0-9+.-]*:/ ) {
		return _fmt_iri_ok(value);
	}
	if ( substr( value, 0, 2 ) eq "//" ) {
		let authority := _fmt_authority_from_iri( "x:" _ value );
		return authority \u2262 null and _fmt_iri_authority_ok(authority);
	}
	return true;
}

function _fmt_regex_hex ( String value, Number start, Number count ) {
	if ( start + count > length value ) {
		return false;
	}
	let i := start;
	while ( i < start + count ) {
		if ( not( substr( value, i, 1 ) ~ /[0-9A-Fa-f]/ ) ) {
			return false;
		}
		i++;
	}
	return true;
}

function _fmt_regex_escape_ok ( String value, Number slash, Boolean in_class ) {
	if ( slash + 1 >= length value ) {
		return {
			ok: false,
			next: slash + 1,
		};
	}

	let esc := substr( value, slash + 1, 1 );
	if ( esc ~ /[fnrtv0bBdDsSwW]/ ) {
		return {
			ok: true,
			next: slash + 2,
		};
	}
	if ( esc eq "c" ) {
		return {
			ok: slash + 2 < length value
				and substr( value, slash + 2, 1 ) ~ /[A-Za-z]/,
			next: slash + 3,
		};
	}
	if ( esc eq "x" ) {
		return {
			ok: _fmt_regex_hex( value, slash + 2, 2 ),
			next: slash + 4,
		};
	}
	if ( esc eq "u" ) {
		if ( slash + 2 < length value and substr( value, slash + 2, 1 ) eq "{" ) {
			let i := slash + 3;
			let digits := 0;
			while ( i < length value and substr( value, i, 1 ) ne "}" ) {
				if ( not( substr( value, i, 1 ) ~ /[0-9A-Fa-f]/ ) ) {
					return {
						ok: false,
						next: i + 1,
					};
				}
				digits++;
				i++;
			}
			return {
				ok: i < length value and digits > 0,
				next: i + 1,
			};
		}
		return {
			ok: _fmt_regex_hex( value, slash + 2, 4 ),
			next: slash + 6,
		};
	}
	if ( esc eq "p" or esc eq "P" ) {
		let open := slash + 2;
		if ( open >= length value or substr( value, open, 1 ) ne "{" ) {
			return {
				ok: false,
				next: open,
			};
		}
		let close := open + 1;
		while ( close < length value and substr( value, close, 1 ) ne "}" ) {
			close++;
		}
		return {
			ok: close < length value and close > open + 1,
			next: close + 1,
		};
	}
	if ( esc ~ /[A-Za-z]/ ) {
		return {
			ok: false,
			next: slash + 2,
		};
	}

	return {
		ok: true,
		next: slash + 2,
	};
}

function _fmt_json_pointer_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	try {
		new JSONPointer( path: value );
		return true;
	}
	catch {
		return false;
	}
}

function _fmt_regex_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	let parens := 0;
	let in_class := false;
	let class_items := 0;
	let i := 0;

	while ( i < length value ) {
		let ch := substr( value, i, 1 );
		if ( ch eq "\\\\" ) {
			let escaped := _fmt_regex_escape_ok( value, i, in_class );
			if ( not escaped{ok} ) {
				return false;
			}
			if ( in_class ) {
				class_items++;
			}
			i := escaped{next};
			next;
		}
		if ( in_class ) {
			if ( ch eq "]" and class_items > 0 ) {
				in_class := false;
			}
			else {
				class_items++;
			}
			i++;
			next;
		}
		if ( ch eq "[" ) {
			in_class := true;
			class_items := 0;
		}
		else if ( ch eq "]" ) {
			return false;
		}
		else if ( ch eq "(" ) {
			parens++;
		}
		else if ( ch eq ")" ) {
			if ( parens == 0 ) {
				return false;
			}
			parens--;
		}
		i++;
	}

	if ( in_class or parens != 0 ) {
		return false;
	}

	try {
		to_Regexp_with_flags(value, "u");
		return true;
	}
	catch {
		return false;
	}
}

function _fmt_uri_template_ok ( value ) {
	if ( not( value instanceof String ) ) { return false; }
	let depth := 0;
	let expr := "";
	let i := 0;
	while ( i < length value ) {
		let ch := substr( value, i, 1 );
		if ( ch eq "{" ) {
			if ( depth != 0 ) { return false; }
			depth := 1;
			expr := "";
		}
		else if ( ch eq "}" ) {
			if ( depth != 1 or expr eq "" ) { return false; }
			if ( not( expr ~ /^[+#./;?&]?[A-Za-z0-9_][A-Za-z0-9_.%]*(?::[1-9][0-9]{0,3})?$/ ) ) {
				return false;
			}
			depth := 0;
		}
		else if ( depth == 1 ) {
			expr _= ch;
		}
		i++;
	}
	return depth == 0;
}

class FormatRegistry {
	let _validators := {};

	method __build__ () {
		self.register( "date-time", _fmt_date_time_ok );
		self.register( "date", _fmt_date_ok );
		self.register( "time", _fmt_time_value_ok );
		self.register( "duration", _fmt_duration_ok );
		self.register( "email", _fmt_email_ok );
		self.register( "idn-email", _fmt_idn_email_ok );
		self.register( "hostname", _fmt_hostname_ok );
		self.register( "idn-hostname", _fmt_idn_hostname_ok );
		self.register( "ipv4", _fmt_ipv4_ok );
		self.register( "ipv6", _fmt_ipv6_ok );
		self.register( "uri", _fmt_uri_ok );
		self.register( "uri-reference", _fmt_uri_reference_ok );
		self.register( "iri", _fmt_iri_ok );
		self.register( "iri-reference", _fmt_iri_reference_ok );
		self.register( "uuid", _fmt_regex(
			"^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$",
		) );
		self.register( "json-pointer", _fmt_json_pointer_ok );
		self.register(
			"relative-json-pointer",
			fn v -> v instanceof String and valid_relative_json_pointer(v),
		);
		self.register( "regex", _fmt_regex_ok );
		self.register( "uri-template", _fmt_uri_template_ok );
	}

	method register ( String name, validator ) {
		_validators.set( name, validator );
		return self;
	}

	method has ( String name ) {
		return _validators.exists(name);
	}

	method check ( String name, value ) {
		if ( not self.has(name) ) { return false; }
		return _validators.get(name)(value);
	}
}
`;
        virtualFiles["/modules/std/data/json/schema/model.zzm"] = `=encoding utf8

=head1 NAME

std/data/json/schema/model - JSON value projection helpers.

=head1 SYNOPSIS

  from std/data/json/schema/model import
    jschema_is_object,
    jschema_object_get,
    jschema_type_name;

  if ( jschema_is_object(value) ) {
    say( jschema_object_get( value, "title", "(untitled)" ) );
  }

  say( jschema_type_name(value) );

=head1 IMPLEMENTATION SUPPORT

This Pure Zuzu module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

This module adapts native Zuzu collection types to the JSON data model used
by the JSON Schema validator. It is mostly an implementation helper, but its
functions are exported so related schema tools can share the same treatment
of objects, arrays, and pointer locations.

C<Dict> and C<PairList> are object-like. C<PairList> preserves duplicate
keys through C<jschema_object_get_all> and C<jschema_object_entries>. C<Array>
is ordered array-like. C<Set> and C<Bag> are unordered array-like; they can
be used for array keywords where order does not matter.

=head1 EXPORTS

=head2 Functions

=over

=item C<< jschema_is_object( value ) >>

Returns true for C<Dict> and C<PairList>.

=item C<< jschema_is_ordered_array( value ) >>

Returns true for C<Array>.

=item C<< jschema_is_unordered_array( value ) >>

Returns true for C<Set> and C<Bag>.

=item C<< jschema_is_arrayish( value ) >>

Returns true for ordered and unordered array-like values.

=item C<< jschema_type_name( value ) >>

Returns the JSON Schema type name for C<value>: C<null>, C<boolean>,
C<number>, C<string>, C<array>, C<object>, or C<unknown>.

=item C<< jschema_type_matches( value, expected ) >>

Returns true when C<value> matches the JSON Schema type named by
C<expected>. C<integer> is accepted for numbers with no fractional part.

=item C<< jschema_object_has( object, key ) >>

Returns true when an object-like value contains C<key>.

=item C<< jschema_object_get( object, key, fallback := null ) >>

Returns the value for C<key>, or C<fallback> when it is missing.

=item C<< jschema_object_get_all( object, key ) >>

Returns all values for C<key>. For C<Dict>, the result has either one value
or none. For C<PairList>, duplicate keys are preserved.

=item C<< jschema_object_keys( object ) >>

Returns object keys, preserving the underlying collection's key behaviour.

=item C<< jschema_object_unique_keys( object ) >>

Returns object keys with duplicates removed.

=item C<< jschema_object_entries( object ) >>

Returns an array of C<[ key, value ]> pairs.

=item C<< jschema_array_items( value ) >>

Returns the array items for an array-like value. Unordered collections are
converted with C<to_Array()>.

=item C<< jschema_array_length( value ) >>

Returns the length of an array-like value, or zero for other values.

=item C<< jschema_pointer_escape( token ) >>

Escapes a JSON Pointer token by replacing C<~> and C</>.

=item C<< jschema_pointer_join( base, step ) >>

Appends C<step> to a JSON Pointer path.

=item C<< jschema_deep_equal( left, right ) >>

Compares two values using ZuzuScript equality. The validator uses this for
C<const>, C<enum>, and uniqueness checks.

=back

=head1 COPYRIGHT AND LICENCE

B<< std/data/json/schema/model >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/string import replace;

function jschema_is_object ( value ) {
	return value instanceof Dict or value instanceof PairList;
}

function jschema_is_ordered_array ( value ) {
	return value instanceof Array;
}

function jschema_is_unordered_array ( value ) {
	return value instanceof Set or value instanceof Bag;
}

function jschema_is_arrayish ( value ) {
	return jschema_is_ordered_array(value)
		or jschema_is_unordered_array(value);
}

function jschema_type_name ( value ) {
	if ( value \u2261 null ) { return "null"; }
	if ( value instanceof Boolean ) { return "boolean"; }
	if ( value instanceof Number ) { return "number"; }
	if ( value instanceof String or value instanceof BinaryString ) {
		return "string";
	}
	if ( jschema_is_arrayish(value) ) { return "array"; }
	if ( jschema_is_object(value) ) { return "object"; }
	return "unknown";
}

function jschema_type_matches ( value, String expected ) {
	switch ( expected : eq ) {
		case "null":    return value \u2261 null;
		case "boolean": return value instanceof Boolean;
		case "number":  return value instanceof Number;
		case "integer": return value instanceof Number and floor(value) == value;
		case "string":
			return value instanceof String or value instanceof BinaryString;
		case "array":   return jschema_is_arrayish(value);
		case "object":  return jschema_is_object(value);
	}
	return false;
}

function jschema_object_has ( object, String key ) {
	if ( object instanceof Dict or object instanceof PairList ) {
		for ( let existing in object.keys() ) {
			if ( existing eq key ) { return true; }
		}
	}
	return false;
}

function jschema_object_get ( object, String key, fallback := null ) {
	if ( object instanceof Dict or object instanceof PairList ) {
		return jschema_object_has(object, key) ? object.get(key) : fallback;
	}
	return fallback;
}

function jschema_object_get_all ( object, String key ) {
	if ( object instanceof Dict ) {
		return jschema_object_has(object, key) ? [ object.get(key) ] : [];
	}
	if ( object instanceof PairList ) {
		return object.get_all(key);
	}
	return [];
}

function jschema_object_keys ( object ) {
	if ( object instanceof Dict or object instanceof PairList ) {
		return object.keys();
	}
	return [];
}

function jschema_object_unique_keys ( object ) {
	let out := [];
	for ( let key in jschema_object_keys(object) ) {
		if ( not( key in out ) ) {
			out.push(key);
		}
	}
	return out;
}

function jschema_object_entries ( object ) {
	let out := [];
	if ( object instanceof Dict ) {
		for ( let key in object.keys() ) {
			out.push( [ key, object.get(key) ] );
		}
	}
	else if ( object instanceof PairList ) {
		for ( let pair in object.to_Array() ) {
			out.push( [ pair.key, pair.value ] );
		}
	}
	return out;
}

function jschema_array_items ( value ) {
	if ( value instanceof Array ) { return value; }
	if ( value instanceof Set or value instanceof Bag ) {
		return value.to_Array();
	}
	return [];
}

function jschema_array_length ( value ) {
	if ( jschema_is_arrayish(value) ) { return value.length(); }
	return 0;
}

function jschema_pointer_escape ( String token ) {
	return token
		\u25B7 replace( ^^, "~", "~0", "g" )
		\u25B7 replace( ^^, "/", "~1", "g" );
}

function jschema_pointer_join ( String base, step ) {
	return base _ "/" _ jschema_pointer_escape("" _ step);
}

function jschema_deep_equal ( left, right ) {
	return left == right;
}
`;
        virtualFiles["/modules/std/data/json/schema/output.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/json/schema/output - JSON Schema validation output objects.\n\n=head1 SYNOPSIS\n\n  from std/data/json/schema import\n    RequiredPropertyError,\n    TypeMismatchError,\n    validate;\n\n  let result := validate( schema, instance );\n\n  if ( not result.valid() ) {\n    for ( let error in result.errors() ) {\n      say( error.keywordLocation() _ " " _ error.error() );\n      if ( error instanceof TypeMismatchError ) {\n        say( "type problem" );\n      }\n    }\n  }\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module defines the object output model for JSON Schema validation. It\nis modelled on the Basic output shape from JSON Schema Core, but each error\nis a real Zuzu object instead of a plain C<Dict>. The class hierarchy lets\ncallers use C<instanceof> to distinguish broad categories and precise\nkeyword failures.\n\nThe hierarchy starts with C<ValidationError>. Most keyword failures are\ngrouped under C<MissingValueError>, C<UnexpectedValueError>, or\nC<WrongValueError>. Applicator keywords can also produce C<SubschemaError>,\nwhose children are stored as weak links to avoid retaining a whole validation\ntree only through parent summary errors.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<ValidationResult>\n\nStructured result returned by C<validate>.\n\n=over\n\n=item C<valid()>\n\nReturns the boolean validation status.\n\n=item C<errors()>\n\nReturns an array of C<ValidationError> objects.\n\n=item C<to_Dict()>\n\nReturns a Basic-style C<Dict>. Errors are converted with their own\nC<to_Dict()> method.\n\n=back\n\n=item C<ValidationError>\n\nBase class for all validation errors.\n\nMethods:\n\n=over\n\n=item C<keywordLocation()>\n\nJSON Pointer location of the failing keyword inside the schema.\n\n=item C<absoluteKeywordLocation()>\n\nAbsolute keyword URI when known, otherwise C<null>.\n\n=item C<instanceLocation()>\n\nJSON Pointer location of the failing instance value.\n\n=item C<error()>\n\nHuman-readable error message.\n\n=item C<keyword()>\n\nThe keyword that produced the error, when known.\n\n=item C<details()>\n\nKeyword-specific structured detail, when present.\n\n=item C<to_Dict()>\n\nConverts the error to a Basic-style C<Dict>.\n\n=back\n\nSnake-case aliases are provided for the location methods:\nC<keyword_location()>, C<absolute_keyword_location()>, and\nC<instance_location()>.\n\n=item C<MissingValueError>\n\nBase class for failures where a required value is absent. Subclasses are\nC<RequiredPropertyError>, C<DependentRequiredPropertyError>,\nC<MinItemsError>, C<MinPropertiesError>, and C<MinContainsError>.\n\n=item C<UnexpectedValueError>\n\nBase class for failures where a value is present but not allowed.\nSubclasses are C<AdditionalPropertiesError>,\nC<UnevaluatedPropertiesError>, C<AdditionalItemsError>,\nC<UnevaluatedItemsError>, C<MaxItemsError>, C<MaxPropertiesError>,\nC<MaxContainsError>, and C<NotMatchedError>.\n\n=item C<WrongValueError>\n\nBase class for failures where a value is present but does not meet a\nconstraint. Subclasses are C<FalseSchemaError>, C<TypeMismatchError>,\nC<EnumMismatchError>, C<ConstMismatchError>, C<MultipleOfError>,\nC<MinimumError>, C<MaximumError>, C<ExclusiveMinimumError>,\nC<ExclusiveMaximumError>, C<MinLengthError>, C<MaxLengthError>,\nC<PatternError>, C<FormatError>, C<UnknownFormatError>,\nC<UniqueItemsError>, C<PropertyNamesError>, C<ContentEncodingError>,\nC<ContentMediaTypeError>, C<AllOfError>, C<AnyOfError>, C<OneOfError>, and\nC<IfThenElseError>.\n\n=item C<SubschemaError>\n\nSummary error for the message C<A subschema had errors.>. The\nC<suberrors()> method returns live child errors that are still reachable.\nChildren are added with C<add_suberror(error)> and\nC<add_suberrors(errors)>.\n\n=item C<ReferenceResolutionError>\n\nError class for failures while resolving C<$ref> or C<$dynamicRef>.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/json/schema/output >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nclass ValidationError {\n	let String keywordLocation;\n	let absoluteKeywordLocation := null;\n	let String instanceLocation;\n	let String error;\n	let keyword := null;\n	let details := null;\n\n	method keywordLocation () { return keywordLocation; }\n	method absoluteKeywordLocation () { return absoluteKeywordLocation; }\n	method instanceLocation () { return instanceLocation; }\n	method error () { return error; }\n	method keyword () { return keyword; }\n	method details () { return details; }\n\n	method keyword_location () { return keywordLocation; }\n	method absolute_keyword_location () { return absoluteKeywordLocation; }\n	method instance_location () { return instanceLocation; }\n\n	method to_Dict () {\n		let out := {\n			keywordLocation: keywordLocation,\n			instanceLocation: instanceLocation,\n			error: error,\n		};\n		if ( absoluteKeywordLocation \u2262 null ) {\n			out{absoluteKeywordLocation} := absoluteKeywordLocation;\n		}\n		return out;\n	}\n}\n\nclass MissingValueError extends ValidationError;\nclass UnexpectedValueError extends ValidationError;\nclass WrongValueError extends ValidationError;\n\nclass SubschemaError extends ValidationError {\n	let _suberrors := [];\n\n	method add_suberror ( child_error ) {\n		_suberrors.push_weak(child_error);\n		return child_error;\n	}\n\n	method add_suberrors ( errors ) {\n		for ( let child_error in errors ) {\n			self.add_suberror(child_error);\n		}\n		return self;\n	}\n\n	method suberrors () {\n		return _suberrors.grep( fn e -> e \u2262 null );\n	}\n}\n\nclass FalseSchemaError extends WrongValueError;\n\nclass RequiredPropertyError extends MissingValueError;\nclass DependentRequiredPropertyError extends MissingValueError;\nclass MinItemsError extends MissingValueError;\nclass MinPropertiesError extends MissingValueError;\nclass MinContainsError extends MissingValueError;\n\nclass AdditionalPropertiesError extends UnexpectedValueError;\nclass UnevaluatedPropertiesError extends UnexpectedValueError;\nclass AdditionalItemsError extends UnexpectedValueError;\nclass UnevaluatedItemsError extends UnexpectedValueError;\nclass MaxItemsError extends UnexpectedValueError;\nclass MaxPropertiesError extends UnexpectedValueError;\nclass MaxContainsError extends UnexpectedValueError;\nclass NotMatchedError extends UnexpectedValueError;\n\nclass TypeMismatchError extends WrongValueError;\nclass EnumMismatchError extends WrongValueError;\nclass ConstMismatchError extends WrongValueError;\nclass MultipleOfError extends WrongValueError;\nclass MinimumError extends WrongValueError;\nclass MaximumError extends WrongValueError;\nclass ExclusiveMinimumError extends WrongValueError;\nclass ExclusiveMaximumError extends WrongValueError;\nclass MinLengthError extends WrongValueError;\nclass MaxLengthError extends WrongValueError;\nclass PatternError extends WrongValueError;\nclass FormatError extends WrongValueError;\nclass UnknownFormatError extends FormatError;\nclass UniqueItemsError extends WrongValueError;\nclass PropertyNamesError extends WrongValueError;\nclass ContentEncodingError extends WrongValueError;\nclass ContentMediaTypeError extends WrongValueError;\nclass AllOfError extends WrongValueError;\nclass AnyOfError extends WrongValueError;\nclass OneOfError extends WrongValueError;\nclass IfThenElseError extends WrongValueError;\n\nclass ReferenceResolutionError extends ValidationError;\n\nclass ValidationResult {\n	let Boolean valid := true;\n	let Array errors := [];\n\n	method valid () { return valid; }\n	method errors () { return errors; }\n\n	method to_Dict () {\n		let out := { valid: valid };\n		if ( not valid ) {\n			out{errors} := errors.map( fn e -> e.to_Dict() );\n		}\n		return out;\n	}\n}\n';
        virtualFiles["/modules/std/data/json/schema/relative_pointer.zzm"] = `=encoding utf8

=head1 NAME

std/data/json/schema/relative_pointer - Relative JSON Pointer parser.

=head1 SYNOPSIS

  from std/data/json/schema/relative_pointer import RelativeJSONPointer;

  let doc := {
    people: [
      { name: "Ada" },
      { name: "Grace" },
    ],
  };

  let pointer := new RelativeJSONPointer( path: "1/name" );
  say( pointer.first( doc, "/people/0/age", "(missing)" ) );

=head1 IMPLEMENTATION SUPPORT

This Pure Zuzu module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

Relative JSON Pointer describes a target by starting from a context location,
climbing zero or more levels, optionally shifting an array index, and then
optionally applying a normal JSON Pointer suffix. JSON Schema uses the
syntax for the C<relative-json-pointer> format.

This module evaluates relative pointers against a root document and a
context pointer. The context pointer must itself be a JSON Pointer string.

=head1 EXPORTS

=head2 Classes

=over

=item C<RelativeJSONPointer>

Construct with C<< new RelativeJSONPointer( path: "0/foo" ) >>. Invalid
syntax throws during construction.

Methods:

=over

=item C<expression()>

Returns the original pointer expression.

=item C<up()>

Returns the number of levels the pointer climbs from the context location.

=item C<index_change()>

Returns the array-index offset, or C<null> when none was supplied.

=item C<pointer()>

Returns the JSON Pointer suffix, or C<null> for a C<#> key request.

=item C<key_request()>

Returns true for C<#> pointers that request the key or array index at the
target location.

=item C<< target_pointer( context_pointer := "" ) >>

Returns the absolute JSON Pointer reached by climbing and applying any index
offset, before the suffix is applied.

=item C<< evaluate( root, context_pointer := "" ) >>

Evaluates the relative pointer. Normal pointers return the same array of
matches as I<std/path/jsonpointer>'s C<query>. C<#> key requests return the
key or index string directly, or C<null> when the request names the document
root.

=item C<< get( root, context_pointer := "" ) >>

Alias for C<evaluate>.

=item C<< first( root, context_pointer := "", fallback := null ) >>

Returns the first matched value, or C<fallback> when no value is found. For
C<#> key requests, C<fallback> is returned only when the key request returns
C<null>.

=item C<< exists( root, context_pointer := "" ) >>

Returns true when evaluation finds a value. For C<#> key requests, the
document root key is treated as absent.

=back

=back

=head2 Functions

=over

=item C<< valid_relative_json_pointer( text ) >>

Returns true when C<text> parses as a Relative JSON Pointer.

=back

=head1 COPYRIGHT AND LICENCE

B<< std/data/json/schema/relative_pointer >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/path/jsonpointer import JSONPointer;
from std/data/json/schema/model import jschema_pointer_join;
from std/string import replace, split, substr;

function _rjp_decode_token ( String raw ) {
	return raw
		\u25B7 replace( ^^, "~1", "/", "g" )
		\u25B7 replace( ^^, "~0", "~", "g" );
}

function _rjp_tokens ( String pointer ) {
	if ( pointer ne "" and substr( pointer, 0, 1 ) ne "/" ) {
		die "Relative JSON Pointer context path must be a JSON Pointer";
	}
	if ( pointer eq "" ) {
		return [];
	}

	let raw := split( substr( pointer, 1 ), "/" );
	let out := [];
	for ( let token in raw ) {
		out.push( _rjp_decode_token(token) );
	}
	return out;
}

function _rjp_pointer_from_tokens ( Array tokens ) {
	let out := "";
	for ( let token in tokens ) {
		out := jschema_pointer_join( out, token );
	}
	return out;
}

class RelativeJSONPointer {
	let String path;
	let Number up := 0;
	let index_change := null;
	let pointer := null;
	let Boolean key_request := false;

	method __build__ () {
		let i := 0;
		let n := length path;
		if ( n == 0 ) {
			die "Relative JSON Pointer parse error: empty pointer";
		}
		if ( not( substr( path, 0, 1 ) ~ /[0-9]/ ) ) {
			die "Relative JSON Pointer parse error: missing non-negative integer";
		}
		if ( n > 1 and substr( path, 0, 1 ) eq "0" and substr( path, 1, 1 ) ~ /[0-9]/ ) {
			die "Relative JSON Pointer parse error: leading zero";
		}
		while ( i < n and substr( path, i, 1 ) ~ /[0-9]/ ) {
			i++;
		}
		up := int( substr( path, 0, i ) );

		if ( i < n and substr( path, i, 1 ) ~ /[+-]/ ) {
			let sign := substr( path, i, 1 );
			i++;
			let start := i;
			if ( i >= n or not( substr( path, i, 1 ) ~ /[0-9]/ ) ) {
				die "Relative JSON Pointer parse error: missing index offset";
			}
			while ( i < n and substr( path, i, 1 ) ~ /[0-9]/ ) {
				i++;
			}
			let offset := int( substr( path, start, i - start ) );
			index_change := sign eq "-" ? 0 - offset : offset;
		}

		if ( i == n ) {
			pointer := "";
			return;
		}

		if ( substr( path, i, 1 ) eq "#" ) {
			if ( i + 1 \u2262 n ) {
				die "Relative JSON Pointer parse error: trailing text after '#'";
			}
			key_request := true;
			return;
		}

		let rest := substr( path, i );
		new JSONPointer( path: rest );
		pointer := rest;
	}

	method expression () { return path; }
	method pointer () { return pointer; }
	method up () { return up; }
	method index_change () { return index_change; }
	method key_request () { return key_request; }

	method target_pointer ( String context_pointer := "" ) {
		let tokens := _rjp_tokens(context_pointer);
		if ( up > tokens.length() ) {
			die "Relative JSON Pointer climbs above the document root";
		}

		let target_len := tokens.length() - up;
		let target := [];
		let i := 0;
		while ( i < target_len ) {
			target.push(tokens[i]);
			i++;
		}

		if ( index_change \u2262 null ) {
			if (
				target.length() == 0
				or not( target[target.length() - 1] ~ /^(0|[1-9][0-9]*)$/ )
			) {
				die "Relative JSON Pointer index manipulation needs an array index";
			}
			let idx := int( target[target.length() - 1] ) + index_change;
			if ( idx < 0 ) {
				die "Relative JSON Pointer index manipulation produced negative index";
			}
			target[target.length() - 1] := "" _ idx;
		}

		return _rjp_pointer_from_tokens(target);
	}

	method evaluate ( root, String context_pointer := "" ) {
		if ( key_request ) {
			let tokens := _rjp_tokens(context_pointer);
			if ( up > tokens.length() ) {
				die "Relative JSON Pointer climbs above the document root";
			}
			if ( tokens.length() == up ) {
				return null;
			}
			return tokens[ tokens.length() - up - 1 ];
		}

		let base := self.target_pointer(context_pointer);
		let full := base;
		if ( pointer \u2262 null and pointer ne "" ) {
			let suffix := pointer;
			full := base eq "" ? suffix : base _ suffix;
		}
		return new JSONPointer( path: full ).query(root);
	}

	method get ( root, String context_pointer := "" ) {
		return self.evaluate( root, context_pointer );
	}

	method first ( root, String context_pointer := "", fallback := null ) {
		if ( key_request ) {
			let key := self.evaluate( root, context_pointer );
			return key \u2261 null ? fallback : key;
		}
		let out := self.evaluate( root, context_pointer );
		return out.length() == 0 ? fallback : out[0];
	}

	method exists ( root, String context_pointer := "" ) {
		if ( key_request ) {
			return self.evaluate( root, context_pointer ) \u2262 null;
		}
		return self.evaluate( root, context_pointer ).length() > 0;
	}
}

function valid_relative_json_pointer ( String text ) {
	try {
		new RelativeJSONPointer( path: text );
		return true;
	}
	catch {
		return false;
	}
}
`;
        virtualFiles["/modules/std/data/json/schema/validation.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/data/json/schema/validation - JSON Schema 2020-12 evaluator.\n\n=head1 SYNOPSIS\n\n  from std/data/json/schema/validation import JSONSchema, validate, valid;\n\n  let schema := new JSONSchema(\n    schema: {\n      type: "array",\n      items: { type: "integer" },\n    },\n  );\n\n  say( schema.is_valid([ 1, 2, 3 ]) );\n\n  let result := validate( { minimum: 10 }, 4 );\n  say( result.errors()[0].error() );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis Pure Zuzu module is supported by all implementations of ZuzuScript.\nNetwork loading requires C<std/net/http> through\nI<std/data/json/schema/core>.\n\n=head1 DESCRIPTION\n\nThis module contains the JSON Schema 2020-12 evaluator. It is normally used\nthrough the facade module I<std/data/json/schema>, which re-exports the\npublic API and the error classes.\n\nThe evaluator supports boolean schemas, object schemas, references,\napplicators, object and array validation, numeric and string constraints,\ndependent keywords, content keywords, and format validation. It validates\ndecoded Zuzu values and uses I<std/data/json/schema/model> to project native\nC<PairList>, C<Set>, and C<Bag> values into the JSON data model where that\nis meaningful.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<JSONSchema>\n\nCompiled schema wrapper. Construct with C<< new JSONSchema( schema: ... ) >>.\nPass C<options> as a named field when configuration is needed.\n\n=over\n\n=item C<< is_valid( instance ) >>\n\nReturns C<true> or C<false>. This mode stops after the first failure.\n\n=item C<< validate( instance ) >>\n\nReturns a C<ValidationResult> and collects independent failures as\nC<ValidationError> objects.\n\n=back\n\n=back\n\n=head2 Functions\n\n=over\n\n=item C<< valid( schema, instance, options := {} ) >>\n\nConstructs a temporary C<JSONSchema> and returns\nC<< is_valid(instance) >>.\n\n=item C<< validate( schema, instance, options := {} ) >>\n\nConstructs a temporary C<JSONSchema> and returns\nC<< validate(instance) >>.\n\n=back\n\n=head1 OPTIONS\n\nC<options> may be a C<Dict> or C<PairList>.\n\n=over\n\n=item C<base_uri>\n\nBase URI for the root schema.\n\n=item C<registry>\n\nC<SchemaRegistry> used for references. If omitted, a new registry is\ncreated and the root schema is registered in it.\n\n=item C<loader>\n\nCallable or object with C<load(uri)> used to load missing referenced\nresources. A string result is decoded as JSON.\n\n=item C<allow_network>\n\nWhen true and C<loader> is not supplied, uses C<HTTPResourceLoader>.\n\n=item C<formats> or C<format_registry>\n\nC<FormatRegistry> used for C<format> checks.\n\n=item C<format_assert>\n\nBoolean. Defaults to false. When false, C<format> never makes validation\nfail.\n\n=item C<unknown_format>\n\nDefaults to C<ignore>. Use C<fail> to report unknown asserted formats.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/data/json/schema/validation >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/internals import to_Regexp_with_flags;\nfrom std/string import join, substr;\nfrom std/data/json/schema/core import\n	HTTPResourceLoader,\n	SchemaRegistry,\n	jschema_uri_resolve,\n	jschema_url_split;\nfrom std/data/json/schema/format import FormatRegistry;\nfrom std/data/json/schema/model import\n	jschema_array_items,\n	jschema_array_length,\n	jschema_deep_equal,\n	jschema_is_arrayish,\n	jschema_is_object,\n	jschema_is_ordered_array,\n	jschema_is_unordered_array,\n	jschema_object_entries,\n	jschema_object_get,\n	jschema_object_get_all,\n	jschema_object_has,\n	jschema_object_keys,\n	jschema_object_unique_keys,\n	jschema_pointer_join,\n	jschema_type_matches,\n	jschema_type_name;\nfrom std/data/json/schema/output import\n	AdditionalItemsError,\n	AdditionalPropertiesError,\n	AllOfError,\n	AnyOfError,\n	ConstMismatchError,\n	ContentEncodingError,\n	ContentMediaTypeError,\n	DependentRequiredPropertyError,\n	EnumMismatchError,\n	ExclusiveMaximumError,\n	ExclusiveMinimumError,\n	FalseSchemaError,\n	FormatError,\n	IfThenElseError,\n	MaxContainsError,\n	MaximumError,\n	MaxItemsError,\n	MaxLengthError,\n	MaxPropertiesError,\n	MinContainsError,\n	MinimumError,\n	MinItemsError,\n	MinLengthError,\n	MinPropertiesError,\n	MultipleOfError,\n	NotMatchedError,\n	OneOfError,\n	PatternError,\n	PropertyNamesError,\n	ReferenceResolutionError,\n	RequiredPropertyError,\n	SubschemaError,\n	TypeMismatchError,\n	UnevaluatedItemsError,\n	UnevaluatedPropertiesError,\n	UnexpectedValueError,\n	UniqueItemsError,\n	UnknownFormatError,\n	ValidationResult;\n\nfunction _jschema_opt ( options, String key, fallback := null ) {\n	if ( options \u2261 null ) {\n		return fallback;\n	}\n	if ( options instanceof Dict ) {\n		return options.exists(key) ? options.get(key) : fallback;\n	}\n	if ( options instanceof PairList ) {\n		return options.has(key) ? options.get(key) : fallback;\n	}\n	return fallback;\n}\n\nfunction _jschema_add_unique ( Array out, value ) {\n	if ( not( value in out ) ) {\n		out.push(value);\n	}\n	return out;\n}\n\nfunction _jschema_validation_vocab_enabled ( schema, registry, String base_uri ) {\n	if (\n		not jschema_is_object(schema)\n		or not jschema_object_has( schema, "$schema" )\n		or not( jschema_object_get( schema, "$schema" ) instanceof String )\n	) {\n		return true;\n	}\n\n	let metaschema;\n	try {\n		metaschema := registry.resolve(\n			jschema_object_get( schema, "$schema" ),\n			base_uri,\n		);\n	}\n	catch {\n		return true;\n	}\n\n	if (\n		jschema_is_object(metaschema)\n		and jschema_object_has( metaschema, "$vocabulary" )\n		and jschema_is_object( jschema_object_get( metaschema, "$vocabulary" ) )\n	) {\n		let vocabulary := jschema_object_get( metaschema, "$vocabulary" );\n		let validation_uri := "https://json-schema.org/draft/2020-12/vocab/validation";\n		if (\n			jschema_object_has( vocabulary, validation_uri )\n			and jschema_object_get( vocabulary, validation_uri ) instanceof Boolean\n		) {\n			return jschema_object_get( vocabulary, validation_uri );\n		}\n		return false;\n	}\n\n	return true;\n}\n\nfunction _jschema_format_assertion_vocab_enabled ( schema, registry, String base_uri, Boolean fallback ) {\n	if (\n		not jschema_is_object(schema)\n		or not jschema_object_has( schema, "$schema" )\n		or not( jschema_object_get( schema, "$schema" ) instanceof String )\n	) {\n		return fallback;\n	}\n\n	let metaschema;\n	try {\n		metaschema := registry.resolve(\n			jschema_object_get( schema, "$schema" ),\n			base_uri,\n		);\n	}\n	catch {\n		return fallback;\n	}\n\n	if (\n		jschema_is_object(metaschema)\n		and jschema_object_has( metaschema, "$vocabulary" )\n		and jschema_is_object( jschema_object_get( metaschema, "$vocabulary" ) )\n	) {\n		let vocabulary := jschema_object_get( metaschema, "$vocabulary" );\n		let format_assertion_uri := "https://json-schema.org/draft/2020-12/vocab/format-assertion";\n		if ( jschema_object_has( vocabulary, format_assertion_uri ) ) {\n			return true;\n		}\n	}\n\n	return fallback;\n}\n\nclass _EvalResult {\n	let Boolean valid := true;\n	let Array errors := [];\n	let Array evaluatedProperties := [];\n	let Array evaluatedItems := [];\n\n	method add_error ( error ) {\n		valid := false;\n		if ( error \u2262 null ) {\n			errors.push(error);\n		}\n		return error;\n	}\n\n	method merge ( other ) {\n		if ( not other.valid() ) {\n			valid := false;\n		}\n		for ( let error in other.errors() ) {\n			errors.push(error);\n		}\n		for ( let prop in other.evaluatedProperties() ) {\n			_jschema_add_unique( evaluatedProperties, prop );\n		}\n		for ( let item in other.evaluatedItems() ) {\n			_jschema_add_unique( evaluatedItems, item );\n		}\n		return self;\n	}\n\n	method mark_property ( prop ) {\n		_jschema_add_unique( evaluatedProperties, prop );\n	}\n\n	method mark_item ( item ) {\n		_jschema_add_unique( evaluatedItems, item );\n	}\n\n	method valid () { return valid; }\n	method errors () { return errors; }\n	method evaluatedProperties () { return evaluatedProperties; }\n	method evaluatedItems () { return evaluatedItems; }\n}\n\nfunction _jschema_regexp ( String pattern ) {\n	return to_Regexp_with_flags(pattern, "u");\n}\n\nclass _SchemaEvaluator {\n	let registry;\n	let formats;\n	let Boolean collect := true;\n	let Boolean format_assert := false;\n	let String unknown_format := "ignore";\n	let Boolean validation_enabled := true;\n	let Array dynamic_scope := [];\n\n	method error (\n		Klass,\n		String keyword_location,\n		String instance_location,\n		String message,\n		keyword := null,\n		details := null,\n	) {\n		if ( not collect ) {\n			return null;\n		}\n		return new Klass(\n			keywordLocation: keyword_location,\n			instanceLocation: instance_location,\n			error: message,\n			keyword: keyword,\n			details: details,\n		);\n	}\n\n	method _subschema_error (\n		String keyword_location,\n		String instance_location,\n		Array child_errors,\n		keyword := null,\n	) {\n		if ( not collect ) {\n			return null;\n		}\n		return new SubschemaError(\n			keywordLocation: keyword_location,\n			instanceLocation: instance_location,\n			error: "A subschema had errors.",\n			keyword: keyword,\n		).add_suberrors(child_errors);\n	}\n\n	method _invalid (\n		_EvalResult result,\n		Klass,\n		String keyword_location,\n		String instance_location,\n		String message,\n		keyword := null,\n		details := null,\n	) {\n		result.add_error(\n			self.error(\n				Klass,\n				keyword_location,\n				instance_location,\n				message,\n				keyword,\n				details,\n			),\n		);\n		return result;\n	}\n\n	method _child (\n		schema,\n		instance,\n		String keyword_location,\n		String instance_location,\n		String base_uri,\n	) {\n		return self.evaluate(\n			schema,\n			instance,\n			keyword_location,\n			instance_location,\n			base_uri,\n		);\n	}\n\n	method _finish ( _EvalResult result, Boolean pushed_scope ) {\n		if ( pushed_scope ) {\n			dynamic_scope.pop();\n		}\n		return result;\n	}\n\n	method _dynamic_target ( ref_info ) {\n		let fragment := ref_info{fragment};\n		if (\n			fragment \u2261 null\n			or fragment eq ""\n			or substr( fragment, 0, 1 ) eq "/"\n			or not registry.has_dynamic_anchor( ref_info{resource_uri}, fragment )\n		) {\n			return ref_info{target};\n		}\n\n		for ( let resource_uri in dynamic_scope ) {\n			let target := registry.dynamic_anchor( resource_uri, fragment );\n			if ( target \u2262 null ) {\n				return target;\n			}\n		}\n\n		return ref_info{target};\n	}\n\n	method evaluate (\n		schema,\n		instance,\n		String keyword_location := "",\n		String instance_location := "",\n		String base_uri := "",\n	) {\n		let result := new _EvalResult();\n		let current_base_uri := base_uri;\n\n		if ( schema instanceof Boolean ) {\n			if ( schema ) {\n				return result;\n			}\n			return self._invalid(\n				result,\n				FalseSchemaError,\n				keyword_location,\n				instance_location,\n				"Boolean false schema does not allow any value.",\n				"false",\n			);\n		}\n\n		if ( not jschema_is_object(schema) ) {\n			return result;\n		}\n\n		let registered_base := registry.schema_base(schema, null);\n		if ( registered_base \u2262 null ) {\n			current_base_uri := registered_base;\n		}\n		else if (\n			jschema_object_has( schema, "$id" )\n			and jschema_object_get( schema, "$id" ) instanceof String\n		) {\n			current_base_uri := jschema_uri_resolve(\n				current_base_uri,\n				jschema_object_get( schema, "$id" ),\n			);\n		}\n\n		let scope_resource := jschema_url_split(current_base_uri){baseurl};\n		dynamic_scope.push(scope_resource);\n		let pushed_scope := true;\n\n		if ( jschema_object_has( schema, "$ref" ) ) {\n			let ref := jschema_object_get( schema, "$ref" );\n			if ( ref instanceof String ) {\n				try {\n					let ref_info := registry.resolve_info( ref, current_base_uri );\n					let child := self._child(\n						ref_info{target},\n						instance,\n						jschema_pointer_join( keyword_location, "$ref" ),\n						instance_location,\n						ref_info{resource_uri},\n					);\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self._subschema_error(\n							jschema_pointer_join( keyword_location, "$ref" ),\n							instance_location,\n							child.errors(),\n							"$ref",\n						) );\n						if ( not collect ) { return self._finish( result, pushed_scope ); }\n					}\n				}\n				catch ( Exception e ) {\n					self._invalid(\n						result,\n						ReferenceResolutionError,\n						jschema_pointer_join( keyword_location, "$ref" ),\n						instance_location,\n						e{message},\n						"$ref",\n					);\n					if ( not collect ) { return self._finish( result, pushed_scope ); }\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "$dynamicRef" ) ) {\n			let ref := jschema_object_get( schema, "$dynamicRef" );\n			if ( ref instanceof String ) {\n				try {\n					let ref_info := registry.resolve_info( ref, current_base_uri );\n					let child := self._child(\n						self._dynamic_target(ref_info),\n						instance,\n						jschema_pointer_join( keyword_location, "$dynamicRef" ),\n						instance_location,\n						ref_info{resource_uri},\n					);\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self._subschema_error(\n							jschema_pointer_join( keyword_location, "$dynamicRef" ),\n							instance_location,\n							child.errors(),\n							"$dynamicRef",\n						) );\n						if ( not collect ) { return self._finish( result, pushed_scope ); }\n					}\n				}\n				catch ( Exception e ) {\n					self._invalid(\n						result,\n						ReferenceResolutionError,\n						jschema_pointer_join( keyword_location, "$dynamicRef" ),\n						instance_location,\n						e{message},\n						"$dynamicRef",\n					);\n					if ( not collect ) { return self._finish( result, pushed_scope ); }\n				}\n			}\n		}\n\n		self._validate_type( result, schema, instance, keyword_location, instance_location );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_enum_const( result, schema, instance, keyword_location, instance_location );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_numeric( result, schema, instance, keyword_location, instance_location );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_string( result, schema, instance, keyword_location, instance_location );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_array( result, schema, instance, keyword_location, instance_location, current_base_uri );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_object( result, schema, instance, keyword_location, instance_location, current_base_uri );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_applicators( result, schema, instance, keyword_location, instance_location, current_base_uri );\n		if ( not result.valid() and not collect ) { return self._finish( result, pushed_scope ); }\n		self._validate_unevaluated( result, schema, instance, keyword_location, instance_location, current_base_uri );\n		return self._finish( result, pushed_scope );\n	}\n\n	method _validate_type ( result, schema, instance, kwloc, instloc ) {\n		if ( not validation_enabled ) {\n			return;\n		}\n		if ( not jschema_object_has( schema, "type" ) ) {\n			return;\n		}\n		let spec := jschema_object_get( schema, "type" );\n		let ok := false;\n		let expected := [];\n		if ( spec instanceof String ) {\n			expected := [ spec ];\n		}\n		else if ( spec instanceof Array ) {\n			expected := spec;\n		}\n		for ( let t in expected ) {\n			if ( t instanceof String and jschema_type_matches( instance, t ) ) {\n				ok := true;\n			}\n		}\n		if ( ok ) {\n			return;\n		}\n		self._invalid(\n			result,\n			TypeMismatchError,\n			jschema_pointer_join( kwloc, "type" ),\n			instloc,\n			`Expected ${join( "|", expected )}, got ${jschema_type_name(instance)}.`,\n			"type",\n		);\n	}\n\n	method _validate_enum_const ( result, schema, instance, kwloc, instloc ) {\n		if ( not validation_enabled ) {\n			return;\n		}\n		if ( jschema_object_has( schema, "const" ) ) {\n			if ( jschema_deep_equal(\n				instance,\n				jschema_object_get( schema, "const" ),\n			) ) {\n				return;\n			}\n			self._invalid(\n				result,\n				ConstMismatchError,\n				jschema_pointer_join( kwloc, "const" ),\n				instloc,\n				"Value does not match const.",\n				"const",\n			);\n			if ( not collect ) {\n				return;\n			}\n		}\n\n		if ( jschema_object_has( schema, "enum" ) ) {\n			let allowed := jschema_object_get( schema, "enum" );\n				if ( allowed instanceof Array ) {\n					for ( let option in allowed ) {\n						if ( jschema_deep_equal( instance, option ) ) {\n							return;\n						}\n					}\n				}\n			self._invalid(\n				result,\n				EnumMismatchError,\n				jschema_pointer_join( kwloc, "enum" ),\n				instloc,\n				"Value is not one of the allowed enum values.",\n				"enum",\n			);\n		}\n	}\n\n	method _validate_numeric ( result, schema, instance, kwloc, instloc ) {\n		if ( not validation_enabled ) {\n			return;\n		}\n		if ( not( instance instanceof Number ) ) {\n			return;\n		}\n		if ( jschema_object_has( schema, "multipleOf" ) ) {\n			let n := jschema_object_get( schema, "multipleOf" );\n			let quotient := n instanceof Number and n != 0\n				? instance / n\n				: 0;\n			if (\n				n instanceof Number\n				and n != 0\n				and (\n					quotient > 10 ** 300\n					or quotient < -( 10 ** 300 )\n					or quotient != floor(quotient)\n				)\n			) {\n				self._invalid(\n					result,\n					MultipleOfError,\n					jschema_pointer_join( kwloc, "multipleOf" ),\n					instloc,\n					`Number is not a multiple of ${n}.`,\n					"multipleOf",\n				);\n				if ( not collect ) {\n					return;\n				}\n			}\n		}\n		if (\n			jschema_object_has( schema, "minimum" )\n			and instance < jschema_object_get( schema, "minimum" )\n		) {\n			self._invalid( result, MinimumError, jschema_pointer_join( kwloc, "minimum" ), instloc, "Number is below minimum.", "minimum" );\n			if ( not collect ) {\n				return;\n			}\n		}\n		if (\n			jschema_object_has( schema, "maximum" )\n			and instance > jschema_object_get( schema, "maximum" )\n		) {\n			self._invalid( result, MaximumError, jschema_pointer_join( kwloc, "maximum" ), instloc, "Number is above maximum.", "maximum" );\n			if ( not collect ) {\n				return;\n			}\n		}\n		if (\n			jschema_object_has( schema, "exclusiveMinimum" )\n			and instance <= jschema_object_get( schema, "exclusiveMinimum" )\n		) {\n			self._invalid( result, ExclusiveMinimumError, jschema_pointer_join( kwloc, "exclusiveMinimum" ), instloc, "Number is not above exclusiveMinimum.", "exclusiveMinimum" );\n			if ( not collect ) {\n				return;\n			}\n		}\n		if (\n			jschema_object_has( schema, "exclusiveMaximum" )\n			and instance >= jschema_object_get( schema, "exclusiveMaximum" )\n		) {\n			self._invalid( result, ExclusiveMaximumError, jschema_pointer_join( kwloc, "exclusiveMaximum" ), instloc, "Number is not below exclusiveMaximum.", "exclusiveMaximum" );\n		}\n	}\n\n	method _validate_string ( result, schema, instance, kwloc, instloc ) {\n		if ( not( instance instanceof String or instance instanceof BinaryString ) ) {\n			return;\n		}\n		let text := "" _ instance;\n		if ( validation_enabled ) {\n			if (\n				jschema_object_has( schema, "minLength" )\n				and length text < jschema_object_get( schema, "minLength" )\n			) {\n				self._invalid( result, MinLengthError, jschema_pointer_join( kwloc, "minLength" ), instloc, "String is shorter than minLength.", "minLength" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if (\n				jschema_object_has( schema, "maxLength" )\n				and length text > jschema_object_get( schema, "maxLength" )\n			) {\n				self._invalid( result, MaxLengthError, jschema_pointer_join( kwloc, "maxLength" ), instloc, "String is longer than maxLength.", "maxLength" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if ( jschema_object_has( schema, "pattern" ) ) {\n				let pattern := jschema_object_get( schema, "pattern" );\n				if ( pattern instanceof String and not( text ~ _jschema_regexp(pattern) ) ) {\n					self._invalid( result, PatternError, jschema_pointer_join( kwloc, "pattern" ), instloc, "String does not match pattern.", "pattern" );\n					if ( not collect ) {\n						return;\n					}\n				}\n			}\n		}\n		if ( format_assert and jschema_object_has( schema, "format" ) ) {\n			let fmt := jschema_object_get( schema, "format" );\n			if ( fmt instanceof String ) {\n				if ( not formats.has(fmt) ) {\n					if ( unknown_format eq "ignore" ) {\n						return;\n					}\n					self._invalid(\n						result,\n						UnknownFormatError,\n						jschema_pointer_join( kwloc, "format" ),\n						instloc,\n						`Unknown format \'${fmt}\'.`,\n						"format",\n					);\n					if ( not collect ) {\n						return;\n					}\n				}\n				else if ( not formats.check( fmt, text ) ) {\n					self._invalid(\n						result,\n						FormatError,\n						jschema_pointer_join( kwloc, "format" ),\n						instloc,\n						`String does not match format \'${fmt}\'.`,\n						"format",\n					);\n				}\n			}\n		}\n		if ( validation_enabled ) {\n			if ( jschema_object_has( schema, "contentEncoding" ) ) {\n				/* Validation of decoded content is intentionally conservative. */\n			}\n			if ( jschema_object_has( schema, "contentMediaType" ) ) {\n				/* The media type keyword is annotation unless content is decoded. */\n			}\n		}\n	}\n\n	method _validate_array ( result, schema, instance, kwloc, instloc, base_uri ) {\n		if ( not jschema_is_arrayish(instance) ) {\n			return;\n		}\n		let items := jschema_array_items(instance);\n		let len := jschema_array_length(instance);\n		if ( validation_enabled ) {\n			if (\n				jschema_object_has( schema, "minItems" )\n				and len < jschema_object_get( schema, "minItems" )\n			) {\n				self._invalid( result, MinItemsError, jschema_pointer_join( kwloc, "minItems" ), instloc, "Array has too few items.", "minItems" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if (\n				jschema_object_has( schema, "maxItems" )\n				and len > jschema_object_get( schema, "maxItems" )\n			) {\n				self._invalid( result, MaxItemsError, jschema_pointer_join( kwloc, "maxItems" ), instloc, "Array has too many items.", "maxItems" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if ( jschema_object_get( schema, "uniqueItems", false ) ) {\n				let i := 0;\n				while ( i < items.length() ) {\n					let j := i + 1;\n					while ( j < items.length() ) {\n						if ( jschema_deep_equal( items[i], items[j] ) ) {\n							self._invalid( result, UniqueItemsError, jschema_pointer_join( kwloc, "uniqueItems" ), instloc, "Array items are not unique.", "uniqueItems" );\n							if ( not collect ) {\n								return;\n							}\n						}\n						j++;\n					}\n					i++;\n				}\n			}\n		}\n\n		if ( jschema_is_unordered_array(instance) and jschema_object_has( schema, "prefixItems" ) ) {\n			self._invalid(\n				result,\n				AdditionalItemsError,\n				jschema_pointer_join( kwloc, "prefixItems" ),\n				instloc,\n				"prefixItems cannot be applied to an unordered collection.",\n				"prefixItems",\n			);\n			if ( not collect ) {\n				return;\n			}\n		}\n\n		let evaluated := [];\n		if ( jschema_object_has( schema, "prefixItems" ) and jschema_is_ordered_array(instance) ) {\n			let prefix := jschema_object_get( schema, "prefixItems" );\n			if ( prefix instanceof Array ) {\n				let i := 0;\n				while ( i < prefix.length() and i < items.length() ) {\n					let child := self._child(\n						prefix[i],\n						items[i],\n						jschema_pointer_join( jschema_pointer_join( kwloc, "prefixItems" ), i ),\n						jschema_pointer_join( instloc, i ),\n						base_uri,\n					);\n					evaluated.push(i);\n					result.mark_item( jschema_pointer_join( instloc, i ) );\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self._subschema_error(\n							jschema_pointer_join( jschema_pointer_join( kwloc, "prefixItems" ), i ),\n							jschema_pointer_join( instloc, i ),\n							child.errors(),\n							"prefixItems",\n						) );\n						if ( not collect ) {\n							return result;\n						}\n					}\n					i++;\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "items" ) ) {\n			let subschema := jschema_object_get( schema, "items" );\n			let start := 0;\n			if (\n				jschema_object_has( schema, "prefixItems" )\n				and jschema_object_get( schema, "prefixItems" ) instanceof Array\n			) {\n				start := jschema_object_get( schema, "prefixItems" ).length();\n			}\n			let i := 0;\n			while ( i < items.length() ) {\n				if ( not jschema_is_ordered_array(instance) or i >= start ) {\n					let child := self._child(\n						subschema,\n						items[i],\n						jschema_pointer_join( kwloc, "items" ),\n						jschema_pointer_join( instloc, i ),\n						base_uri,\n					);\n					result.mark_item( jschema_pointer_join( instloc, i ) );\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self._subschema_error(\n							jschema_pointer_join( kwloc, "items" ),\n							jschema_pointer_join( instloc, i ),\n							child.errors(),\n							"items",\n						) );\n						if ( not collect ) {\n							return result;\n						}\n					}\n				}\n				i++;\n			}\n		}\n\n		if ( jschema_object_has( schema, "contains" ) ) {\n			let matches := 0;\n			let i := 0;\n			while ( i < items.length() ) {\n				let child := self._child(\n					jschema_object_get( schema, "contains" ),\n					items[i],\n					jschema_pointer_join( kwloc, "contains" ),\n					jschema_pointer_join( instloc, i ),\n					base_uri,\n				);\n				if ( child.valid() ) {\n					matches++;\n					result.mark_item( jschema_pointer_join( instloc, i ) );\n					result.merge(child);\n				}\n				i++;\n			}\n			let min := jschema_object_get( schema, "minContains", 1 );\n			let max := jschema_object_get( schema, "maxContains", null );\n			if ( validation_enabled and matches < min ) {\n				self._invalid( result, MinContainsError, jschema_pointer_join( kwloc, "minContains" ), instloc, "Array contains too few matching items.", "minContains" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if ( validation_enabled and max \u2262 null and matches > max ) {\n				self._invalid( result, MaxContainsError, jschema_pointer_join( kwloc, "maxContains" ), instloc, "Array contains too many matching items.", "maxContains" );\n				if ( not collect ) {\n					return;\n				}\n			}\n		}\n\n	}\n\n	method _validate_object ( result, schema, instance, kwloc, instloc, base_uri ) {\n		if ( not jschema_is_object(instance) ) {\n			return;\n		}\n		let keys := jschema_object_keys(instance);\n		let unique_keys := jschema_object_unique_keys(instance);\n		if ( validation_enabled ) {\n			if (\n				jschema_object_has( schema, "minProperties" )\n				and keys.length() < jschema_object_get( schema, "minProperties" )\n			) {\n				self._invalid( result, MinPropertiesError, jschema_pointer_join( kwloc, "minProperties" ), instloc, "Object has too few properties.", "minProperties" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if (\n				jschema_object_has( schema, "maxProperties" )\n				and keys.length() > jschema_object_get( schema, "maxProperties" )\n			) {\n				self._invalid( result, MaxPropertiesError, jschema_pointer_join( kwloc, "maxProperties" ), instloc, "Object has too many properties.", "maxProperties" );\n				if ( not collect ) {\n					return;\n				}\n			}\n			if ( jschema_object_has( schema, "required" ) ) {\n				for ( let key in jschema_object_get( schema, "required" ) ) {\n					if ( not jschema_object_has( instance, key ) ) {\n						self._invalid(\n							result,\n							RequiredPropertyError,\n							jschema_pointer_join( kwloc, "required" ),\n							instloc,\n							`Required property \'${key}\' is missing.`,\n							"required",\n						);\n						if ( not collect ) {\n							return;\n						}\n					}\n				}\n			}\n			if ( jschema_object_has( schema, "dependentRequired" ) ) {\n				let deps := jschema_object_get( schema, "dependentRequired" );\n				if ( jschema_is_object(deps) ) {\n					for ( let entry in jschema_object_entries(deps) ) {\n						if ( jschema_object_has( instance, entry[0] ) ) {\n							for ( let dep in entry[1] ) {\n								if ( not jschema_object_has( instance, dep ) ) {\n									self._invalid(\n										result,\n										DependentRequiredPropertyError,\n										jschema_pointer_join( kwloc, "dependentRequired" ),\n										instloc,\n										`Dependent property \'${dep}\' is missing.`,\n										"dependentRequired",\n									);\n									if ( not collect ) {\n										return;\n									}\n								}\n							}\n						}\n					}\n				}\n			}\n			if ( jschema_object_has( schema, "dependencies" ) ) {\n				let deps := jschema_object_get( schema, "dependencies" );\n				if ( jschema_is_object(deps) ) {\n					for ( let entry in jschema_object_entries(deps) ) {\n						if ( jschema_object_has( instance, entry[0] ) ) {\n							if ( entry[1] instanceof Array ) {\n								for ( let dep in entry[1] ) {\n									if ( not jschema_object_has( instance, dep ) ) {\n										self._invalid(\n											result,\n											DependentRequiredPropertyError,\n											jschema_pointer_join( kwloc, "dependencies" ),\n											instloc,\n											`Dependent property \'${dep}\' is missing.`,\n											"dependencies",\n										);\n										if ( not collect ) {\n											return;\n										}\n									}\n								}\n							}\n							else {\n								let child := self._child(\n									entry[1],\n									instance,\n									jschema_pointer_join(\n										jschema_pointer_join( kwloc, "dependencies" ),\n										entry[0],\n									),\n									instloc,\n									base_uri,\n								);\n								result.merge(child);\n								if ( not child.valid() ) {\n									result.add_error( self._subschema_error(\n										jschema_pointer_join(\n											jschema_pointer_join( kwloc, "dependencies" ),\n											entry[0],\n										),\n										instloc,\n										child.errors(),\n										"dependencies",\n									) );\n									if ( not collect ) { return result; }\n								}\n							}\n						}\n					}\n				}\n			}\n		}\n\n		let matched_properties := [];\n		if ( jschema_object_has( schema, "properties" ) ) {\n			let props := jschema_object_get( schema, "properties" );\n			if ( jschema_is_object(props) ) {\n				for ( let entry in jschema_object_entries(props) ) {\n					let key := entry[0];\n					if ( jschema_object_has( instance, key ) ) {\n						let ix := 0;\n						for ( let value in jschema_object_get_all( instance, key ) ) {\n							let child := self._child(\n								entry[1],\n								value,\n								jschema_pointer_join( jschema_pointer_join( kwloc, "properties" ), key ),\n								jschema_pointer_join( instloc, key ),\n								base_uri,\n							);\n							_jschema_add_unique( matched_properties, key );\n							result.mark_property( jschema_pointer_join( instloc, key ) );\n							result.merge(child);\n							if ( not child.valid() ) {\n								result.add_error( self._subschema_error(\n									jschema_pointer_join( jschema_pointer_join( kwloc, "properties" ), key ),\n									jschema_pointer_join( instloc, key ),\n									child.errors(),\n									"properties",\n								) );\n								if ( not collect ) { return result; }\n							}\n							ix++;\n						}\n					}\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "patternProperties" ) ) {\n			let patterns := jschema_object_get( schema, "patternProperties" );\n			if ( jschema_is_object(patterns) ) {\n				for ( let pentry in jschema_object_entries(patterns) ) {\n					let pattern := pentry[0];\n					for ( let entry in jschema_object_entries(instance) ) {\n						let key := entry[0];\n						if ( key ~ _jschema_regexp(pattern) ) {\n							let child := self._child(\n								pentry[1],\n								entry[1],\n								jschema_pointer_join( jschema_pointer_join( kwloc, "patternProperties" ), pattern ),\n								jschema_pointer_join( instloc, key ),\n								base_uri,\n							);\n							_jschema_add_unique( matched_properties, key );\n							result.mark_property( jschema_pointer_join( instloc, key ) );\n							result.merge(child);\n							if ( not child.valid() ) {\n								result.add_error( self._subschema_error(\n									jschema_pointer_join( jschema_pointer_join( kwloc, "patternProperties" ), pattern ),\n									jschema_pointer_join( instloc, key ),\n									child.errors(),\n									"patternProperties",\n								) );\n								if ( not collect ) { return result; }\n							}\n						}\n					}\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "additionalProperties" ) ) {\n			for ( let entry in jschema_object_entries(instance) ) {\n				let key := entry[0];\n				if ( not( key in matched_properties ) ) {\n					let child := self._child(\n						jschema_object_get( schema, "additionalProperties" ),\n						entry[1],\n						jschema_pointer_join( kwloc, "additionalProperties" ),\n						jschema_pointer_join( instloc, key ),\n						base_uri,\n					);\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self.error(\n							AdditionalPropertiesError,\n							jschema_pointer_join( kwloc, "additionalProperties" ),\n							jschema_pointer_join( instloc, key ),\n							"Additional property is not allowed.",\n							"additionalProperties",\n						) );\n						if ( not collect ) { return result; }\n					}\n					result.mark_property( jschema_pointer_join( instloc, key ) );\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "propertyNames" ) ) {\n			for ( let key in unique_keys ) {\n				let child := self._child(\n					jschema_object_get( schema, "propertyNames" ),\n					key,\n					jschema_pointer_join( kwloc, "propertyNames" ),\n					jschema_pointer_join( instloc, key ),\n					base_uri,\n				);\n				result.merge(child);\n				if ( not child.valid() ) {\n					result.add_error( self.error(\n						PropertyNamesError,\n						jschema_pointer_join( kwloc, "propertyNames" ),\n						jschema_pointer_join( instloc, key ),\n						"Property name does not match schema.",\n						"propertyNames",\n					) );\n					if ( not collect ) { return result; }\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "dependentSchemas" ) ) {\n			let deps := jschema_object_get( schema, "dependentSchemas" );\n			if ( jschema_is_object(deps) ) {\n				for ( let entry in jschema_object_entries(deps) ) {\n					if ( jschema_object_has( instance, entry[0] ) ) {\n						let child := self._child(\n							entry[1],\n							instance,\n							jschema_pointer_join( jschema_pointer_join( kwloc, "dependentSchemas" ), entry[0] ),\n							instloc,\n							base_uri,\n						);\n						result.merge(child);\n						if ( not child.valid() ) {\n							result.add_error( self._subschema_error(\n								jschema_pointer_join( jschema_pointer_join( kwloc, "dependentSchemas" ), entry[0] ),\n								instloc,\n								child.errors(),\n								"dependentSchemas",\n							) );\n							if ( not collect ) { return result; }\n						}\n					}\n				}\n			}\n		}\n\n	}\n\n	method _validate_unevaluated ( result, schema, instance, kwloc, instloc, base_uri ) {\n		if (\n			jschema_is_arrayish(instance)\n			and jschema_object_has( schema, "unevaluatedItems" )\n		) {\n			let items := jschema_array_items(instance);\n			let i := 0;\n			while ( i < items.length() ) {\n				if (\n					not( jschema_pointer_join( instloc, i )\n						in result.evaluatedItems() )\n				) {\n					let child := self._child(\n						jschema_object_get( schema, "unevaluatedItems" ),\n						items[i],\n						jschema_pointer_join( kwloc, "unevaluatedItems" ),\n						jschema_pointer_join( instloc, i ),\n						base_uri,\n					);\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self.error(\n							UnevaluatedItemsError,\n							jschema_pointer_join( kwloc, "unevaluatedItems" ),\n							jschema_pointer_join( instloc, i ),\n							"Unevaluated array item is not allowed.",\n							"unevaluatedItems",\n						) );\n						if ( not collect ) { return result; }\n					}\n					result.mark_item( jschema_pointer_join( instloc, i ) );\n				}\n				i++;\n			}\n		}\n\n		if (\n			jschema_is_object(instance)\n			and jschema_object_has( schema, "unevaluatedProperties" )\n		) {\n			for ( let entry in jschema_object_entries(instance) ) {\n				let key := entry[0];\n				if (\n					not( jschema_pointer_join( instloc, key )\n						in result.evaluatedProperties() )\n				) {\n					let child := self._child(\n						jschema_object_get( schema, "unevaluatedProperties" ),\n						entry[1],\n						jschema_pointer_join( kwloc, "unevaluatedProperties" ),\n						jschema_pointer_join( instloc, key ),\n						base_uri,\n					);\n					result.merge(child);\n					if ( not child.valid() ) {\n						result.add_error( self.error(\n							UnevaluatedPropertiesError,\n							jschema_pointer_join( kwloc, "unevaluatedProperties" ),\n							jschema_pointer_join( instloc, key ),\n							"Unevaluated property is not allowed.",\n							"unevaluatedProperties",\n						) );\n						if ( not collect ) { return result; }\n					}\n					result.mark_property( jschema_pointer_join( instloc, key ) );\n				}\n			}\n		}\n	}\n\n	method _validate_applicators ( result, schema, instance, kwloc, instloc, base_uri ) {\n		if ( jschema_object_has( schema, "allOf" ) ) {\n			let arr := jschema_object_get( schema, "allOf" );\n			if ( arr instanceof Array ) {\n				let i := 0;\n				while ( i < arr.length() ) {\n					let child := self._child( arr[i], instance, jschema_pointer_join( jschema_pointer_join( kwloc, "allOf" ), i ), instloc, base_uri );\n					if ( child.valid() ) {\n						result.merge(child);\n					}\n					else {\n						result.merge(child);\n						result.add_error( self.error( AllOfError, jschema_pointer_join( jschema_pointer_join( kwloc, "allOf" ), i ), instloc, "allOf subschema failed.", "allOf" ) );\n						if ( not collect ) { return result; }\n					}\n					i++;\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "anyOf" ) ) {\n			let arr := jschema_object_get( schema, "anyOf" );\n			if ( arr instanceof Array ) {\n				let ok := false;\n				let child_errors := [];\n				let i := 0;\n				while ( i < arr.length() ) {\n					let child := self._child( arr[i], instance, jschema_pointer_join( jschema_pointer_join( kwloc, "anyOf" ), i ), instloc, base_uri );\n					if ( child.valid() ) {\n						ok := true;\n						result.merge(child);\n					}\n					else {\n						for ( let e in child.errors() ) { child_errors.push(e); }\n					}\n					i++;\n				}\n				if ( not ok ) {\n					result.add_error( self.error( AnyOfError, jschema_pointer_join( kwloc, "anyOf" ), instloc, "No anyOf subschema matched.", "anyOf" ) );\n					result.add_error( self._subschema_error( jschema_pointer_join( kwloc, "anyOf" ), instloc, child_errors, "anyOf" ) );\n					if ( not collect ) { return result; }\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "oneOf" ) ) {\n			let arr := jschema_object_get( schema, "oneOf" );\n			if ( arr instanceof Array ) {\n				let matches := 0;\n				let child_errors := [];\n				let i := 0;\n				while ( i < arr.length() ) {\n					let child := self._child( arr[i], instance, jschema_pointer_join( jschema_pointer_join( kwloc, "oneOf" ), i ), instloc, base_uri );\n					if ( child.valid() ) {\n						matches++;\n						result.merge(child);\n					}\n					else {\n						for ( let e in child.errors() ) { child_errors.push(e); }\n					}\n					i++;\n				}\n				if ( matches != 1 ) {\n					result.add_error( self.error( OneOfError, jschema_pointer_join( kwloc, "oneOf" ), instloc, "Expected exactly one oneOf subschema to match.", "oneOf" ) );\n					if ( matches == 0 ) {\n						result.add_error( self._subschema_error( jschema_pointer_join( kwloc, "oneOf" ), instloc, child_errors, "oneOf" ) );\n					}\n					if ( not collect ) { return result; }\n				}\n			}\n		}\n\n		if ( jschema_object_has( schema, "not" ) ) {\n			let child := self._child( jschema_object_get( schema, "not" ), instance, jschema_pointer_join( kwloc, "not" ), instloc, base_uri );\n			if ( child.valid() ) {\n				self._invalid( result, NotMatchedError, jschema_pointer_join( kwloc, "not" ), instloc, "Value matched a forbidden subschema.", "not" );\n				if ( not collect ) { return result; }\n			}\n		}\n\n		if ( jschema_object_has( schema, "if" ) ) {\n			let cond := self._child( jschema_object_get( schema, "if" ), instance, jschema_pointer_join( kwloc, "if" ), instloc, base_uri );\n			if ( cond.valid() ) {\n				result.merge(cond);\n			}\n			if ( cond.valid() and jschema_object_has( schema, "then" ) ) {\n				let child := self._child( jschema_object_get( schema, "then" ), instance, jschema_pointer_join( kwloc, "then" ), instloc, base_uri );\n				result.merge(child);\n				if ( not child.valid() ) {\n					result.add_error( self.error( IfThenElseError, jschema_pointer_join( kwloc, "then" ), instloc, "then subschema failed.", "then" ) );\n					if ( not collect ) { return result; }\n				}\n			}\n			else if ( not cond.valid() and jschema_object_has( schema, "else" ) ) {\n				let child := self._child( jschema_object_get( schema, "else" ), instance, jschema_pointer_join( kwloc, "else" ), instloc, base_uri );\n				result.merge(child);\n				if ( not child.valid() ) {\n					result.add_error( self.error( IfThenElseError, jschema_pointer_join( kwloc, "else" ), instloc, "else subschema failed.", "else" ) );\n					if ( not collect ) { return result; }\n				}\n			}\n		}\n	}\n}\n\nclass JSONSchema {\n	let schema;\n	let options := {};\n	let registry;\n	let formats;\n	let String base_uri := "";\n	let Boolean format_assert := false;\n	let String unknown_format := "ignore";\n	let Boolean validation_enabled := true;\n\n	method __build__ () {\n		base_uri := _jschema_opt( options, "base_uri", base_uri );\n		registry := _jschema_opt( options, "registry", null );\n		if ( registry \u2261 null ) {\n			registry := new SchemaRegistry();\n		}\n		formats := _jschema_opt( options, "formats", null );\n		if ( formats \u2261 null ) {\n			formats := _jschema_opt( options, "format_registry", null );\n		}\n		if ( formats \u2261 null ) {\n			formats := new FormatRegistry();\n		}\n		let loader := _jschema_opt( options, "loader", null );\n		if ( loader \u2261 null and _jschema_opt( options, "allow_network", false ) ) {\n			loader := new HTTPResourceLoader();\n		}\n		if ( loader \u2262 null ) {\n			registry.set_loader(loader);\n		}\n		unknown_format := _jschema_opt( options, "unknown_format", "ignore" );\n		validation_enabled := _jschema_opt(\n			options,\n			"validation_enabled",\n			_jschema_validation_vocab_enabled( schema, registry, base_uri ),\n		);\n		format_assert := _jschema_format_assertion_vocab_enabled(\n			schema,\n			registry,\n			base_uri,\n			_jschema_opt( options, "format_assert", false ),\n		);\n		registry.register( schema, base_uri );\n	}\n\n	method _evaluator ( Boolean collect ) {\n		return new _SchemaEvaluator(\n			registry: registry,\n			formats: formats,\n			collect: collect,\n			format_assert: format_assert,\n			unknown_format: unknown_format,\n			validation_enabled: validation_enabled,\n		);\n	}\n\n	method is_valid ( instance ) {\n		return self._evaluator(false).evaluate(\n			schema,\n			instance,\n			"",\n			"",\n			base_uri,\n		).valid();\n	}\n\n	method validate ( instance ) {\n		let ev := self._evaluator(true).evaluate(\n			schema,\n			instance,\n			"",\n			"",\n			base_uri,\n		);\n		return new ValidationResult(\n			valid: ev.valid(),\n			errors: ev.errors(),\n		);\n	}\n}\n\nfunction valid ( schema, instance, options := {} ) {\n	return new JSONSchema( schema: schema, options: options ).is_valid(instance);\n}\n\nfunction validate ( schema, instance, options := {} ) {\n	return new JSONSchema( schema: schema, options: options ).validate(instance);\n}\n';
        virtualFiles["/modules/std/mail.zzm"] = `=encoding utf8

=head1 NAME

std/mail - Pure ZuzuScript mail message object model.

=head1 SYNOPSIS

  from std/mail import Address, Head, Body, Message;
  let message := new Message(
    head: new Head(),
    body: Body.bytes( to_binary("Hello\\r\\n") )
  );

=head1 IMPLEMENTATION SUPPORT

This module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

This module provides the object model for RFC 5322-style message
headers, address objects, MIME-ish bodies, date helpers, a conservative
parser, and integration with compatible low-level mailers.

The parser ignores multipart preamble and epilogue bytes in Phase 9.
When either is present, C<Parser.warnings()> records the limitation.

The serializer can generate missing multipart boundaries on request.
C<Serializer.serialize()> writes matching C<Content-Type> output for the
generated boundary. C<Serializer.serialize_body()> returns only body bytes,
so callers using it with a generated boundary must provide the matching
C<Content-Type> header separately.

=head1 EXPORTS

=head2 Functions

=over

=item C<< parse_datetime(String text) >>

Parameters: C<text> is a mail date string. Returns: C<Time>. Parses a
mail header date into a C<std/time> object.

=item C<< format_datetime(Time time) >>

Parameters: C<time> is a C<std/time> object. Returns: C<String>. Formats
a time for use in mail headers.

=back

=head2 Classes

=over

=item C<Address>

Mail address object.

=over

=item C<< Address.parse(String text) >>, C<< Address.parse_list(String text) >>

Parameters: C<text> is address header text. Returns: C<Address> or
C<Array>. Parses one address or a comma-separated address list.

=item C<< address.local() >>, C<< address.domain() >>, C<< address.display_name() >>, C<< address.address() >>

Parameters: none. Returns: C<String> or C<null>. Returns address
components.

=item C<< address.to_header() >>, C<< address.to_String() >>

Parameters: none. Returns: C<String>. Formats the address.

=item C<< address.to_Dict() >>

Parameters: none. Returns: C<Dict>. Converts the address to a
dictionary.

=back

=item C<Head>

Ordered mail header collection.

=over

=item C<< head.fields() >>, C<< head.to_PairList() >>, C<< head.to_Iterator() >>

Parameters: none. Returns: C<PairList> or C<Function>. Returns header
fields or an iterator.

=item C<< head.raw(String name, fallback := null) >>, C<< head.raw_all(String name) >>, C<< head.decoded(String name, fallback := null) >>, C<< head.decoded_all(String name) >>, C<< head.get(String name, fallback := null) >>, C<< head.get_all(String name) >>

Parameters: C<name> is a header name and C<fallback> is optional.
Returns: C<String>, C<Array>, or fallback. Reads header values.

=item C<< head.set(String name, String value) >>, C<< head.add(String name, String value) >>, C<< head.remove(String name) >>

Parameters: C<name> is a header name and C<value> is header text.
Returns: C<Head>. Mutates header fields.

=item C<< head.has(String name) >>

Parameters: C<name> is a header name. Returns: C<Boolean>. Tests whether
a header exists.

=item C<< head.content_type() >>, C<< head.content_transfer_encoding() >>, C<< head.charset() >>, C<< head.boundary() >>, C<< head.message_id() >>, C<< head.date() >>, C<< head.from() >>, C<< head.to() >>, C<< head.cc() >>, C<< head.bcc() >>, C<< head.subject() >>

Parameters: none. Returns: header-specific value. Reads common headers.

=back

=item C<Body>

Mail body value.

=over

=item C<< Body.bytes(BinaryString raw, ... PairList options) >>

Parameters: C<raw> is body bytes and C<options> describe content type,
encoding, and parts. Returns: C<Body>. Creates a leaf or multipart body.

=item C<< Body.nested(message, ... PairList options) >>

Parameters: C<message> is a C<Message>. Returns: C<Body>. Creates a
nested message body.

=item C<< body.is_multipart() >>, C<< body.is_nested() >>

Parameters: none. Returns: C<Boolean>. Reports body shape.

=item C<< body.bytes() >>, C<< body.decoded() >>, C<< body.encoded() >>

Parameters: none. Returns: C<BinaryString>. Returns raw, decoded, or
encoded body bytes.

=item C<< body.parts() >>, C<< body.part(Number index) >>, C<< body.count() >>

Parameters: C<index> selects a body part. Returns: C<Array>, C<Body>, or
C<Number>. Reads multipart body parts.

=item C<< body.nested() >>, C<< body.content_type() >>, C<< body.transfer_encoding() >>, C<< body.to_Dict() >>

Parameters: none. Returns: value. Reads body metadata or converts the
body to a dictionary.

=back

=item C<Message>

Mail message object with C<head> and C<body>.

=over

=item C<< message.head() >>, C<< message.body() >>

Parameters: none. Returns: C<Head> or C<Body>. Returns message parts.

=item C<< message.header(String name, fallback := null) >>, C<< message.headers(String name) >>

Parameters: C<name> is a header name and C<fallback> is optional.
Returns: C<String>, C<Array>, or fallback. Reads message headers.

=item C<< message.set_header(String name, String value) >>, C<< message.add_header(String name, String value) >>, C<< message.remove_header(String name) >>

Parameters: C<name> is a header name and C<value> is header text.
Returns: C<Message>. Mutates message headers.

=item C<< message.subject() >>, C<< message.from() >>, C<< message.to() >>, C<< message.cc() >>, C<< message.bcc() >>, C<< message.date() >>, C<< message.message_id() >>

Parameters: none. Returns: header-specific value. Reads common message
headers.

=item C<< message.is_part() >>, C<< message.container() >>, C<< message.toplevel() >>

Parameters: none. Returns: C<Boolean> or C<Message>. Reads containment
state.

=item C<< message.send(mailer, ... PairList options) >>

Parameters: C<mailer> is a compatible low-level mailer. Returns: value.
Sends the message.

=item C<< message.to_Dict() >>

Parameters: none. Returns: C<Dict>. Converts the message to a
dictionary.

=back

=item C<Parser>

Conservative mail parser.

=over

=item C<< parser.warnings() >>

Parameters: none. Returns: C<Array>. Returns non-fatal parse warnings.

=item C<< parser.parse(BinaryString bytes) >>

Parameters: C<bytes> is raw message bytes. Returns: C<Message>. Parses a
mail message.

=back

=item C<Serializer>

Mail serializer.

=over

=item C<< serializer.serialize_body(Message message, ... PairList options) >>

Parameters: C<message> is a mail message and C<options> control output.
Returns: C<BinaryString>. Serializes only the message body.

=item C<< serializer.serialize(Message message, ... PairList options) >>

Parameters: C<message> is a mail message and C<options> control output.
Returns: C<BinaryString>. Serializes a complete message.

=back

=back

=head1 COPYRIGHT AND LICENCE

B<< std/mail >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/string import chr, index, join, ord, substr, trim;

from std/string/base64 import
	encode as _base64_encode,
	decode as _base64_decode;
from std/string/quoted_printable import decode as _qp_decode;
from std/time import Time, TimeZone;

function _parse_one_address;
function _parse_address_list;
function _parse_address_header;
function _mail_send_serialize_body;

function _has_crlf ( String text ) {
	return index( text, "\\r" ) >= 0 or index( text, "\\n" ) >= 0;
}

function _assert_no_crlf ( String text, String context ) {
	if ( _has_crlf(text) ) {
		die \`mail.\${context}: value must not contain CR or LF\`;
	}
}

function _is_ws ( String ch ) {
	return ch eq " " or ch eq "\\t";
}

function _skip_ws ( String text, Number i ) {
	let pos := i;
	let n := length text;
	while ( pos < n and _is_ws( substr( text, pos, 1 ) ) ) {
		pos++;
	}
	return pos;
}

function _div_floor ( Number n, Number d ) {
	return floor( n / d );
}

function _hex_value ( String ch ) {
	let v := index( "0123456789ABCDEF", uc(ch) );
	return v;
}

function _bytes_to_binary ( Array bytes ) {
	let alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		_ "abcdefghijklmnopqrstuvwxyz0123456789+/";
	let out := "";
	let i := 0;
	let n := bytes.length();

	while ( i < n ) {
		let b0 := bytes[i];
		let b1 := null;
		let b2 := null;
		if ( i + 1 < n ) {
			b1 := bytes[i + 1];
		}
		if ( i + 2 < n ) {
			b2 := bytes[i + 2];
		}

		let c0 := _div_floor( b0, 4 );
		let c1 := ( b0 mod 4 ) * 16;
		let c2 := 64;
		let c3 := 64;

		if ( not( b1 == null ) ) {
			c1 += _div_floor( b1, 16 );
			c2 := ( b1 mod 16 ) * 4;
			if ( not( b2 == null ) ) {
				c2 += _div_floor( b2, 64 );
				c3 := b2 mod 64;
			}
		}

		out _= substr( alphabet, c0, 1 );
		out _= substr( alphabet, c1, 1 );
		out _= c2 == 64 ? "=" : substr( alphabet, c2, 1 );
		out _= c3 == 64 ? "=" : substr( alphabet, c3, 1 );
		i += 3;
	}

	return _base64_decode(out);
}

function _binary_to_bytes ( BinaryString raw ) {
	let alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
		_ "abcdefghijklmnopqrstuvwxyz0123456789+/";
	let b64 := _base64_encode(raw);
	let out := [];
	let i := 0;
	let n := length b64;

	while ( i < n ) {
		let c0 := index( alphabet, substr( b64, i, 1 ) );
		let c1 := index( alphabet, substr( b64, i + 1, 1 ) );
		let ch2 := substr( b64, i + 2, 1 );
		let ch3 := substr( b64, i + 3, 1 );
		let c2 := -1;
		let c3 := -1;
		if ( ch2 ne "=" ) {
			c2 := index( alphabet, ch2 );
		}
		if ( ch3 ne "=" ) {
			c3 := index( alphabet, ch3 );
		}

		out.push( c0 * 4 + _div_floor( c1, 16 ) );
		if ( c2 >= 0 ) {
			out.push( ( c1 mod 16 ) * 16 + _div_floor( c2, 4 ) );
		}
		if ( c3 >= 0 ) {
			out.push( ( c2 mod 4 ) * 64 + c3 );
		}

		i += 4;
	}

	return out;
}

function _latin1_to_string ( BinaryString raw ) {
	let out := "";
	for ( let b in _binary_to_bytes(raw) ) {
		out _= chr(b);
	}
	return out;
}

function _read_quoted_string ( String text, Number start ) {
	let n := length text;
	if ( substr( text, start, 1 ) ne "\\"" ) {
		die "mail.invalid_address: expected quoted string";
	}

	let out := "";
	let i := start + 1;
	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( ch eq "\\"" ) {
			return { value: out, end: i + 1 };
		}
		if ( ch eq "\\\\" ) {
			if ( i + 1 >= n ) {
				die "mail.invalid_address: unterminated quoted string";
			}
			out _= substr( text, i + 1, 1 );
			i += 2;
			next;
		}
		if ( ch eq "\\r" or ch eq "\\n" ) {
			die "mail.invalid_address: quoted string must not contain CR or LF";
		}
		out _= ch;
		i++;
	}

	die "mail.invalid_address: unterminated quoted string";
}

function _quote_string ( String text ) {
	let out := "\\"";
	let i := 0;
	let n := length text;

	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( ch eq "\\\\" or ch eq "\\"" ) {
			out _= "\\\\";
		}
		out _= ch;
		i++;
	}

	return out _ "\\"";
}

function _is_alpha ( String ch ) {
	let cp := ord(ch);
	return ( cp >= 65 and cp <= 90 ) or ( cp >= 97 and cp <= 122 );
}

function _is_digit ( String ch ) {
	let cp := ord(ch);
	return cp >= 48 and cp <= 57;
}

function _is_atext ( String ch ) {
	if ( _is_alpha(ch) or _is_digit(ch) ) {
		return true;
	}
	return index( "!#$%&'*+-/=?^_\`{|}~", ch ) >= 0;
}

function _is_dot_atom ( String text ) {
	let n := length text;
	return false if n == 0;
	return false if substr( text, 0, 1 ) eq ".";
	return false if substr( text, n - 1, 1 ) eq ".";

	let prev_dot := false;
	let i := 0;
	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( ch eq "." ) {
			return false if prev_dot;
			prev_dot := true;
		}
		else {
			return false if not _is_atext(ch);
			prev_dot := false;
		}
		i++;
	}

	return true;
}

function _is_domain_text ( String text ) {
	let n := length text;
	return false if n == 0;
	return false if substr( text, 0, 1 ) eq ".";
	return false if substr( text, n - 1, 1 ) eq ".";

	let i := 0;
	while ( i < n ) {
		let ch := substr( text, i, 1 );
		return false if not(
			_is_alpha(ch)
			or _is_digit(ch)
			or ch eq "-"
			or ch eq "."
		);
		i++;
	}

	return true;
}

function _is_phrase_text ( String text ) {
	let n := length text;
	return false if n == 0;
	return false if text ne trim(text);

	let i := 0;
	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( _is_ws(ch) ) {
			i++;
			next;
		}
		return false if not _is_atext(ch) and ch ne ".";
		i++;
	}

	return true;
}

function _find_unquoted (
	String text,
	String target,
	Number start := 0,
	Boolean ignore_angle := false,
) {
	let i := start;
	let n := length text;
	let in_quote := false;
	let escape := false;
	let in_literal := false;
	let angle_depth := 0;

	while ( i < n ) {
		let ch := substr( text, i, 1 );

		if ( escape ) {
			escape := false;
			i++;
			next;
		}
		if ( in_quote ) {
			if ( ch eq "\\\\" ) {
				escape := true;
			}
			else if ( ch eq "\\"" ) {
				in_quote := false;
			}
			i++;
			next;
		}
		if ( in_literal ) {
			if ( ch eq "]" ) {
				in_literal := false;
			}
			i++;
			next;
		}

		if ( ch eq target and ( not ignore_angle or angle_depth == 0 ) ) {
			return i;
		}
		if ( ch eq "\\"" ) {
			in_quote := true;
		}
		else if ( ch eq "[" ) {
			in_literal := true;
		}
		else if ( ch eq "<" ) {
			angle_depth++;
		}
		else if ( ch eq ">" and angle_depth > 0 ) {
			angle_depth--;
		}

		i++;
	}

	return -1;
}

function _find_top_level ( String text, String target, Number start := 0 ) {
	return _find_unquoted( text, target, start, true );
}

function _parse_phrase ( String raw ) {
	let text := trim(raw);
	return null if text eq "";

	if ( substr( text, 0, 1 ) eq "\\"" ) {
		let quoted := _read_quoted_string( text, 0 );
		if ( trim( substr( text, quoted{end} ) ) ne "" ) {
			die "mail.invalid_address: text follows quoted display name";
		}
		return quoted{value};
	}

	return text;
}

function _parse_addr_spec ( String raw ) {
	let text := trim(raw);
	_assert_no_crlf( text, "invalid_address" );

	if ( substr( text, 0, 1 ) eq "@" ) {
		die "mail.invalid_address: obsolete route syntax is not supported";
	}

	let at := _find_unquoted( text, "@", 0, false );
	if ( at < 0 ) {
		die "mail.invalid_address: mailbox address is missing @";
	}

	let route := _find_unquoted( text, ":", 0, false );
	if ( route >= 0 and route < at ) {
		die "mail.invalid_address: obsolete route syntax is not supported";
	}

	let local := trim( substr( text, 0, at ) );
	let domain := trim( substr( text, at + 1 ) );
	if ( local eq "" or domain eq "" ) {
		die "mail.invalid_address: mailbox address is incomplete";
	}

	if ( substr( local, 0, 1 ) eq "\\"" ) {
		let quoted := _read_quoted_string( local, 0 );
		if ( quoted{end} != length local ) {
			die "mail.invalid_address: text follows quoted local part";
		}
		local := quoted{value};
	}
	else if ( not _is_dot_atom(local) ) {
		die "mail.invalid_address: invalid local part";
	}

	if ( substr( domain, 0, 1 ) eq "[" ) {
		if ( substr( domain, ( length domain ) - 1, 1 ) ne "]" ) {
			die "mail.invalid_address: unterminated domain literal";
		}
		if ( _has_crlf(domain) ) {
			die "mail.invalid_address: invalid domain literal";
		}
	}
	else if ( not _is_domain_text(domain) ) {
		die "mail.invalid_address: invalid domain";
	}

	return { local: local, domain: domain };
}

function _decode_q_encoded_word ( String text ) {
	let bytes := [];
	let i := 0;
	let n := length text;

	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( ch eq "_" ) {
			bytes.push(32);
			i++;
			next;
		}
		if ( ch eq "=" ) {
			if ( i + 2 >= n ) {
				return null;
			}
			let hi := _hex_value( substr( text, i + 1, 1 ) );
			let lo := _hex_value( substr( text, i + 2, 1 ) );
			if ( hi < 0 or lo < 0 ) {
				return null;
			}
			bytes.push( hi * 16 + lo );
			i += 3;
			next;
		}

		let cp := ord(ch);
		return null if cp > 127;
		bytes.push(cp);
		i++;
	}

	return _bytes_to_binary(bytes);
}

function _normal_charset ( String charset ) {
	let cs := lc(charset);
	if ( cs in [ "utf-8", "utf8" ] ) {
		return "utf-8";
	}
	if ( cs in [ "us-ascii", "ascii" ] ) {
		return "us-ascii";
	}
	if ( cs in [ "latin1", "latin-1", "iso-8859-1", "iso8859-1" ] ) {
		return "latin1";
	}
	return null;
}

function _decode_charset_bytes ( BinaryString bytes, String charset ) {
	let cs := _normal_charset(charset);
	return null if cs == null;

	if ( cs eq "latin1" ) {
		return _latin1_to_string(bytes);
	}

	return try {
		to_string(bytes);
	}
	catch {
		null;
	};
}

function _parse_encoded_word_at ( String text, Number start ) {
	if ( substr( text, start, 2 ) ne "=?" ) {
		return null;
	}

	let q1 := index( text, "?", start + 2 );
	return null if q1 < 0;
	let q2 := index( text, "?", q1 + 1 );
	return null if q2 < 0;
	let end := index( text, "?=", q2 + 1 );
	return null if end < 0;

	let charset := substr( text, start + 2, q1 - start - 2 );
	let encoding := lc( substr( text, q1 + 1, q2 - q1 - 1 ) );
	let payload := substr( text, q2 + 1, end - q2 - 1 );
	let bytes := null;

	if ( charset eq "" or payload eq "" ) {
		return null;
	}
	if ( encoding eq "b" ) {
		bytes := try {
			_base64_decode(payload);
		}
		catch {
			null;
		};
	}
	else if ( encoding eq "q" ) {
		bytes := _decode_q_encoded_word(payload);
	}
	else {
		return null;
	}

	return null if bytes == null;
	let decoded := _decode_charset_bytes( bytes, charset );
	return null if decoded == null;

	return { text: decoded, end: end + 2 };
}

function _decode_rfc2047 ( String raw ) {
	let out := "";
	let pending_ws := "";
	let last_encoded := false;
	let i := 0;
	let n := length raw;

	while ( i < n ) {
		let ch := substr( raw, i, 1 );
		if ( _is_ws(ch) ) {
			let start := i;
			while ( i < n and _is_ws( substr( raw, i, 1 ) ) ) {
				i++;
			}
			pending_ws _= substr( raw, start, i - start );
			next;
		}

		if ( substr( raw, i, 2 ) eq "=?" ) {
			let parsed := _parse_encoded_word_at( raw, i );
			if ( not( parsed == null ) ) {
				out _= pending_ws unless last_encoded;
				pending_ws := "";
				out _= parsed{text};
				last_encoded := true;
				i := parsed{end};
				next;
			}
		}

		out _= pending_ws;
		pending_ws := "";
		out _= ch;
		last_encoded := false;
		i++;
	}

	return out _ pending_ws;
}

function _copy_pairlist ( fields ) {
	let copy := new PairList();
	if ( fields == null ) {
		return copy;
	}
	if ( not( fields instanceof PairList ) ) {
		die "mail.invalid_headers: Head fields expects PairList";
	}
	for ( let pair in fields.to_Array() ) {
		copy.add( pair.key, pair.value );
	}
	return copy;
}

function _mail_send_recipients_option ( value ) {
	if ( value instanceof String ) {
		return [ value ];
	}
	if ( not( value instanceof Array ) ) {
		die "mail.send: envelope_to expects String or Array";
	}

	let out := [];
	for ( let item in value ) {
		if ( not( item instanceof String ) ) {
			die "mail.send: envelope_to expects String or Array of String";
		}
		out.push(item);
	}
	if ( out.length() == 0 ) {
		die "mail.invalid_address: Message.send requires at least one "
			_ "envelope recipient";
	}
	return out;
}

function _mail_send_options ( PairList options ) {
	let out := {
		envelope_from: null,
		envelope_to: null,
		send_options: new PairList(),
	};

	for ( let pair in options.to_Array() ) {
		if ( pair.key eq "envelope_from" ) {
			if ( not( pair.value instanceof String ) ) {
				die "mail.send: envelope_from expects String";
			}
			out{envelope_from} := pair.value;
		}
		else if ( pair.key eq "envelope_to" ) {
			out{envelope_to} := _mail_send_recipients_option(pair.value);
		}
		else if ( pair.key eq "send_options" ) {
			if ( not( pair.value instanceof Dict )
				and not( pair.value instanceof PairList ) ) {
				die "mail.send: send_options expects Dict or PairList";
			}
			out{send_options} := pair.value;
		}
		else {
			die "mail.send: unsupported option '" _ pair.key _ "'";
		}
	}

	return out;
}

function _valid_header_name ( String name ) {
	let n := length name;
	return false if n == 0;
	let i := 0;
	while ( i < n ) {
		let cp := ord( substr( name, i, 1 ) );
		return false if cp < 33 or cp > 126 or cp == 58;
		i++;
	}
	return true;
}

function _check_header_name ( String name ) {
	if ( not _valid_header_name(name) ) {
		die "mail.invalid_headers: invalid header name";
	}
}

function _check_header_value ( value ) {
	if ( not( value instanceof String ) ) {
		die "mail.invalid_headers: header value expects String, got "
			_ typeof value;
	}
	_assert_no_crlf( value, "invalid_headers" );
}

function _split_header_segments ( String text, String delimiter ) {
	let out := [];
	let start := 0;
	let i := 0;
	let n := length text;
	let in_quote := false;
	let escape := false;

	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( escape ) {
			escape := false;
		}
		else if ( in_quote ) {
			if ( ch eq "\\\\" ) {
				escape := true;
			}
			else if ( ch eq "\\"" ) {
				in_quote := false;
			}
		}
		else if ( ch eq "\\"" ) {
			in_quote := true;
		}
		else if ( ch eq delimiter ) {
			out.push( substr( text, start, i - start ) );
			start := i + 1;
		}
		i++;
	}
	out.push( substr( text, start ) );

	return out;
}

function _unquote_header_param ( String text ) {
	let value := trim(text);
	if ( length value >= 2 and substr( value, 0, 1 ) eq "\\"" ) {
		let quoted := _read_quoted_string( value, 0 );
		if ( trim( substr( value, quoted{end} ) ) eq "" ) {
			return quoted{value};
		}
	}
	return value;
}

function _header_main_value ( String value ) {
	let parts := _split_header_segments( value, ";" );
	return lc( trim( parts[0] ) );
}

function _header_parameter ( String value, String wanted ) {
	let parts := _split_header_segments( value, ";" );
	let i := 1;
	while ( i < parts.length() ) {
		let part := parts[i];
		let equals_at := _find_unquoted( part, "=", 0, false );
		if ( equals_at > 0 ) {
			let name := lc( trim( substr( part, 0, equals_at ) ) );
			if ( name eq lc(wanted) ) {
				return _unquote_header_param( substr( part, equals_at + 1 ) );
			}
		}
		i++;
	}
	return null;
}

function _body_options ( PairList options ) {
	let opts := {
		content_type: null,
		transfer_encoding: null,
		charset: null,
		boundary: null,
	};

	for ( let option in options.to_Array() ) {
		let key := option.key;
		let value := option.value;
		if ( key eq "content_type" ) {
			opts{content_type} := value;
		}
		else if ( key eq "transfer_encoding"
			or key eq "content_transfer_encoding" ) {
			opts{transfer_encoding} := value;
		}
		else if ( key eq "charset" ) {
			opts{charset} := value;
		}
		else if ( key eq "boundary" ) {
			opts{boundary} := value;
		}
		else {
			die \`mail.body: unsupported Body option '\${key}'\`;
		}
	}

	return opts;
}

function _copy_array ( Array items ) {
	let out := [];
	for ( let item in items ) {
		out.push(item);
	}
	return out;
}

function _bytes_slice ( Array bytes, Number start, count := null ) {
	let out := [];
	let end := count == null ? bytes.length() : start + count;
	end := bytes.length() if end > bytes.length();
	let i := start;

	while ( i < end ) {
		out.push(bytes[i]);
		i++;
	}

	return out;
}

function _bytes_to_latin1_string ( Array bytes ) {
	return _latin1_to_string( _bytes_to_binary(bytes) );
}

function _split_message_bytes ( Array bytes ) {
	let n := bytes.length();
	let i := 0;
	let line_start := 0;

	while ( i < n ) {
		if ( bytes[i] == 10 ) {
			let content_end := i;
			if ( content_end > line_start and bytes[content_end - 1] == 13 ) {
				content_end--;
			}
			if ( content_end == line_start ) {
				return {
					header_bytes: _bytes_slice( bytes, 0, line_start ),
					body_bytes: _bytes_slice( bytes, i + 1 ),
					header_size: line_start,
					found_separator: true,
				};
			}
			i++;
			line_start := i;
			next;
		}
		i++;
	}

	return {
		header_bytes: _bytes_slice( bytes, 0 ),
		body_bytes: [],
		header_size: n,
		found_separator: false,
	};
}

function _mail_header_lines ( Array bytes ) {
	let lines := [];
	let n := bytes.length();
	let i := 0;
	let line_start := 0;

	while ( i < n ) {
		if ( bytes[i] == 10 ) {
			let content_end := i;
			if ( content_end > line_start and bytes[content_end - 1] == 13 ) {
				content_end--;
			}
			lines.push(
				_bytes_to_latin1_string(
					_bytes_slice( bytes, line_start, content_end - line_start ),
				),
			);
			i++;
			line_start := i;
			next;
		}
		i++;
	}

	if ( line_start < n ) {
		lines.push( _bytes_to_latin1_string( _bytes_slice( bytes, line_start ) ) );
	}

	return lines;
}

function _parse_mail_header_fields ( Array header_bytes ) {
	let fields := new PairList();
	let current_name := null;
	let current_value := "";

	for ( let line in _mail_header_lines(header_bytes) ) {
		next if line eq "";

		if ( _is_ws( substr( line, 0, 1 ) ) ) {
			if ( current_name == null ) {
				die "mail.parse: folded header without previous field";
			}
			current_value _= " " _ trim(line);
			next;
		}

		if ( not( current_name == null ) ) {
			fields.add( current_name, current_value );
		}

		let colon := index( line, ":" );
		if ( colon <= 0 ) {
			die "mail.parse: malformed header line";
		}

		current_name := substr( line, 0, colon );
		if ( not _valid_header_name(current_name) ) {
			die "mail.parse: invalid header name";
		}
		current_value := trim( substr( line, colon + 1 ) );
	}

	if ( not( current_name == null ) ) {
		fields.add( current_name, current_value );
	}

	return fields;
}

function _only_sp_tab ( String text ) {
	let i := 0;
	let n := length text;

	while ( i < n ) {
		return false if not _is_ws( substr( text, i, 1 ) );
		i++;
	}

	return true;
}

function _mail_boundary_line_kind ( Array line_bytes, String boundary ) {
	let line := _bytes_to_latin1_string(line_bytes);
	let delimiter := "--" _ boundary;
	let dlen := length delimiter;

	return null if length line < dlen;
	return null if substr( line, 0, dlen ) ne delimiter;

	let tail := substr( line, dlen );
	return "open" if _only_sp_tab(tail);

	if ( length tail >= 2 and substr( tail, 0, 2 ) eq "--" ) {
		return "close" if _only_sp_tab( substr( tail, 2 ) );
	}

	return null;
}

function _mail_part_end_before_boundary (
	Array bytes,
	Number part_start,
	Number line_start
) {
	let end := line_start;
	if ( end > part_start and bytes[end - 1] == 10 ) {
		end--;
		if ( end > part_start and bytes[end - 1] == 13 ) {
			end--;
		}
	}
	return end;
}

function _scan_multipart_parts ( Array bytes, String boundary ) {
	let parts := [];
	let n := bytes.length();
	let line_start := 0;
	let opened := false;
	let closed := false;
	let part_start := 0;
	let preamble_size := 0;
	let epilogue_size := 0;

	while ( line_start < n ) {
		let line_end := line_start;
		while ( line_end < n and bytes[line_end] != 10 ) {
			line_end++;
		}

		let content_end := line_end;
		if ( content_end > line_start and bytes[content_end - 1] == 13 ) {
			content_end--;
		}

		let after_line := line_end < n ? line_end + 1 : n;
		let kind := _mail_boundary_line_kind(
			_bytes_slice( bytes, line_start, content_end - line_start ),
			boundary,
		);

		if ( not( kind == null ) ) {
			if ( not opened ) {
				opened := true;
				preamble_size := line_start;
				part_start := after_line;
				if ( kind eq "close" ) {
					closed := true;
					epilogue_size := n - after_line;
					return {
						opened: opened,
						closed: closed,
						parts: parts,
						preamble_size: preamble_size,
						epilogue_size: epilogue_size,
					};
				}
			}
			else {
				let part_end := _mail_part_end_before_boundary(
					bytes,
					part_start,
					line_start,
				);
				parts.push(
					_bytes_slice( bytes, part_start, part_end - part_start ),
				);
				part_start := after_line;

				if ( kind eq "close" ) {
					closed := true;
					epilogue_size := n - after_line;
					return {
						opened: opened,
						closed: closed,
						parts: parts,
						preamble_size: preamble_size,
						epilogue_size: epilogue_size,
					};
				}
			}
		}

		line_start := after_line;
	}

	if ( opened and not closed ) {
		parts.push( _bytes_slice( bytes, part_start ) );
	}

	return {
		opened: opened,
		closed: closed,
		parts: parts,
		preamble_size: preamble_size,
		epilogue_size: epilogue_size,
	};
}

function _is_identity_transfer_encoding ( encoding ) {
	if ( encoding == null or encoding eq "" ) {
		return true;
	}
	return encoding in [ "identity", "7bit", "8bit", "binary" ];
}

function _invalid_datetime ( String message ) {
	die "mail.invalid_datetime: " _ message;
}

function _numeric_zone_seconds ( String zone ) {
	return null if not( zone ~ /^[+-][0-9]{4}$/ );

	let sign := substr( zone, 0, 1 ) eq "-" ? -1 : 1;
	let hours := int( substr( zone, 1, 2 ) );
	let minutes := int( substr( zone, 3, 2 ) );
	return null if hours > 23 or minutes > 59;
	return sign * ( hours * 3600 + minutes * 60 );
}

function _datetime_apply_option ( Dict opts, Dict seen, key, value ) {
	if ( not( key instanceof String ) ) {
		_invalid_datetime("format option names must be strings");
	}
	if ( seen.exists(key) ) {
		_invalid_datetime( "conflicting format option '" _ key _ "'" );
	}
	seen.set( key, true );

	if ( key eq "utc" ) {
		if ( not( value instanceof Boolean ) ) {
			_invalid_datetime("format option 'utc' expects Boolean");
		}
		opts{utc} := value;
		opts{utc_seen} := true;
		return;
	}
	if ( key eq "offset" ) {
		if ( not( value instanceof String ) ) {
			_invalid_datetime("format option 'offset' expects String");
		}
		let seconds := _numeric_zone_seconds(value);
		if ( seconds == null ) {
			_invalid_datetime("format option 'offset' expects +HHMM or -HHMM");
		}
		opts{offset} := value;
		opts{offset_seconds} := seconds;
		opts{offset_seen} := true;
		return;
	}
	if ( key eq "include_weekday" ) {
		if ( not( value instanceof Boolean ) ) {
			_invalid_datetime("format option 'include_weekday' expects Boolean");
		}
		opts{include_weekday} := value;
		return;
	}

	_invalid_datetime( "unknown format option '" _ key _ "'" );
}

function _datetime_options ( options, PairList named_options ) {
	let opts := {
		utc: true,
		utc_seen: false,
		offset: "+0000",
		offset_seconds: 0,
		offset_seen: false,
		include_weekday: true,
	};
	let seen := {};

	if ( options instanceof Dict ) {
		for ( let key in options.keys() ) {
			_datetime_apply_option( opts, seen, key, options.get(key) );
		}
	}
	else if ( options instanceof PairList ) {
		for ( let pair in options.to_Array() ) {
			_datetime_apply_option( opts, seen, pair.key, pair.value );
		}
	}
	else {
		_invalid_datetime("format options expects Dict");
	}

	for ( let pair in named_options.to_Array() ) {
		_datetime_apply_option( opts, seen, pair.key, pair.value );
	}

	if ( opts{offset_seen} and not opts{utc_seen} ) {
		opts{utc} := false;
	}
	if ( opts{utc} and opts{offset_seconds} != 0 ) {
		_invalid_datetime("format options 'utc' and 'offset' conflict");
	}
	return opts;
}

function _datetime_parse_error_message ( e ) {
	let message := lc( "" _ e );
	return "invalid time zone" if index( message, "invalid time zone" ) >= 0;
	return "invalid time zone" if index( message, "timezone offset" ) >= 0;
	return "invalid date" if index( message, "invalid date" ) >= 0;
	return "invalid time" if index( message, "invalid time" ) >= 0;
	return "invalid month" if index( message, "invalid month" ) >= 0;
	return "invalid weekday" if index( message, "invalid weekday" ) >= 0;
	return "invalid year" if index( message, "invalid year" ) >= 0;
	return "expected RFC 5322 date-time";
}

function parse_datetime ( String text ) {
	_assert_no_crlf( text, "invalid_datetime" );

	try {
		return Time.parse( trim(text) );
	}
	catch ( Exception e ) {
		_invalid_datetime( _datetime_parse_error_message(e) );
	}
}

function format_datetime (
	time,
	options := {},
	... PairList named_options
) {
	if ( not( time instanceof Time ) ) {
		_invalid_datetime("format_datetime expects Time");
	}

	let opts := _datetime_options( options, named_options );
	let zoned := opts{utc}
		? time.with_timezone( TimeZone.utc() )
		: time.with_timezone( TimeZone.offset(opts{offset_seconds}) );
	return zoned.to_rfc5322( include_weekday: opts{include_weekday} );
}

class Address {
	let local := null;
	let domain := null;
	let display_name := null;

	method __build__ () {
		if ( not( local instanceof String ) or local eq "" ) {
			die "mail.invalid_address: local part expects non-empty String";
		}
		if ( not( domain instanceof String ) or domain eq "" ) {
			die "mail.invalid_address: domain expects non-empty String";
		}
		if ( not( display_name == null ) and not( display_name instanceof String ) ) {
			die "mail.invalid_address: display_name expects String or null";
		}

		_assert_no_crlf( local, "invalid_address" );
		_assert_no_crlf( domain, "invalid_address" );
		if ( not( display_name == null ) ) {
			_assert_no_crlf( display_name, "invalid_address" );
		}
	}

	method local () {
		return local;
	}

	method domain () {
		return domain;
	}

	method display_name () {
		return display_name;
	}

	method address () {
		let lhs := _is_dot_atom(local) ? local : _quote_string(local);
		return lhs _ "@" _ domain;
	}

	method to_header () {
		if ( display_name == null or display_name eq "" ) {
			return self.address();
		}

		let name := _is_phrase_text(display_name)
			? display_name
			: _quote_string(display_name);
		return name _ " <" _ self.address() _ ">";
	}

	method to_String () {
		return self.to_header();
	}

	method to_Dict () {
		return {
			local: local,
			domain: domain,
			display_name: display_name,
			address: self.address(),
			header: self.to_header(),
		};
	}

	static method parse ( String text ) {
		return _parse_one_address(text);
	}

	static method parse_list ( String text ) {
		return _parse_address_list(text);
	}
}

function _parse_one_address ( String raw ) {
	let text := trim(raw);
	_assert_no_crlf( text, "invalid_address" );

	if ( text eq "" ) {
		die "mail.invalid_address: empty address";
	}
	if ( _find_unquoted( text, "(", 0, false ) >= 0
		or _find_unquoted( text, ")", 0, false ) >= 0 ) {
		die "mail.invalid_address: obsolete comment syntax is not supported";
	}

	let angle_start := _find_unquoted( text, "<", 0, false );
	if ( angle_start >= 0 ) {
		let angle_end := _find_unquoted( text, ">", angle_start + 1, false );
		if ( angle_end < 0 ) {
			die "mail.invalid_address: unterminated angle address";
		}
		if ( trim( substr( text, angle_end + 1 ) ) ne "" ) {
			die "mail.invalid_address: text follows angle address";
		}

		let spec := _parse_addr_spec(
			substr( text, angle_start + 1, angle_end - angle_start - 1 ),
		);
		return new Address(
			local: spec{local},
			domain: spec{domain},
			display_name: _parse_phrase( substr( text, 0, angle_start ) ),
		);
	}

	let spec := _parse_addr_spec(text);
	return new Address( local: spec{local}, domain: spec{domain} );
}

function _parse_address_list ( String text ) {
	_assert_no_crlf( text, "invalid_address" );

	let out := [];
	let i := 0;
	let n := length text;

	while ( i < n ) {
		i := _skip_ws( text, i );
		if ( i < n and substr( text, i, 1 ) eq "," ) {
			i++;
			next;
		}

		let comma := _find_top_level( text, ",", i );
		let semi := _find_top_level( text, ";", i );
		let colon := _find_top_level( text, ":", i );
		let group_end := semi;

		if ( colon >= 0
			and ( comma < 0 or colon < comma )
			and ( semi < 0 or colon < semi ) ) {
			if ( group_end < 0 ) {
				die "mail.invalid_address: unterminated address group";
			}
			for ( let addr in _parse_address_list(
				substr( text, colon + 1, group_end - colon - 1 ),
			) ) {
				out.push(addr);
			}
			i := group_end + 1;
			next;
		}

		let end := comma < 0 ? n : comma;
		if ( semi >= 0 and semi < end ) {
			end := semi;
		}
		let token := trim( substr( text, i, end - i ) );
		if ( token ne "" ) {
			out.push( Address.parse(token) );
		}
		i := end + 1;
	}

	return out;
}

function _parse_address_header ( value ) {
	if ( value == null ) {
		return [];
	}
	return Address.parse_list(value);
}

function _mail_send_addresses_from_headers ( head, Array names ) {
	let out := [];
	for ( let name in names ) {
		for ( let value in head.decoded_all(name) ) {
			for ( let address in Address.parse_list(value) ) {
				out.push(address);
			}
		}
	}
	return out;
}

function _mail_send_envelope_from ( head ) {
	let senders := _mail_send_addresses_from_headers( head, [ "Sender" ] );
	if ( senders.length() == 1 ) {
		return senders[0].address();
	}
	if ( senders.length() > 1 ) {
		die "mail.invalid_address: Message.send requires exactly one "
			_ "Sender address";
	}

	let from_addrs := _mail_send_addresses_from_headers( head, [ "From" ] );
	if ( from_addrs.length() == 1 ) {
		return from_addrs[0].address();
	}
	if ( from_addrs.length() > 1 ) {
		die "mail.invalid_address: Message.send requires exactly one "
			_ "From address when Sender is absent";
	}
	die "mail.invalid_address: Message.send requires a Sender or From "
		_ "address";
}

function _mail_send_envelope_to ( head ) {
	let addresses := _mail_send_addresses_from_headers(
		head,
		[ "To", "Cc", "Bcc" ],
	);
	let seen := {};
	let out := [];

	for ( let address in addresses ) {
		let value := address.address();
		if ( not( value in seen ) ) {
			seen{(value)} := true;
			out.push(value);
		}
	}
	if ( out.length() == 0 ) {
		die "mail.invalid_address: Message.send requires at least one "
			_ "envelope recipient";
	}
	return out;
}

function _mail_send_headers ( head ) {
	let out := new PairList();
	for ( let pair in head.to_PairList().to_Array() ) {
		if ( lc(pair.key) ne "bcc" ) {
			out.add( pair.key, pair.value );
		}
	}
	return out;
}

class Head {
	let fields := null;

	method __build__ () {
		fields := _copy_pairlist(fields);
		for ( let pair in fields.to_Array() ) {
			_check_header_name(pair.key);
			_check_header_value(pair.value);
		}
	}

	method fields () {
		return fields.keys();
	}

	method raw ( String name, fallback := null ) {
		_check_header_name(name);
		let key := lc(name);
		for ( let pair in fields.to_Array() ) {
			if ( lc(pair.key) eq key ) {
				return pair.value;
			}
		}
		return fallback;
	}

	method raw_all ( String name ) {
		_check_header_name(name);
		let key := lc(name);
		let out := [];
		for ( let pair in fields.to_Array() ) {
			if ( lc(pair.key) eq key ) {
				out.push(pair.value);
			}
		}
		return out;
	}

	method decoded ( String name, fallback := null ) {
		let raw := self.raw( name, null );
		return fallback if raw == null;
		return _decode_rfc2047(raw);
	}

	method decoded_all ( String name ) {
		let out := [];
		for ( let value in self.raw_all(name) ) {
			out.push( _decode_rfc2047(value) );
		}
		return out;
	}

	method get ( String name, fallback := null ) {
		return self.decoded( name, fallback );
	}

	method get_all ( String name ) {
		return self.decoded_all(name);
	}

	method set ( String name, String value ) {
		self.remove(name);
		return self.add( name, value );
	}

	method add ( String name, String value ) {
		_check_header_name(name);
		_check_header_value(value);
		fields.add( name, value );
		return self;
	}

	method remove ( String name ) {
		_check_header_name(name);
		let key := lc(name);
		let kept := new PairList();
		for ( let pair in fields.to_Array() ) {
			if ( lc(pair.key) ne key ) {
				kept.add( pair.key, pair.value );
			}
		}
		fields := kept;
		return self;
	}

	method has ( String name ) {
		return not( self.raw( name, null ) == null );
	}

	method to_PairList () {
		return _copy_pairlist(fields);
	}

	method to_Iterator () {
		let items := fields.to_Array();
		return items.to_Iterator();
	}

	method content_type () {
		let value := self.decoded( "Content-Type", null );
		return value == null ? null : _header_main_value(value);
	}

	method content_transfer_encoding () {
		let value := self.decoded( "Content-Transfer-Encoding", null );
		return value == null ? null : lc( trim(value) );
	}

	method charset () {
		let value := self.decoded( "Content-Type", null );
		let got := value == null ? null : _header_parameter( value, "charset" );
		return got == null ? null : lc(got);
	}

	method boundary () {
		let value := self.decoded( "Content-Type", null );
		return value == null ? null : _header_parameter( value, "boundary" );
	}

	method message_id () {
		return self.decoded( "Message-ID", null );
	}

	method date () {
		return self.decoded( "Date", null );
	}

	method from () {
		return _parse_address_header( self.decoded( "From", null ) );
	}

	method to () {
		return _parse_address_header( self.decoded( "To", null ) );
	}

	method cc () {
		return _parse_address_header( self.decoded( "Cc", null ) );
	}

	method bcc () {
		return _parse_address_header( self.decoded( "Bcc", null ) );
	}

	method subject () {
		return self.decoded( "Subject", null );
	}
}

class _BodyBase {
	let kind := "bytes";
	let _bytes := null;
	let _parts := null;
	let _nested := null;
	let content_type := null;
	let transfer_encoding := null;
	let charset := null;
	let boundary := null;
	let _owner_message but weak;

	method __build__ () {
		_bytes := to_binary("") if _bytes == null;
		_parts := [] if _parts == null;
		self._refresh_links();
	}

	method _refresh_links () {
		if ( kind eq "multipart" ) {
			for ( let part in _parts ) {
				part._set_container(self);
			}
		}
		else if ( kind eq "nested" and not( _nested == null ) ) {
			_nested._set_container(self);
		}
		return self;
	}

	method _set_owner_message ( owner ) {
		_owner_message := owner but weak;
		return self;
	}

	method owner_message () {
		return _owner_message;
	}

	method is_multipart () {
		return kind eq "multipart";
	}

	method is_nested () {
		return kind eq "nested";
	}

	method bytes () {
		if ( kind ne "bytes" ) {
			die "mail.body: only leaf bodies expose bytes";
		}
		return _bytes;
	}

	method parts () {
		return _copy_array(_parts);
	}

	method part ( Number index ) {
		if ( kind ne "multipart" ) {
			die "mail.body: only multipart bodies expose parts";
		}
		return _parts[index];
	}

	method count () {
		if ( kind eq "multipart" ) {
			return _parts.length();
		}
		return kind eq "nested" ? 1 : 0;
	}

	method nested () {
		return kind eq "nested" ? _nested : null;
	}

	method content_type () {
		return content_type;
	}

	method transfer_encoding () {
		return transfer_encoding == null ? "identity" : lc(transfer_encoding);
	}

	method decoded () {
		if ( kind ne "bytes" ) {
			die "mail.body: multipart/nested decoding is planned for Phase 10";
		}

		let enc := self.transfer_encoding();
		if ( enc eq "base64" ) {
			return _base64_decode( to_string(_bytes) );
		}
		if ( enc eq "quoted-printable" ) {
			return _qp_decode( to_string(_bytes) );
		}
		if ( enc in [ "identity", "7bit", "8bit", "binary" ] ) {
			return _bytes;
		}

		die \`mail.body: unsupported transfer encoding '\${enc}'\`;
	}

	method encoded () {
		if ( kind ne "bytes" ) {
			die "mail.body: multipart/nested encoding is planned for Phase 10";
		}
		return _bytes;
	}

	method to_Dict () {
		if ( kind eq "multipart" ) {
			return {
				kind: kind,
				content_type: content_type,
				transfer_encoding: transfer_encoding,
				charset: charset,
				boundary: boundary,
				parts: _parts.map( fn part -> part.to_Dict() ),
			};
		}
		if ( kind eq "nested" ) {
			return {
				kind: kind,
				content_type: content_type,
				transfer_encoding: transfer_encoding,
				charset: charset,
				message: _nested == null ? null : _nested.to_Dict(),
			};
		}
		return {
			kind: kind,
			content_type: content_type,
			transfer_encoding: transfer_encoding,
			charset: charset,
			bytes: _bytes,
		};
	}

}

class Body extends _BodyBase {
	static method bytes ( BinaryString raw, ... PairList options ) {
		let opts := _body_options(options);
		return new Body(
			kind: "bytes",
			_bytes: raw,
			content_type: opts{content_type},
			transfer_encoding: opts{transfer_encoding},
			charset: opts{charset},
		);
	}

	static method multipart (
		Array parts,
		String boundary,
		... PairList options
	) {
		_assert_no_crlf( boundary, "body" );
		let opts := _body_options(options);
		let ctype := opts{content_type} == null
			? "multipart/mixed"
			: opts{content_type};
		let body := new Body(
			kind: "multipart",
			_parts: _copy_array(parts),
			content_type: ctype,
			transfer_encoding: opts{transfer_encoding},
			charset: opts{charset},
			boundary: boundary,
		);
		return body._refresh_links();
	}

	static method nested ( message, ... PairList options ) {
		let opts := _body_options(options);
		let ctype := opts{content_type} == null
			? "message/rfc822"
			: opts{content_type};
		let body := new Body(
			kind: "nested",
			_nested: message,
			content_type: ctype,
			transfer_encoding: opts{transfer_encoding},
			charset: opts{charset},
		);
		return body._refresh_links();
	}
}

class Message {
	let head := null;
	let body := null;
	let _container but weak;

	method __build__ () {
		head := new Head() if head == null;
		body := Body.bytes( to_binary("") ) if body == null;
		body._set_owner_message(self);
	}

	method _set_container ( container ) {
		_container := container but weak;
		return self;
	}

	method head () {
		return head;
	}

	method body () {
		return body;
	}

	method header ( String name, fallback := null ) {
		return head.get( name, fallback );
	}

	method headers ( String name ) {
		return head.get_all(name);
	}

	method set_header ( String name, String value ) {
		head.set( name, value );
		return self;
	}

	method add_header ( String name, String value ) {
		head.add( name, value );
		return self;
	}

	method remove_header ( String name ) {
		head.remove(name);
		return self;
	}

	method subject () {
		return head.subject();
	}

	method from () {
		return head.from();
	}

	method to () {
		return head.to();
	}

	method cc () {
		return head.cc();
	}

	method bcc () {
		return head.bcc();
	}

	method date () {
		return head.date();
	}

	method message_id () {
		return head.message_id();
	}

	method is_part () {
		return not( _container == null );
	}

	method container () {
		return _container;
	}

	method toplevel () {
		let current := self;
		while ( not( current.container() == null ) ) {
			let owner := current.container().owner_message();
			return current if owner == null;
			current := owner;
		}
		return current;
	}

	method send ( mailer, ... PairList options ) {
		if ( mailer == null or not( mailer can "send" ) ) {
			die "mail.unsupported: Message.send requires a compatible mailer";
		}

		let opts := _mail_send_options(options);
		let envelope_from := opts{envelope_from} == null
			? _mail_send_envelope_from(head)
			: opts{envelope_from};
		let envelope_to := opts{envelope_to} == null
			? _mail_send_envelope_to(head)
			: opts{envelope_to};
		let headers := _mail_send_headers(head);
		let send_body := _mail_send_serialize_body(self);

		return mailer.send(
			envelope_from,
			envelope_to,
			headers,
			send_body,
			opts{send_options},
		);
	}

	method to_Dict () {
		return {
			head: head.to_PairList(),
			body: body.to_Dict(),
			is_part: self.is_part(),
		};
	}
}

class Parser {
	let strict := false;
	let max_header_bytes := 65536;
	let max_depth := 32;
	let decode_transfer := false;
	let _warnings := [];

	method __build__ () {
		if ( not( strict instanceof Boolean ) ) {
			die "mail.parse: strict expects Boolean";
		}
		if ( not( max_header_bytes instanceof Number ) or max_header_bytes < 0 ) {
			die "mail.parse: max_header_bytes expects non-negative Number";
		}
		if ( not( max_depth instanceof Number ) or max_depth < 0 ) {
			die "mail.parse: max_depth expects non-negative Number";
		}
		if ( not( decode_transfer instanceof Boolean ) ) {
			die "mail.parse: decode_transfer expects Boolean";
		}

		_warnings := [];
	}

	method warnings () {
		return _copy_array(_warnings);
	}

	method _warn ( String message ) {
		_warnings.push( "mail.parse: " _ message );
		return self;
	}

	method _fail ( String message ) {
		die "mail.parse: " _ message;
	}

	method _enforce_depth ( Number depth ) {
		if ( depth > max_depth ) {
			self._fail("max_depth exceeded");
		}
	}

	method _parse_head ( Array header_bytes ) {
		let fields := _parse_mail_header_fields(header_bytes);
		return new Head( fields: fields );
	}

	method _header_malformed_message ( BinaryString raw ) {
		self._warn("malformed header section; preserving original bytes");
		return new Message(
			head: new Head(),
			body: Body.bytes(raw),
		);
	}

	method _safe_content_type ( Head head ) {
		try {
			return head.content_type();
		}
		catch {
			if ( strict ) {
				self._fail("malformed Content-Type header");
			}
			self._warn("malformed Content-Type header");
			return null;
		}
	}

	method _safe_charset ( Head head ) {
		try {
			return head.charset();
		}
		catch {
			if ( strict ) {
				self._fail("malformed Content-Type charset");
			}
			self._warn("malformed Content-Type charset");
			return null;
		}
	}

	method _safe_boundary ( Head head ) {
		try {
			return head.boundary();
		}
		catch {
			if ( strict ) {
				self._fail("malformed multipart boundary");
			}
			self._warn("malformed multipart boundary");
			return null;
		}
	}

	method _safe_transfer_encoding ( Head head ) {
		try {
			return head.content_transfer_encoding();
		}
		catch {
			if ( strict ) {
				self._fail("malformed Content-Transfer-Encoding header");
			}
			self._warn("malformed Content-Transfer-Encoding header");
			return null;
		}
	}

	method _leaf_body (
		BinaryString raw,
		content_type,
		transfer_encoding,
		charset
	) {
		return Body.bytes(
			raw,
			content_type: content_type,
			transfer_encoding: transfer_encoding,
			charset: charset,
		);
	}

	method _multipart_body (
		BinaryString raw,
		Array body_bytes,
		String content_type,
		transfer_encoding,
		charset,
		boundary,
		Number depth
	) {
		if ( boundary == null or boundary eq "" or _has_crlf(boundary) ) {
			if ( strict ) {
				self._fail("multipart body missing boundary");
			}
			self._warn("multipart body missing boundary; using leaf body");
			return self._leaf_body( raw, content_type, transfer_encoding, charset );
		}

		let scanned := _scan_multipart_parts( body_bytes, boundary );
		if ( not scanned{opened} ) {
			if ( strict ) {
				self._fail("multipart boundary open delimiter not found");
			}
			self._warn("multipart boundary open delimiter not found; using leaf body");
			return self._leaf_body( raw, content_type, transfer_encoding, charset );
		}

		if ( scanned{preamble_size} > 0 ) {
			self._warn("multipart preamble ignored");
		}
		if ( scanned{epilogue_size} > 0 ) {
			self._warn("multipart epilogue ignored");
		}
		if ( not scanned{closed} ) {
			if ( strict ) {
				self._fail("multipart boundary close delimiter not found");
			}
			self._warn("multipart boundary close delimiter not found");
		}

		let messages := [];
		for ( let part_bytes in scanned{parts} ) {
			messages.push(
				self._parse_message( _bytes_to_binary(part_bytes), depth + 1 ),
			);
		}

		return Body.multipart(
			messages,
			boundary,
			content_type: content_type,
			transfer_encoding: transfer_encoding,
			charset: charset,
		);
	}

	method _nested_body (
		BinaryString raw,
		String content_type,
		transfer_encoding,
		charset,
		Number depth
	) {
		if ( not _is_identity_transfer_encoding(transfer_encoding) ) {
			if ( strict ) {
				self._fail("encoded message/rfc822 bodies are not supported");
			}
			self._warn("encoded message/rfc822 body kept as leaf body");
			return self._leaf_body( raw, content_type, transfer_encoding, charset );
		}

		return Body.nested(
			self._parse_message( raw, depth + 1 ),
			content_type: content_type,
			transfer_encoding: transfer_encoding,
			charset: charset,
		);
	}

	method _parse_message ( BinaryString raw, Number depth ) {
		self._enforce_depth(depth);

		let bytes := _binary_to_bytes(raw);
		let split := _split_message_bytes(bytes);
		if ( split{header_size} > max_header_bytes ) {
			self._fail("max_header_bytes exceeded");
		}

		let head;
		if ( strict ) {
			head := try {
				self._parse_head( split{header_bytes} );
			} catch {
				self._fail("malformed header section");
			};
		}
		else {
			let fallback := null;
			head := try {
				self._parse_head( split{header_bytes} );
			} catch {
				fallback := self._header_malformed_message(raw);
				null;
			};
			return fallback if not( fallback == null );
		}

		let raw_body := _bytes_to_binary( split{body_bytes} );
		let content_type := self._safe_content_type(head);
		let charset := self._safe_charset(head);
		let boundary := self._safe_boundary(head);
		let transfer_encoding := self._safe_transfer_encoding(head);
		let body;

		if ( not( content_type == null ) and index( content_type, "multipart/" ) == 0 ) {
			body := self._multipart_body(
				raw_body,
				split{body_bytes},
				content_type,
				transfer_encoding,
				charset,
				boundary,
				depth,
			);
		}
		else if ( content_type eq "message/rfc822" ) {
			body := self._nested_body(
				raw_body,
				content_type,
				transfer_encoding,
				charset,
				depth,
			);
		}
		else {
			body := self._leaf_body(
				raw_body,
				content_type,
				transfer_encoding,
				charset,
			);
		}

		return new Message( head: head, body: body );
	}

	method parse ( BinaryString bytes ) {
		return self._parse_message( bytes, 0 );
	}
}

function _mail_serialize_fail ( String message ) {
	die "mail.serialize: " _ message;
}

function _mail_serialize_append_text (
	Array out,
	String text,
	String context
) {
	let i := 0;
	let n := length text;

	while ( i < n ) {
		let cp := ord( substr( text, i, 1 ) );
		if ( cp > 255 ) {
			_mail_serialize_fail(
				context _ " contains a character outside byte range",
			);
		}
		out.push(cp);
		i++;
	}

	return out;
}

function _mail_serialize_append_binary ( Array out, BinaryString bytes ) {
	for ( let b in _binary_to_bytes(bytes) ) {
		out.push(b);
	}
	return out;
}

function _mail_serialize_header_words ( String value ) {
	let words := [];
	let i := 0;
	let n := length value;

	while ( i < n ) {
		i := _skip_ws( value, i );
		last if i >= n;

		let start := i;
		while ( i < n and not _is_ws( substr( value, i, 1 ) ) ) {
			i++;
		}
		words.push( substr( value, start, i - start ) );
	}

	return words;
}

function _mail_serialize_folded_header_lines (
	String name,
	String value,
	Number line_length
) {
	let unfolded := name _ ": " _ value;
	return [ unfolded ] if length unfolded <= line_length;

	let words := _mail_serialize_header_words(value);
	return [ unfolded ] if words.length() <= 1;

	let lines := [];
	let first_prefix := name _ ": ";
	let line := first_prefix;

	for ( let word in words ) {
		let separator := ( line eq first_prefix or line eq "\\t" )
			? ""
			: " ";
		let candidate := line _ separator _ word;

		if ( length candidate <= line_length
			or line eq first_prefix
			or line eq "\\t" ) {
			line := candidate;
			next;
		}

		lines.push(line);
		line := "\\t" _ word;
	}

	lines.push(line);
	return lines;
}

function _mail_serialize_quote_boundary ( String boundary ) {
	return _quote_string(boundary);
}

class Serializer {
	let newline := "\\r\\n";
	let fold_headers := true;
	let line_length := 78;
	let generate_boundary := false;
	let _boundary_counter := 0;

	method __build__ () {
		if ( not( newline instanceof String ) ) {
			self._fail("newline expects String");
		}
		if ( newline ne "\\r\\n" and newline ne "\\n" ) {
			self._fail("newline must be CRLF or LF");
		}
		if ( not( fold_headers instanceof Boolean ) ) {
			self._fail("fold_headers expects Boolean");
		}
		if ( not( line_length instanceof Number ) ) {
			self._fail("line_length expects Number");
		}
		if ( line_length < 1 ) {
			self._fail("line_length must be positive");
		}
		if ( not( generate_boundary instanceof Boolean ) ) {
			self._fail("generate_boundary expects Boolean");
		}
		if ( not( _boundary_counter instanceof Number ) or _boundary_counter < 0 ) {
			self._fail("_boundary_counter expects non-negative Number");
		}

		line_length := int(line_length);
		_boundary_counter := int(_boundary_counter);
	}

	method _fail ( String message ) {
		_mail_serialize_fail(message);
	}

	method _reject_method_options ( PairList options ) {
		let items := options.to_Array();
		if ( items.length() > 0 ) {
			self._fail(
				"unsupported method option '" _ items[0].key
					_ "'; use constructor named arguments",
			);
		}
	}

	method _validate_header_pair ( pair ) {
		if ( not( pair.key instanceof String ) or not _valid_header_name(pair.key) ) {
			self._fail("invalid header name");
		}
		if ( not( pair.value instanceof String ) ) {
			self._fail("header value expects String, got " _ typeof pair.value);
		}
		if ( _has_crlf(pair.value) ) {
			self._fail("header value must not contain CR or LF");
		}
	}

	method _append_line ( Array out, String line ) {
		_mail_serialize_append_text( out, line, "header line" );
		_mail_serialize_append_text( out, newline, "newline" );
	}

	method _append_header ( Array out, String name, String value ) {
		let lines := fold_headers
			? _mail_serialize_folded_header_lines(
				name,
				value,
				line_length,
			)
			: [ name _ ": " _ value ];

		for ( let line in lines ) {
			self._append_line( out, line );
		}
	}

	method _generated_boundary () {
		_boundary_counter++;
		return \`zuzu-boundary-\${_boundary_counter}\`;
	}

	method _validate_boundary ( String boundary ) {
		if ( boundary eq "" ) {
			self._fail("multipart body missing boundary");
		}
		if ( _has_crlf(boundary) ) {
			self._fail("multipart boundary must not contain CR or LF");
		}
		return boundary;
	}

	method _header_boundary ( Head head ) {
		let value := head.raw( "Content-Type", null );
		return null if value == null;

		let boundary := null;
		try {
			boundary := _header_parameter( value, "boundary" );
		}
		catch {
			boundary := null;
		}

		return boundary;
	}

	method _body_content_type ( body ) {
		let data := body.to_Dict();
		let content_type := data{content_type};
		return "multipart/mixed" if content_type == null;
		if ( not( content_type instanceof String ) ) {
			self._fail("multipart content_type expects String");
		}
		return content_type;
	}

	method _content_type_with_boundary (
		body,
		String value,
		String boundary
	) {
		let existing := null;
		let main := null;
		try {
			existing := _header_parameter( value, "boundary" );
			main := _header_main_value(value);
		}
		catch {
			existing := null;
			main := null;
		}

		let quoted := _mail_serialize_quote_boundary(boundary);
		if ( not( existing == null ) and existing eq "" ) {
			return self._body_content_type(body) _ "; boundary=" _ quoted;
		}
		if ( existing == null ) {
			if ( main == null or index( main, "multipart/" ) != 0 ) {
				return self._body_content_type(body) _ "; boundary=" _ quoted;
			}
			return value _ "; boundary=" _ quoted;
		}

		return value;
	}

	method _generated_content_type ( body, String boundary ) {
		return self._body_content_type(body)
			_ "; boundary="
			_ _mail_serialize_quote_boundary(boundary);
	}

	method _full_context ( Message message ) {
		let body := message.body();
		let data := body.to_Dict();
		if ( data{kind} ne "multipart" ) {
			return { multipart: false, boundary: null };
		}

		let boundary := data{boundary};
		if ( not( boundary == null ) and not( boundary instanceof String ) ) {
			self._fail("multipart boundary expects String");
		}
		if ( boundary == null or boundary eq "" ) {
			boundary := self._header_boundary( message.head() );
		}
		if ( not( boundary == null ) and not( boundary instanceof String ) ) {
			self._fail("multipart boundary expects String");
		}
		if ( boundary == null or boundary eq "" ) {
			if ( generate_boundary ) {
				boundary := self._generated_boundary();
			}
			else {
				return { multipart: true, boundary: null };
			}
		}

		return {
			multipart: true,
			boundary: self._validate_boundary(boundary),
		};
	}

	method _multipart_boundary ( body, boundary_override := null ) {
		if ( not( boundary_override == null ) ) {
			return self._validate_boundary(boundary_override);
		}

		let data := body.to_Dict();
		let boundary := data{boundary};

		if ( boundary == null or boundary eq "" ) {
			if ( generate_boundary ) {
				return self._generated_boundary();
			}
			self._fail("multipart body missing boundary");
		}
		if ( not( boundary instanceof String ) ) {
			self._fail("multipart boundary expects String");
		}
		return self._validate_boundary(boundary);
	}

	method _serialize_body ( body, boundary_override := null ) {
		let data := body.to_Dict();
		let kind := data{kind};

		if ( kind eq "bytes" ) {
			return body.encoded();
		}
		if ( kind eq "nested" ) {
			let nested := body.nested();
			if ( nested == null ) {
				self._fail("message/rfc822 body missing nested message");
			}
			return self.serialize(nested);
		}
		if ( kind ne "multipart" ) {
			self._fail("unsupported body kind '" _ kind _ "'");
		}

		let boundary := self._multipart_boundary( body, boundary_override );
		let out := [];

		for ( let part in body.parts() ) {
			_mail_serialize_append_text( out, "--" _ boundary, "boundary" );
			_mail_serialize_append_text( out, newline, "newline" );
			_mail_serialize_append_binary( out, self.serialize(part) );
			_mail_serialize_append_text( out, newline, "newline" );
		}

		_mail_serialize_append_text( out, "--" _ boundary _ "--", "boundary" );
		_mail_serialize_append_text( out, newline, "newline" );

		return _bytes_to_binary(out);
	}

	method serialize_body ( Message message, ... PairList options ) {
		self._reject_method_options(options);
		return self._serialize_body( message.body() );
	}

	method serialize ( Message message, ... PairList options ) {
		self._reject_method_options(options);
		let out := [];
		let context := self._full_context(message);
		let saw_content_type := false;

		for ( let pair in message.head().to_PairList().to_Array() ) {
			self._validate_header_pair(pair);
			let value := pair.value;
			if ( context{multipart}
				and lc(pair.key) eq "content-type"
				and not saw_content_type
				and not( context{boundary} == null ) ) {
				value := self._content_type_with_boundary(
					message.body(),
					value,
					context{boundary},
				);
				saw_content_type := true;
			}
			else if ( lc(pair.key) eq "content-type" ) {
				saw_content_type := true;
			}
			self._append_header( out, pair.key, value );
		}

		if ( context{multipart}
			and not saw_content_type
			and not( context{boundary} == null ) ) {
			self._append_header(
				out,
				"Content-Type",
				self._generated_content_type(
					message.body(),
					context{boundary},
				),
			);
		}

		_mail_serialize_append_text( out, newline, "newline" );
		_mail_serialize_append_binary(
			out,
			self._serialize_body( message.body(), context{boundary} ),
		);

		return _bytes_to_binary(out);
	}
}

function _mail_send_serialize_body ( message ) {
	return ( new Serializer() ).serialize_body(message);
}
`;
        virtualFiles["/modules/std/data/xml/escape.zzm"] = `=encoding utf8

=head1 NAME

std/data/xml/escape - XML entity escaping helpers.

=head1 SYNOPSIS

  from std/data/xml/escape import
    escape_xml, unescape_xml;

  let escaped := escape_xml(
    "<tea attr=\\"hot\\">& 'biscuits'</tea>"
  );
  let text := unescape_xml(
    "&lt;tea&gt;&#x41;&#65;&lt;/tea&gt;"
  );

=head1 IMPLEMENTATION SUPPORT

This module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

This module provides lightweight XML entity
escaping and unescaping helpers.

=head1 EXPORTS

=head2 Functions

=over

=item C<< escape_xml(value) >>

Parameters: C<value> is any value. Returns: C<String>. Escapes XML
special characters C<&>, C<< < >>, C<< > >>, C<">, and C<'>.

=item C<< unescape_xml(value) >>

Parameters: C<value> is any value. Returns: C<String>. Unescapes XML
named entities C<&lt;>, C<&gt;>, C<&quot;>, C<&apos;>, and C<&amp;>.

Also decodes numeric entities in decimal and hexadecimal
forms, such as C<&#65;> and C<&#x41;>.

=back

=head1 COPYRIGHT AND LICENCE

B<< std/data/xml/escape >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/string import substr, replace, sprint, index;

function escape_xml ( value ) {
	let out := value \u2261 null ? "" : "" _ value;
	out := replace( out, "&", "&amp;", "g" );
	out := replace( out, "<", "&lt;", "g" );
	out := replace( out, ">", "&gt;", "g" );
	out := replace( out, "\\"", "&quot;", "g" );
	out := replace( out, "'", "&apos;", "g" );
	return out;
}

function _hex_to_number ( String digits ) {
	let out := 0;
	let i := 0;
	let n := length digits;

	while ( i < n ) {
		let ch := substr( digits, i, 1 );
		let val := 0;

		if ( ch ~ /[0-9]/ ) {
			val := 0 + ch;
		}
		else {
			let lower := lc(ch);
			val := 10 + index( "abcdef", lower );
		}

		out := out * 16 + val;
		i++;
	}

	return out;
}

function _decode_numeric_xml_entities ( text ) {
	let out := "";
	let i := 0;
	let n := length text;

	while ( i < n ) {
		let ch := substr( text, i, 1 );
		if ( ch \u2261 "&" and i + 2 < n and substr( text, i, 2 ) \u2261 "&#" ) {
			let j := i + 2;
			let hex := false;

			if ( j < n ) {
				let mark := substr( text, j, 1 );
				if ( mark \u2261 "x" or mark \u2261 "X" ) {
					hex := true;
					j++;
				}
			}

			let digits := "";
			while ( j < n ) {
				let d := substr( text, j, 1 );
				last if d \u2261 ";";

				if ( hex ) {
					last unless d ~ /[0-9A-Fa-f]/;
				}
				else {
					last unless d ~ /[0-9]/;
				}

				digits _= d;
				j++;
			}

			if ( digits \u2262 "" and j < n and substr( text, j, 1 ) \u2261 ";" ) {
				let code := hex
					? _hex_to_number( digits )
					: 0 + digits;
				out _= sprint( "%c", code );
				i := j + 1;
				next;
			}
		}

		out _= ch;
		i++;
	}

	return out;
}

function unescape_xml ( value ) {
	let out := value \u2261 null ? "" : "" _ value;
	out := _decode_numeric_xml_entities( out );
	out := replace( out, "&lt;", "<", "g" );
	out := replace( out, "&gt;", ">", "g" );
	out := replace( out, "&quot;", "\\"", "g" );
	out := replace( out, "&apos;", "'", "g" );
	out := replace( out, "&amp;", "&", "g" );
	return out;
}
`;
        virtualFiles["/modules/std/path/simple.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/simple - Tiny JSONPath/XPath-like traversal helper.\n\n=head1 SYNOPSIS\n\n  from std/path/simple import SimplePath;\n\n  let data := {\n    store: {\n      books: [\n        { author: "Nigel Rees" },\n        { author: "J. R. R. Tolkien" },\n      ],\n    },\n  };\n\n  let p := new SimplePath( path: "store.books[*].author" );\n  for ( let name in p.query(data) ) {\n    say name;\n  }\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nC<SimplePath> implements only a tiny subset of path traversal:\n\n=over\n\n=item * C<.something>\n\nDict/PairList lookup by key.\n\n=item * C<.*>\n\nDict/PairList wildcard that yields all values.\n\n=item * C<[1]>\n\nArray lookup by numeric index.\n\n=item * C<[-1]>\n\nNegative indexes count from the end of arrays.\n\n=item * C<[*]>\n\nArray/Bag/Set wildcard that yields all items.\n\n=back\n\nNo other syntax is supported.\n\nThe public API intentionally mirrors key C<std/path/z> methods:\nC<get>, C<select>, C<query>, C<first>, C<exists>,\nC<expression>, C<assign_first>, C<assign_all>, C<assign_maybe>,\nC<ref_first>, C<ref_all>, and C<ref_maybe>.\n\nThe path operators C<@>, C<@@>, and C<@?> can be set to use this module\nin a lexical scope:\n\n  from std/path/simple import SimplePath;\n  SimplePath.use();\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< SimplePath({ path: String }) >>\n\nConstructs a simple path selector. Returns: C<SimplePath>.\n\n=over\n\n=item C<< SimplePath.use() >>\n\nParameters: none. Returns: C<null>. Makes this path class the lexical\nimplementation for C<@>, C<@@>, and C<@?>.\n\n=item C<< path.expression() >>\n\nParameters: none. Returns: C<String>. Returns the original path\nexpression.\n\n=item C<< path.get(value) >>, C<< path.select(value) >>, C<< path.query(value) >>\n\nParameters: C<value> is the query root. Returns: C<Array>. Evaluates the\npath and returns selected values.\n\n=item C<< path.first(value, fallback) >>\n\nParameters: C<value> is the query root and C<fallback> is returned when\nthere is no match. Returns: value. Returns the first selected value.\n\n=item C<< path.exists(value) >>\n\nParameters: C<value> is the query root. Returns: C<Boolean>. Returns\ntrue when the path selects at least one value.\n\n=item C<< path.assign_first(target, value, op := ":=", weak := false) >>\n\nParameters: C<target> is the query root, C<value> is the assignment\nvalue, C<op> is an assignment operator, and C<weak> is accepted for path\nAPI compatibility. Returns: value. Updates the first selected location.\n\n=item C<< path.assign_all(target, value, op := ":=", weak := false) >>\n\nParameters: same as C<assign_first>. Returns: value. Updates every\nselected location.\n\n=item C<< path.assign_maybe(target, value, op := ":=", weak := false) >>\n\nParameters: same as C<assign_first>. Returns: C<Boolean>. Updates the\nfirst selected location when one exists.\n\n=item C<< path.ref_first(target) >>\n\nParameters: C<target> is the query root. Returns: C<Function>. Returns a\nreference-like getter/setter for the first selected location.\n\n=item C<< path.ref_all(target) >>\n\nParameters: C<target> is the query root. Returns: C<Array>. Returns\nreference-like getter/setters for all selected locations.\n\n=item C<< path.ref_maybe(target) >>\n\nParameters: C<target> is the query root. Returns: C<Function> or\nC<null>. Returns a reference-like getter/setter for the first selected\nlocation when one exists.\n\n=back\n\n=back\n\n=cut\n\nfrom std/string import substr;\n\n\nclass SimplePath {\n	let String path;\n	let Array _steps := [];\n\n	static method use () {\n		from std/internals import setupperprop;\n		setupperprop( 1, "paths", self );\n	}\n\n	method __build__ () {\n		_steps := self._parse(path);\n	}\n\n	method expression () {\n		return path;\n	}\n\n	method _parse ( String raw ) {\n		let text := raw;\n		let steps := [];\n		let i := 0;\n\n		while ( i < length text ) {\n			let ch := substr( text, i, 1 );\n			if ( ch \u2261 "." ) {\n				i++;\n				die "SimplePath parse error: expected name or * after \'.\'"\n					if i >= length text;\n				let after_dot := substr( text, i, 1 );\n				if ( after_dot \u2261 "*" ) {\n					steps.push( { kind: "dict_wildcard" } );\n					i++;\n					next;\n				}\n				let start := i;\n				while ( i < length text ) {\n					let c := substr( text, i, 1 );\n					last if c \u2261 "." or c \u2261 "[" or c \u2261 "]";\n					i++;\n				}\n				let key := substr( text, start, i - start );\n				die "SimplePath parse error: empty key"\n					if key \u2261 "";\n				steps.push( { kind: "key", value: key } );\n				next;\n			}\n\n			if ( ch \u2261 "[" ) {\n				let close := i + 1;\n				while ( close < length text and substr( text, close, 1 ) \u2262 "]" ) {\n					close++;\n				}\n				die "SimplePath parse error: missing closing \']\'"\n					if close >= length text;\n				let inner := substr( text, i + 1, close - i - 1 );\n				if ( inner \u2261 "*" ) {\n					steps.push( { kind: "list_wildcard" } );\n				}\n				else if ( inner ~ /^-?[0-9]+$/ ) {\n					steps.push( { kind: "index", value: int(inner) } );\n				}\n				else {\n					die `SimplePath parse error: unsupported bracket token \'[${inner}]\'`;\n				}\n				i := close + 1;\n				next;\n			}\n\n			let start := i;\n			while ( i < length text ) {\n				let c := substr( text, i, 1 );\n				last if c \u2261 "." or c \u2261 "[" or c \u2261 "]";\n				i++;\n			}\n			let key := substr( text, start, i - start );\n			die `SimplePath parse error: unexpected token \'${ch}\'`\n				if key \u2261 "";\n			steps.push( { kind: "key", value: key } );\n		}\n\n		return steps;\n	}\n\n	method _node ( value, parent, key ) {\n		return {\n			value: value,\n			parent: parent,\n			key: key,\n		};\n	}\n\n	method _evaluate_nodes ( value ) {\n		let current := [ self._node( value, null, null ) ];\n\n		for ( let step in _steps ) {\n			let next_nodes := [];\n\n			for ( let node in current ) {\n				let v := node{value};\n\n				if ( step{kind} \u2261 "key" ) {\n					if ( v instanceof Dict and v.exists( step{value} ) ) {\n						next_nodes.push( self._node( v.get( step{value} ), node, step{value} ) );\n					}\n					else if ( v instanceof PairList ) {\n						for ( let item in v.get_all( step{value} ) ) {\n							next_nodes.push( self._node( item, node, step{value} ) );\n						}\n					}\n					next;\n				}\n\n				if ( step{kind} \u2261 "dict_wildcard" ) {\n					if ( v instanceof Dict ) {\n						for ( let k in v.keys() ) {\n							next_nodes.push( self._node( v.get(k), node, k ) );\n						}\n					}\n					else if ( v instanceof PairList ) {\n						for ( let pair in v.to_Array() ) {\n							next_nodes.push( self._node( pair.value, node, pair.key ) );\n						}\n					}\n					next;\n				}\n\n				if ( step{kind} \u2261 "index" ) {\n					if ( v instanceof Array ) {\n						let idx := step{value};\n						if ( idx < 0 ) {\n							idx := v.length() + idx;\n						}\n						if ( idx >= 0 and idx < v.length() ) {\n							next_nodes.push( self._node( v[idx], node, idx ) );\n						}\n					}\n					next;\n				}\n\n				if ( step{kind} \u2261 "list_wildcard" ) {\n					if ( v instanceof Array ) {\n						let i := 0;\n						while ( i < v.length() ) {\n							next_nodes.push( self._node( v[i], node, i ) );\n							i++;\n						}\n					}\n					else if ( v instanceof Bag or v instanceof Set ) {\n						for ( let item in v.to_Array() ) {\n							next_nodes.push( self._node( item, node, "*" ) );\n						}\n					}\n					next;\n				}\n			}\n\n			current := next_nodes;\n		}\n\n		return current;\n	}\n\n	method _evaluate ( value ) {\n		return self._evaluate_nodes(value).map( fn n -> n{value} );\n	}\n\n	method get ( value ) {\n		return self._evaluate(value);\n	}\n\n	method select ( value ) {\n		return self._evaluate(value);\n	}\n\n	method query ( value ) {\n		return self._evaluate(value);\n	}\n\n	method first ( value, fallback ) {\n		let out := self._evaluate(value);\n		return out.length() = 0 ? fallback : out[0];\n	}\n\n	method exists ( value ) {\n		return self._evaluate(value).length() > 0;\n	}\n\n	method _assign_node ( Dict node, value ) {\n		let parent := node{parent};\n		die "SimplePath assignment target has no parent node"\n			if parent \u2261 null;\n\n		let container := parent{value};\n		let key := node{key};\n\n		if ( container instanceof Array ) {\n			die "SimplePath assignment expects numeric array index"\n				if not( key instanceof Number );\n			container[key] := value;\n			return value;\n		}\n\n		if ( container instanceof Dict ) {\n			die "SimplePath assignment expects string dict key"\n				if not( key instanceof String );\n			container{(key)} := value;\n			return value;\n		}\n\n		if ( container instanceof PairList ) {\n			die "SimplePath assignment expects string pairlist key"\n				if not( key instanceof String );\n			container.set( key, value );\n			return value;\n		}\n\n		die `SimplePath assignment target container \'${typeof container}\' is not assignable`;\n	}\n\n	method _ref_for_node ( Dict node ) {\n		let parent := node{parent};\n		die "SimplePath assignment target has no parent node"\n			if parent \u2261 null;\n\n		let container := parent{value};\n		let key := node{key};\n\n		if ( container instanceof Array ) {\n			die "SimplePath assignment expects numeric array index"\n				if not( key instanceof Number );\n			return \\ container[key];\n		}\n\n		if ( container instanceof Dict ) {\n			die "SimplePath assignment expects string dict key"\n				if not( key instanceof String );\n			return \\ container{(key)};\n		}\n\n		if ( container instanceof PairList ) {\n			die "SimplePath assignment expects string pairlist key"\n				if not( key instanceof String );\n			return \\ container{(key)};\n		}\n\n		die `SimplePath assignment target container \'${typeof container}\' is not assignable`;\n	}\n\n	method _apply_assignment_ref ( ref, value, op := ":=", weak := false ) {\n		die "SimplePath weak assignment is not supported"\n			if weak;\n\n		if ( op \u2261 ":=" ) {\n			return ref(value);\n		}\n\n		let current := ref();\n\n		if ( op \u2261 "+=" ) {\n			current += value;\n		}\n		else if ( op \u2261 "-=" ) {\n			current -= value;\n		}\n		else if ( op \u2261 "*=" or op \u2261 "\xD7=" ) {\n			current *= value;\n		}\n		else if ( op \u2261 "/=" or op \u2261 "\xF7=" ) {\n			current /= value;\n		}\n		else if ( op \u2261 "**=" ) {\n			current **= value;\n		}\n		else if ( op \u2261 "_=" ) {\n			current _= value;\n		}\n		else if ( op \u2261 "?:=" ) {\n			current ?:= value;\n		}\n		else if ( op \u2261 "~=" ) {\n			current ~= value[0] -> value[1](m);\n		}\n		else {\n			die `Unsupported path assignment operator \'${op}\'`;\n		}\n\n		ref(current);\n		return current;\n	}\n\n	method _assign_all_result ( value, op, last_result ) {\n		return op \u2261 "~=" ? last_result : value;\n	}\n\n	method assign_first ( target, value, op := ":=", weak := false ) {\n		let nodes := self._evaluate_nodes(target);\n		die "SimplePath assignment found no matches"\n			if nodes.length() \u2261 0;\n		return self._apply_assignment_ref(\n			self._ref_for_node( nodes[0] ),\n			value,\n			op,\n			weak,\n		);\n	}\n\n	method assign_all ( target, value, op := ":=", weak := false ) {\n		let nodes := self._evaluate_nodes(target);\n		if ( nodes.length() \u2261 0 ) {\n			return self._assign_all_result( value, op, value );\n		}\n\n		let i := 0;\n		let last_result := value;\n		while ( i < nodes.length() ) {\n			last_result := self._apply_assignment_ref(\n				self._ref_for_node( nodes[i] ),\n				value,\n				op,\n				weak,\n			);\n			i++;\n		}\n\n		return self._assign_all_result( value, op, last_result );\n	}\n\n	method assign_maybe ( target, value, op := ":=", weak := false ) {\n		let nodes := self._evaluate_nodes(target);\n		if ( nodes.length() \u2261 0 ) {\n			return false;\n		}\n\n		self._apply_assignment_ref(\n			self._ref_for_node( nodes[0] ),\n			value,\n			op,\n			weak,\n		);\n		return true;\n	}\n\n	method ref_first ( target ) {\n		let nodes := self._evaluate_nodes(target);\n		die "SimplePath assignment found no matches"\n			if nodes.length() \u2261 0;\n		return self._ref_for_node( nodes[0] );\n	}\n\n	method ref_all ( target ) {\n		let nodes := self._evaluate_nodes(target);\n		let out := [];\n		for ( let node in nodes ) {\n			out.push( self._ref_for_node(node) );\n		}\n		return out;\n	}\n\n	method ref_maybe ( target ) {\n		let nodes := self._evaluate_nodes(target);\n		return nodes.length() \u2261 0 ? null : self._ref_for_node( nodes[0] );\n	}\n}\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/simple >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n';
        virtualFiles["/modules/std/path/z.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z - Pure Zuzu implementation of ZPath selectors.\n\n=head1 SYNOPSIS\n\n  from std/path/z import ZPath;\n  from std/time import Time;\n\n  let data := {\n    users: [\n      { name: "Ada", age: 32, updated: new Time() },\n      { name: "Bob", age: 27 },\n    ],\n  };\n\n  let names := query( data, "/users/*/name" );\n  let zp := new ZPath( path: "/users/#0/name" );\n  say( zp.first( data, "n/a" ) );\n  say( exists( data, "/users/#9/name" ) );\n  say( first( data, "/users/#0/updated/@year" ) );\n  say( zp.assign_first( data, "Adele" ) );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nNative (pure-Zuzu) path traversal for structured values.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< ZPath({ path: String, ast? }) >>\n\nConstructs a compiled ZPath selector. Returns: C<ZPath>.\n\n=over\n\n=item C<< ZPath.use() >>\n\nParameters: none. Returns: C<null>. Makes this path class the lexical\nimplementation for C<@>, C<@@>, and C<@?>.\n\n=item C<< path.get_evaluator() >>\n\nParameters: none. Returns: C<Evaluator>. Returns the evaluator used for\nthis path.\n\n=item C<< path.evaluate(raw, meta := {}) >>\n\nParameters: C<raw> is the query root and C<meta> is optional evaluation\nmetadata. Returns: C<Array>. Evaluates the path and returns selected\nnodes.\n\n=item C<< path.get(raw) >>, C<< path.select(raw) >>, C<< path.query(raw) >>\n\nParameters: C<raw> is the query root. Returns: C<Array>. Evaluates the\npath and returns selected primitive values.\n\n=item C<< path.first(raw, fallback?) >>\n\nParameters: C<raw> is the query root and C<fallback> is optional.\nReturns: value. Returns the first selected value or C<fallback>/C<null>.\n\n=item C<< path.exists(raw) >>\n\nParameters: C<raw> is the query root. Returns: C<Boolean>. Returns true\nwhen the path selects at least one value.\n\n=item C<< path.assign_first(raw, value, op := ":=", weak := false) >>\n\nParameters: C<raw> is the query root, C<value> is the assignment value,\nC<op> is an assignment operator, and C<weak> requests weak assignment.\nReturns: value. Updates the first selected node or throws if none match.\n\n=item C<< path.assign_all(raw, value, op := ":=", weak := false) >>\n\nParameters: same as C<assign_first>. Returns: value. Updates every\nselected node.\n\n=item C<< path.assign_maybe(raw, value, op := ":=", weak := false) >>\n\nParameters: same as C<assign_first>. Returns: C<Boolean>. Updates the\nfirst selected node when one exists.\n\n=item C<< path.ref_first(raw) >>\n\nParameters: C<raw> is the query root. Returns: C<Function>. Returns a\nreference-like getter/setter for the first selected node.\n\n=item C<< path.ref_all(raw) >>\n\nParameters: C<raw> is the query root. Returns: C<Array>. Returns\nreference-like getter/setters for all selected nodes.\n\n=item C<< path.ref_maybe(raw) >>\n\nParameters: C<raw> is the query root. Returns: C<Function> or C<null>.\nReturns a reference-like getter/setter for the first selected node when\none exists.\n\n=back\n\n=back\n\n=head1 USE WITH PATH OPERATORS\n\nThe path operators C<@>, C<@@>, and C<@?> can be set to use this module\nin a lexical scope.\n\n  from std/path/z import ZPath;\n\n  function find_usernames (data) {\n    ZPath.use();\n    return data @@ "/users/*/name";\n  }\n\nHowever, for repeatedly used paths it may be more efficient to compile the\npath once and use many times:\n\n  let _usernames_zpath;\n  function find_usernames (data) {\n    from std/path/z import ZPath;\n    _usernames_zpath ?:= new ZPath( path: "/users/*/name" );\n    return data @@ _usernames_zpath;\n  }\n\n=head1 SUPPORTED TYPES\n\n=over\n\n=item B<Null>, B<Boolean>, B<Number>, B<String>, B<BinaryString>, B<Regexp>\n\nTreated as terminal nodes. These objects cannot have child objects.\n\n=item B<Array>\n\nArray items can be indexed by number.\n\n=item B<Bag>, B<Set>\n\nItems cannot be indexed by number, but can be returned by "*".\n\n=item B<Dict>\n\nValues are named by their key.\n\n=item B<PairList>\n\nPairs can be indexed by number, named by their key, or use a combination of\nboth.\n\n  {{ foo: 11, bar: -1, foo: 22, foo: 33 }}\n\nC<< /#2 >> (0-based index) will retrieve C<< foo: 22 >>.\nC<< /foo >> will retrieve C<< foo: 11 >>, C<< foo: 22 >>, and C<< foo: 33 >>.\nC<< /foo#2 >> (0-based index on just values with key "foo") will retrieve C<< foo: 33 >>.\n\nNote that rather than just retrieving the value, a Pair object is retrieved.\nThe selected Pair exposes C<< @key >> and C<< @value >> attributes. Path\nassignment to a selected Pair, or to its C<< @value >> attribute, replaces\nthat pair entry\'s value while preserving pair order and duplicate keys.\n\n=item B<< Pair >>\n\nPair objects do not have child objects but do have C<< @key >> and\nC<< @value >> attributes.\n\n  let pairlist := {{ foo: 11, bar: -1, foo: 22, foo: 33 }};\n  say( first( pairlist, "/#2/@key" ) );     // "foo"\n  say( first( pairlist, "/#2/@value" ) );   // 22\n\n=item B<< Time >>\n\nTime is treated as a terminal node with attributes C<< @year >>,\nC<< @month >>, C<< @day >>, C<< @hour >>, C<< @min >>, and C<< @sec >>.\n\nSee C<< std/time >>.\n\n=item B<< Path >>\n\nPaths representing files are treated as terminal nodes with attributes\ncorresponding to the values from the C<stat> system call: C<< @dev >>,\nC<< @ino >>, C<< @mode >>, C<< @nlink >>, C<< @uid >>, C<< @gid >>,\nC<< @rdev >>, C<< @size >>, C<< @atime >>, C<< @mtime >>, C<< @ctime >>,\nC<< @blksize >>, and C<< @blocks >>.\n\nSee C<< std/io >>.\n\n=item B<< XMLDocument >>, B<< XMLNode >>, etc.\n\nAre treated roughly how the ZPath specification suggests.\n\n  /html/body/table/tbody/tr     // all rows in the tbody\n  /html/body/table/tbody/tr#0   // the first row in the tbody\n  /html/body/table/tbody/#0     // the child element in the tbody\n  /html/body/table[@id]         // all tables that have an id attribute\n\nSee C<< std/data/xml >>.\n\n=back\n\n=head1 SEE ALSO\n\nSpecification: L<https://zpath.me>.\n\nZPath specification: L<https://zpath.me>.\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z/parser import Parser;\nfrom std/path/z/evaluate import Evaluator;\nfrom std/path/z/context import Ctx;\n\nlet _cache;\ndo {\n	from std/cache/lru try import Cache;\n	if ( Cache ) {\n		_cache := new Cache( capacity: 16 );\n	}\n};\n\nclass ZPath {\n	let String path;\n	let ast;\n	let ev;\n\n	static method use () {\n		from std/internals import setupperprop;\n		setupperprop( 1, "paths", self );\n	}\n\n	method __build__ () {\n		ev := self.get_evaluator;\n		const p := new Parser( allowed_operators: ev.operator_definitions() );\n		ast ?:= _cache\n			? _cache.get( path, fn x \u2192 p.parse_top_level_terms(x) )\n			: p.parse_top_level_terms(path);\n	}\n\n	method get_evaluator () {\n		return new Evaluator();\n	}\n\n	method evaluate ( raw, meta := {} ) {\n\n		meta.set( "level", 0 ) unless meta.defined( "level" );\n		const ctx := new Ctx(\n			root: raw,\n			nodeset: meta.get( "nodeset", null ),\n			parentset: meta.get( "parentset", null ),\n			meta: meta,\n		);\n\n		const short_circuit := ( meta.get( "want", "all" ) in [ "first", "exists" ] );\n\n		let results := [];\n		for ( let term in ast ) {\n			for ( let node in ev.eval_expr( term, ctx ) ) {\n				let next_node := ev.maybe_apply_action( node, ctx );\n				results.push(next_node);\n				return results if short_circuit;\n			}\n		}\n\n		return results;\n	}\n\n	method get ( raw ) {\n		return self.evaluate(raw).map( fn r \u2192 r.primitive_value );\n	}\n\n	method select ( raw ) {\n		return self.evaluate(raw).map( fn r \u2192 r.primitive_value );\n	}\n\n	method query ( raw ) {\n		return self.evaluate(raw).map( fn r \u2192 r.primitive_value );\n	}\n\n	method first ( raw, fallback? ) {\n		let got := self.evaluate( raw, { want: "first" } );\n		return got.empty ? fallback : got[0].primitive_value;\n	}\n\n	method exists ( raw ) {\n		let got := self.evaluate( raw, { want: "exists" } );\n		return not got.empty;\n	}\n\n	method _apply_assignment_ref ( ref, value, op := ":=", weak := false ) {\n		if ( op \u2261 ":=" ) {\n			return weak ? ref( value, true ) : ref(value);\n		}\n\n		let current := ref();\n\n		if ( op \u2261 "+=" ) {\n			current += value;\n		}\n		else if ( op \u2261 "-=" ) {\n			current -= value;\n		}\n		else if ( op \u2261 "*=" or op \u2261 "\xD7=" ) {\n			current *= value;\n		}\n		else if ( op \u2261 "/=" or op \u2261 "\xF7=" ) {\n			current /= value;\n		}\n		else if ( op \u2261 "**=" ) {\n			current **= value;\n		}\n		else if ( op \u2261 "_=" ) {\n			current _= value;\n		}\n		else if ( op \u2261 "?:=" ) {\n			current ?:= value;\n		}\n		else if ( op \u2261 "~=" ) {\n			current ~= value[0] -> value[1](m);\n		}\n		else {\n			die `Unsupported path assignment operator \'${op}\'`;\n		}\n\n		ref(current);\n		return current;\n	}\n\n	method _assign_all_result ( value, op, last_result ) {\n		return op \u2261 "~=" ? last_result : value;\n	}\n\n	method assign_first ( raw, value, op := ":=", weak := false ) {\n		let got := self.evaluate( raw, { want: "first" } );\n		die "Path assignment (@) found no matches" if got.empty;\n		return self._apply_assignment_ref(\n			got[0].ref(),\n			value,\n			op,\n			weak,\n		);\n	}\n\n	method assign_all ( raw, value, op := ":=", weak := false ) {\n		let got := self.evaluate(raw);\n		if ( got.empty ) {\n			return self._assign_all_result( value, op, value );\n		}\n\n		let last_result := value;\n		for ( let node in got ) {\n			last_result := self._apply_assignment_ref(\n				node.ref(),\n				value,\n				op,\n				weak,\n			);\n		}\n\n		return self._assign_all_result( value, op, last_result );\n	}\n\n	method assign_maybe ( raw, value, op := ":=", weak := false ) {\n		let got := self.evaluate( raw, { want: "first" } );\n		if ( got.empty ) {\n			return false;\n		}\n\n		self._apply_assignment_ref( got[0].ref(), value, op, weak );\n		return true;\n	}\n\n	method ref_first ( raw ) {\n		let got := self.evaluate( raw, { want: "first" } );\n		die "Path assignment (@) found no matches" if got.empty;\n		return got[0].ref();\n	}\n\n	method ref_all ( raw ) {\n		return self.evaluate(raw).map( fn n \u2192 n.ref );\n	}\n\n	method ref_maybe ( raw ) {\n		let got := self.evaluate( raw, { want: "first" } );\n		return got.empty ? null : got[0].ref();\n	}\n}\n';
        virtualFiles["/modules/std/path/z/context.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/context - Evaluation context used by std/path/z.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides the pure-Zuzu evaluation context used by ZPath.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< Ctx({ root, nodeset?, parentset?, meta? }) >>\n\nConstructs a ZPath evaluation context. Returns: C<Ctx>. Wraps C<root>\nas a C<std/path/z/node> C<Node> and stores the active node sets.\n\n=over\n\n=item C<< ctx.with_nodeset(ns, ps) >>\n\nParameters: C<ns> is the next node set and C<ps> is the parent set.\nReturns: C<Ctx>. Returns a copy of the context with different node\nsets.\n\n=item C<< ctx.nested(extras?) >>\n\nParameters: C<extras> is optional metadata. Returns: C<Ctx>. Returns a\nnested context with incremented metadata level.\n\n=item C<< ctx.root() >>\n\nParameters: none. Returns: C<Node>. Returns the root node.\n\n=item C<< ctx.nodeset() >>\n\nParameters: none. Returns: C<Array>. Returns the current node set.\n\n=item C<< ctx.parentset() >>\n\nParameters: none. Returns: C<Array> or C<null>. Returns the parent node\nset.\n\n=item C<< ctx.meta() >>\n\nParameters: none. Returns: C<Dict>. Returns context metadata.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/context >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z/node import Node;\n\nclass Ctx {\n	let root := null;\n	let nodeset := null;\n	let parentset := null;\n	let meta := null;\n\n	method __build__ () {\n		if ( not ( root instanceof Node ) ) {\n			let root_obj := root;\n			let node_type := null;\n\n			try {\n				node_type := int( "" _ root_obj.nodeType() );\n			}\n			catch {\n			}\n\n			let xml_document := node_type = 9;\n			if ( not xml_document and root_obj can documentElement ) {\n				try {\n					root_obj.documentElement();\n					xml_document := true;\n				}\n				catch {\n				}\n			}\n\n			if ( xml_document ) {\n				try {\n					let de := root_obj.documentElement();\n					root_obj := de if de \u2262 null;\n				}\n				catch {\n				}\n			}\n\n			root := Node.wrap( root_obj );\n		}\n\n		nodeset ?:= [ root ];\n		meta ?:= { level: 0 };\n	}\n\n	method with_nodeset ( ns, ps ) {\n		return new Ctx(\n			root: root,\n			nodeset: ns,\n			parentset: ps,\n			meta: meta,\n		);\n	}\n\n	method nested ( extras? ) {\n		let extra_meta := extras ?: {};\n\n		let next_meta := {\n			level: meta.get( "level", 0 ) + 1,\n		};\n\n		for ( let pair in extra_meta.enumerate ) {\n			next_meta.add( pair );\n		}\n\n		return new Ctx(\n			root: root,\n			nodeset: nodeset,\n			parentset: parentset,\n			meta: next_meta,\n		);\n	}\n\n	method root () { return root; }\n	method nodeset () { return nodeset; }\n	method parentset () { return parentset; }\n	method meta () { return meta; }\n}\n';
        virtualFiles["/modules/std/path/z/evaluate.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/evaluate - Pure Zuzu evaluator for ZPath expressions.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides the pure-Zuzu evaluator used by ZPath.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<Evaluator>\n\nPure-Zuzu evaluator for parsed ZPath AST values.\n\n=over\n\n=item C<< evaluator.operator_definitions() >>\n\nParameters: none. Returns: C<Array>. Returns the active operator\ndefinition table.\n\n=item C<< evaluator.function_definitions() >>\n\nParameters: none. Returns: C<Array>. Returns the active function\ndefinition table.\n\n=item C<< evaluator.eval_expr_wrap(ast, ctx) >>\n\nParameters: C<ast> is an AST node and C<ctx> is a C<Ctx>. Returns:\nC<Array>. Evaluates with optional debug dumping.\n\n=item C<< evaluator.eval_expr(ast, ctx) >>\n\nParameters: C<ast> is an AST node and C<ctx> is a C<Ctx>. Returns:\nC<Array>. Evaluates an expression to a node set.\n\n=item C<< evaluator.nested_ctx(ctx, ... PairList extras) >>\n\nParameters: C<ctx> is a C<Ctx> or C<null> and C<extras> are metadata.\nReturns: C<Ctx> or C<null>. Creates a nested evaluation context.\n\n=item C<< evaluator.eval_binop(ast, ctx) >>, C<< evaluator.eval_unop(ast, ctx) >>\n\nParameters: C<ast> is an operator AST node and C<ctx> is a C<Ctx>.\nReturns: C<Array>. Evaluates a binary or unary operator.\n\n=item C<< evaluator.eval_path(path_ast, ctx) >>\n\nParameters: C<path_ast> is a path AST node and C<ctx> is a C<Ctx>.\nReturns: C<Array>. Evaluates a path expression to selected nodes.\n\n=item C<< evaluator.maybe_apply_action(node, ctx) >>\n\nParameters: C<node> is a C<Node> and C<ctx> is a C<Ctx>. Returns:\nC<Node>. Applies any pending path action.\n\n=item C<< evaluator.eval_fn(fn_ast, ctx) >>\n\nParameters: C<fn_ast> is a function-call AST node and C<ctx> is a\nC<Ctx>. Returns: C<Array>. Evaluates a ZPath function call.\n\n=item C<< evaluator.string_replace(string, pattern, replacement) >>\n\nParameters: all arguments are strings or regex-like values. Returns:\nC<String>. Applies ZPath string replacement.\n\n=item C<< evaluator.dedup_nodes(nodes) >>\n\nParameters: C<nodes> is an array of nodes. Returns: C<Array>. Removes\nduplicate nodes while preserving order.\n\n=item C<< evaluator.truthy(n) >>\n\nParameters: C<n> is a node or value. Returns: C<Boolean>. Applies ZPath\ntruthiness.\n\n=item C<< evaluator.to_number(n) >>, C<< evaluator.to_string(n) >>\n\nParameters: C<n> is a node or value. Returns: C<Number> or C<String>.\nCoerces a ZPath value.\n\n=item C<< evaluator.equals(a, b) >>\n\nParameters: C<a> and C<b> are nodes or values. Returns: C<Boolean>.\nCompares two ZPath values.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/evaluate >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import replace, index, substr;\nfrom std/path/z/node import Node;\nfrom std/path/z/functions import STANDARD_FUNCTIONS;\nfrom std/path/z/operators import STANDARD_OPERATORS;\n\nlet _do_dump := false;\n\nclass Evaluator {\n	let _operator_definitions;\n	let _function_definitions;\n\n	let \u03B5 := 0.000000001;\n\n	method operator_definitions () {\n		_operator_definitions ?:= STANDARD_OPERATORS;\n		return _operator_definitions;\n	}\n\n	method function_definitions () {\n		_function_definitions ?:= STANDARD_FUNCTIONS;\n		return _function_definitions;\n	}\n\n	method eval_expr_wrap ( ast, ctx ) {\n		from std/dump import Dumper;\n		let got := self._real_eval_expr ( ast, ctx );\n		say `AST ${Dumper.dump(ast)} CTX ${Dumper.dump(ctx)} \u21D2 GOT ${Dumper.dump(got)}` if _do_dump;\n		return got;\n	}\n\n	method eval_expr ( ast, ctx ) {\n\n		switch ( ast{t} : eq ) {\n			case "num":\n				return [ Node.wrap( ast{v} ) ];\n			case "str":\n				return [ Node.wrap( ast{v} ) ];\n			case "path":\n				return self.eval_path( ast, ctx );\n			case "fn":\n				return self.eval_fn( ast, ctx );\n			case "un":\n				return self.eval_unop( ast, ctx );\n			case "bin":\n				return self.eval_binop( ast, ctx );\n			case "ternary":\n				let c  := self.eval_expr( ast{c}, ctx );\n				let ab := self.truthy( c.get(0) ) ? "a" : "b";\n				return self.eval_expr( ast{(ab)}, ctx );\n			case "elvis":\n				let left := self.eval_expr( ast{c}, ctx );\n				return left if self.truthy( left.get(0) );\n				return self.eval_expr( ast{b}, ctx );\n			default:\n				die "Panic! Unknown AST node type!";\n		}\n	}\n\n	method nested_ctx ( ctx, ... PairList extras ) {\n		return null if ctx \u2261 null;\n		return ctx.nested( extras );\n	}\n\n	method _hold_parent ( node, parent ) {\n		if ( node \u2262 null and parent \u2262 null ) {\n			node.hold_parent(parent);\n		}\n		return node;\n	}\n\n	method _children ( node ) {\n		let out := [];\n		for ( let child in node.children() ) {\n			out.push( self._hold_parent( child, node ) );\n		}\n		return out;\n	}\n\n	method _attributes ( node ) {\n		let out := [];\n		for ( let attr in node.attributes() ) {\n			out.push( self._hold_parent( attr, node ) );\n		}\n		return out;\n	}\n\n	method _indexed_child ( node, i ) {\n		return self._hold_parent( node.indexed_child(i), node );\n	}\n\n	method _named_child ( node, name ) {\n		return self._hold_parent( node.named_child(name), node );\n	}\n\n	method _named_indexed_child ( node, name, i ) {\n		return self._hold_parent( node.named_indexed_child( name, i ), node );\n	}\n\n	method eval_binop ( ast, ctx ) {\n		const op := ast{op};\n		const op_def := self.operator_definitions().first(\n			fn x \u2192 x.get_spelling eq op and x.is_binary()\n		);\n		if ( op_def and op_def{f} ) {\n			const implementation := op_def{f};\n			return implementation( op_def, self, ast, ctx, ast{l}, ast{r} );\n		}\n		return [];\n	}\n\n	method eval_unop ( ast, ctx ) {\n		const op := ast{op};\n		const op_def := self.operator_definitions().first(\n			fn x \u2192 x.get_spelling eq op and x.is_unary()\n		);\n		if ( op_def and op_def{f} ) {\n			const implementation := op_def{f};\n			return implementation( op_def, self, ast, ctx, ast{e} );\n		}\n		return [];\n	}\n\n	method eval_path ( path_ast, ctx ) {\n		let current := [];\n		for ( let n in ctx.nodeset() ) {\n			current.push(n);\n		}\n\n		let parentset := ctx.parentset();\n\n		for ( let seg in path_ast{s} ) {\n			let next_nodes := [];\n\n			if ( seg{k} \u2261 "root" ) {\n				next_nodes := [ ctx.root() ];\n			}\n			else if ( seg{k} \u2261 "dot" ) {\n				next_nodes := current;\n			}\n			else if ( seg{k} \u2261 "parent" ) {\n				for ( let n in current ) {\n					let p := n.parent();\n					if ( p \u2262 null ) {\n						next_nodes.push(p);\n					}\n				}\n				next_nodes := self.dedup_nodes(next_nodes);\n			}\n			else if ( seg{k} \u2261 "ancestors" ) {\n				let anc := [];\n				for ( let n in current ) {\n					let p := n.parent();\n					while ( p \u2262 null ) {\n						anc.push(p);\n						p := p.parent();\n					}\n				}\n				next_nodes := self.dedup_nodes(anc);\n			}\n			else if ( seg{k} \u2261 "star" ) {\n				let kids := [];\n				for ( let n in current ) {\n					for ( let child in self._children(n) ) {\n						if ( child.type() \u2262 "attr" ) {\n							kids.push(child);\n						}\n					}\n				}\n				next_nodes := self.dedup_nodes(kids);\n			}\n			else if ( seg{k} \u2261 "desc" ) {\n				let acc := [];\n				let stack := [];\n				for ( let n in current ) {\n					stack.push(n);\n				}\n\n				while ( stack.length() > 0 ) {\n					let n := stack.shift();\n					acc.push(n);\n					for ( let child in self._children(n) ) {\n						if ( child.type() \u2262 "attr" ) {\n							stack.push(child);\n						}\n					}\n				}\n				next_nodes := self.dedup_nodes(acc);\n			}\n			else if ( seg{k} \u2261 "index" ) {\n				let idx := seg{i};\n				let kids := [];\n				for ( let n in current ) {\n					let c := self._indexed_child( n, idx );\n					kids.push(c) if c \u2262 null;\n				}\n				next_nodes := self.dedup_nodes(kids);\n			}\n			else if ( seg{k} \u2261 "fnseg" ) {\n				let out := [];\n				for ( let n in current ) {\n					let seg_ctx := ctx.with_nodeset( [ n ], current );\n					let fn_ast := { t: "fn", n: seg{n}, a: seg{a} };\n					let res := self.eval_fn( fn_ast, seg_ctx );\n					for ( let x in res ) {\n						out.push(x);\n					}\n				}\n				next_nodes := out;\n			}\n			else if ( seg{k} \u2261 "name" ) {\n				let name := seg{n};\n\n				if ( name ~ /^\\@/ ) {\n					if ( name \u2261 "@*" ) {\n						let attrs := [];\n						for ( let n in current ) {\n							for ( let a in self._attributes(n) ) {\n								attrs.push(a);\n							}\n						}\n						next_nodes := self.dedup_nodes(attrs);\n					}\n					else {\n						let attrs := [];\n						for ( let n in current ) {\n							for ( let a in self._attributes(n) ) {\n								if ( a.name() \u2261 name ) {\n									attrs.push(a);\n								}\n							}\n						}\n						next_nodes := self.dedup_nodes(attrs);\n					}\n				}\n				else {\n					let kids := [];\n					for ( let n in current ) {\n						if ( n.can_have_named_indexed_children() ) {\n							let idx := 0;\n							while ( true ) {\n								let c := self._named_indexed_child( n, name, idx );\n								last if c \u2261 null;\n								kids.push(c);\n								idx++;\n							}\n						}\n						else {\n							let c := self._named_child( n, name );\n							kids.push(c) if c \u2262 null;\n						}\n					}\n					next_nodes := self.dedup_nodes(kids);\n				}\n\n				if ( seg.exists("i") and seg{i} \u2262 null ) {\n					let idx := seg{i};\n					let picked := [];\n					for ( let n in current ) {\n						let c := self._named_indexed_child( n, name, idx );\n						picked.push(c) if c \u2262 null;\n					}\n					next_nodes := self.dedup_nodes(picked);\n				}\n			}\n			else {\n				die "Unknown path segment kind: " _ seg{k};\n			}\n\n			if ( seg.exists("q") and seg{q}.length() > 0 ) {\n				for ( let q in seg{q} ) {\n					if ( q.exists("t") and q{t} \u2261 "num" and q{v} ~ /^\\d+$/ ) {\n						let idx := 0 + q{v};\n\n						if ( next_nodes.length() > 0 and self._node_is_xml(next_nodes[0]) ) {\n							next_nodes := ( idx \u2265 0 and idx < next_nodes.length() ) ? [ next_nodes[idx] ] : [];\n						}\n						else {\n							let picked := [];\n							for ( let node in next_nodes ) {\n								let ch := self._children(node)\n									.grep( fn c \u2192 c.type() \u2262 "attr" );\n								if ( idx \u2265 0 and idx < ch.length() ) {\n									picked.push( ch[idx] );\n								}\n							}\n							next_nodes := picked;\n						}\n\n						next;\n					}\n\n					let filtered := [];\n					let i := 0;\n					while ( i < next_nodes.length() ) {\n						let node := next_nodes[i];\n						let ns_ctx := ctx.with_nodeset( next_nodes, current );\n						let filter_ctx := ns_ctx.with_nodeset( [ node ], next_nodes );\n						let r := self.eval_expr( q, self.nested_ctx( filter_ctx, want: "exists" ) );\n\n						let ok := false;\n						if ( q.exists("t") and q{t} \u2261 "path" ) {\n							ok := r.length() > 0;\n						}\n						else {\n							ok := self.truthy( r.length() > 0 ? r[0] : null );\n						}\n\n						if ( ok ) {\n							filtered.push(node);\n						}\n						i++;\n					}\n					next_nodes := filtered;\n				}\n			}\n\n			parentset := current;\n			current := next_nodes;\n		}\n\n		return current;\n	}\n\n	method maybe_apply_action ( node, ctx ) {\n		const meta := ctx.meta();\n		return node if not meta.exists( "action" );\n		const action := meta{action};\n		return node if action \u2261 null;\n		return node if not action.exists( "op" );\n		node.do_action(action);\n		return node;\n	}\n\n	method eval_fn ( fn_ast, ctx ) {\n		const name := fn_ast{n};\n		const fn_def := self.function_definitions().first( fn f \u2192 f.has_name(name) );\n		return fn_def{f}( fn_def, self, fn_ast, ctx, fn_ast{a} ?: [] ) if fn_def;\n		return [];\n	}\n\n	method string_replace ( string, pattern, replacement ) {\n		let text := string \u2261 null ? "" : "" _ string;\n		let rep := replacement \u2261 null ? "" : "" _ replacement;\n\n		try {\n			return replace( text, pattern, rep, "g" );\n		}\n		catch {\n			return replace( text, "" _ pattern, rep, "g" );\n		}\n	}\n\n	method dedup_nodes ( nodes ) {\n		let seen := {};\n		let out := [];\n		for ( let n in nodes ) {\n			let key := n.id ?: ( "anon:" _ out.length() _ ":" _ ( "" _ n.raw() ) );\n			if ( not seen.exists(key) ) {\n				seen.set( key, true );\n				out.push(n);\n			}\n		}\n		return out;\n	}\n\n	method truthy ( n ) {\n		return false if n \u2261 null;\n		let pv := n.primitive_value();\n		return pv ? true : false;\n	}\n\n	method to_number ( n ) {\n		return null if n \u2261 null;\n		return n.number_value();\n	}\n\n	method to_string ( n ) {\n		return null if n \u2261 null;\n		return n.string_value();\n	}\n\n	method equals ( a, b ) {\n		return false if a \u2261 null or b \u2261 null;\n\n		let a_type := a.type();\n		let b_type := b.type();\n\n		if ( b_type eq "null" ) {\n			return a_type eq "null";\n		}\n		if ( a_type eq "null" ) {\n			return b_type eq "null";\n		}\n\n		if ( a_type eq "boolean" and b_type eq "boolean" ) {\n			let av := a.primitive_value() ? true : false;\n			let bv := b.primitive_value() ? true : false;\n			return av \u2261 bv;\n		}\n\n		if ( a_type \u2261 "number" and b_type \u2261 "number" ) {\n			let av := a.number_value();\n			let bv := b.number_value();\n			return false if av \u2261 null or bv \u2261 null;\n\n			if ( ( "" _ av ) ~ /\\./ or ( "" _ bv ) ~ /\\./ ) {\n				return abs( av - bv ) < \u03B5;\n			}\n\n			return av = bv;\n		}\n\n		let string_like := [ "string", "text", "attr", "comment", "element" ];\n		if ( a_type in string_like and b_type in string_like ) {\n			let av := a.string_value();\n			let bv := b.string_value();\n			return av eq bv;\n		}\n\n		let aid := a.id();\n		let bid := b.id();\n		return false if aid \u2261 null or bid \u2261 null;\n		return aid eq bid;\n	}\n\n	method _node_is_xml ( n ) {\n		if ( n \u2261 null ) {\n			return false;\n		}\n		let raw := n.raw();\n		try {\n			let node_type := raw.nodeType();\n			return node_type \u2262 null;\n		}\n		catch {\n			return false;\n		}\n	}\n}\n';
        virtualFiles["/modules/std/path/z/functions.zzm"] = `=encoding utf8

=head1 NAME

std/path/z/functions - Function definitions for ZPath.

=head1 IMPLEMENTATION SUPPORT

This module is supported by all implementations of ZuzuScript.

=head1 DESCRIPTION

This module defines the function objects and standard function table used
by C<std/path/z>.

=head1 EXPORTS

=head2 Classes

=over

=item C<< Func({ spelling: String, f: Function }) >>

Constructs a ZPath function definition. Returns: C<Func>.

=over

=item C<< func.has_name(n) >>

Parameters: C<n> is a function name. Returns: C<Boolean>. Returns true
when C<n> matches the function spelling.

=back

=back

=head2 Functions

=over

=item C<< replace(haystack, needle, replacement) >>

Parameters: C<haystack> is source text, C<needle> is a pattern, and
C<replacement> is replacement text. Returns: C<String>. Performs ZPath
replacement with capture substitutions.

=item C<< mk_single_number_function(String name, Function impl) >>

Parameters: C<name> is a ZPath function name and C<impl> maps one
number. Returns: C<Function>. Builds a function wrapper for per-node
numeric functions.

=item C<< mk_aggregate_number_function(String name, Function impl) >>

Parameters: C<name> is a ZPath function name and C<impl> maps an array
of numbers. Returns: C<Function>. Builds a function wrapper for
aggregate numeric functions.

=item C<< mk_single_string_function(String name, Function impl) >>

Parameters: C<name> is a ZPath function name and C<impl> maps one
string. Returns: C<Function>. Builds a function wrapper for per-node
string functions.

=item C<< mk_match_function() >>

Parameters: none. Returns: C<Function>. Builds the standard ZPath
C<match> function implementation.

=back

=head2 Constants

=over

=item C<STANDARD_FUNCTIONS>

Type: C<Array>. Standard ZPath function definitions.

=back

=head1 COPYRIGHT AND LICENCE

B<< std/path/z/functions >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/path/z/node import KDLNodeNode, KDLValueNode, Node, XmlNodeNode;
from std/path/z/operators import EvalHelpers;
from std/data/xml/escape import escape_xml, unescape_xml;
from std/string import index, rindex, search, sprint, substr, join;
from std/math import Math;


class Func with EvalHelpers {
	let String spelling with get;
	let Function f;

	method has_name ( n ) {
		return true if self.get_spelling eq n;
		return false;
	}
}

function replace ( haystack, needle, replacement ) {
	let copy := haystack;

	if ( replacement ~ /\\$[0-9]/ ) {
		let r := replacement;
		copy ~= needle \u2192 do {
			let matches := m;
			r ~= /\\$([0-9]+)/g \u2192 matches[ m[1] ];
			r;
		};
	}
	else {
		copy ~= needle \u2192 replacement;
	}

	return copy;
}

function mk_single_number_function ( String name, Function impl ) {
	return function ( funk, ev, ast, ctx, args ) {
		let nodes := [];
		for ( let a in args ) {
			const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
			for ( let n in got ) {
				nodes.push( n );
			}
		}
		else {
			nodes := ctx.nodeset;
		}
		return nodes
			.map( fn x \u2192 x.number_value )
			.grep( fn x \u2192 x instanceof Number )
			.map( fn x \u2192 funk.wrap_for_array( impl(x) ) );
	};
}

function mk_aggregate_number_function ( String name, Function impl ) {
	return function ( funk, ev, ast, ctx, args ) {
		let nodes := [];
		for ( let a in args ) {
			const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
			for ( let n in got ) {
				nodes.push( n );
			}
		}
		else {
			nodes := ctx.nodeset;
		}
		const nums := nodes
			.map( fn x \u2192 x.number_value )
			.grep( fn x \u2192 x instanceof Number );
		return funk.wrap( impl( nums ) );
	};
}

function mk_single_string_function ( String name, Function impl ) {
	return function ( funk, ev, ast, ctx, args ) {
		let nodes := [];
		for ( let a in args ) {
			const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
			for ( let n in got ) {
				nodes.push( n );
			}
		}
		else {
			nodes := ctx.nodeset;
		}
		return nodes
			.map( fn x \u2192 x.string_value )
			.grep( fn x \u2192 x instanceof String )
			.map( fn x \u2192 funk.wrap_for_array( impl(x) ) );
	};
}

function mk_match_function () {
	return function ( funk, ev, ast, ctx, args ) {
		let nodes := [];
		let re;

		if ( args.empty ) {
			die "Not enough arguments for match()";
		}
		else {
			re := try {
				ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
			} catch {
				"";
			};
		}

		for ( let a in args[1:] ) {
			const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
			for ( let n in got ) {
				nodes.push( n );
			}
		}
		else {
			nodes := ctx.nodeset;
		}

		return nodes
			.map( fn x \u2192 x.string_value )
			.grep( fn x \u2192 x instanceof String )
			.map( fn x \u2192 funk.wrap_for_array( ( x ~ re ) ? true : false ) );
	}
}

const STANDARD_FUNCTIONS := [
	new Func(
		spelling: "true",
		f: function ( funk, ev, ast, ctx, args ) {
			die "Too many arguments for true()" unless args.empty;
			return funk.wrap( true );
		},
	),

	new Func(
		spelling: "false",
		f: function ( funk, ev, ast, ctx, args ) {
			die "Too many arguments for false()" unless args.empty;
			return funk.wrap( false );
		},
	),

	new Func(
		spelling: "null",
		f: function ( funk, ev, ast, ctx, args ) {
			die "Too many arguments for null()" unless args.empty;
			return funk.wrap( null );
		},
	),

	new Func(
		spelling: "die",
		f: function ( funk, ev, ast, ctx, args ) {
			die "Called 'die' function in zpath";
		},
	),

	new Func(
		spelling: "count",
		f: function ( funk, ev, ast, ctx, args ) {
			let n := 0;
			for ( let a in args ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				n += got.length;
			}
			else {
				const cur := ctx.parentset ?: ctx.nodeset;
				n := cur.length;
			}
			return funk.wrap( n );
		},
	),

	new Func(
		spelling: "index",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return funk.wrap( cur ? cur.ix : null );
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
				return got.map( fn x \u2192 funk.wrap_for_array(x.ix) );
			}
			die "Too many arguments for index()";
		},
	),

	new Func(
		spelling: "key",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return funk.wrap( cur ? cur.key : null );
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
				return got.map(
					fn x \u2192 funk.wrap_for_array(
						x \u2261 null ? null : x.key
					)
				);
			}
			die "Too many arguments for key()";
		},
	),

	new Func(
		spelling: "type",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return funk.wrap( cur ? cur.type : "undefined" );
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) ).get( 0, null );
				return funk.wrap( got ? got.type : "undefined" );
			}
			die "Too many arguments for type()";
		},
	),

	new Func(
		spelling: "union",
		f: function ( funk, ev, ast, ctx, args ) {
			let out := [];
			for ( let arg in args ) {
				const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					out.push( n );
				}
			}
			return ev.dedup_nodes( out );
		},
	),

	new Func(
		spelling: "intersection",
		f: function ( funk, ev, ast, ctx, args ) {
			return [] if args.empty;

			let out := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
			out := ev.dedup_nodes( out );

			let i := 1;
			while ( i < args.length() ) {
				let got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );
				got := ev.dedup_nodes( got );

				let seen := {};
				for ( let n in got ) {
					let key := n.id();
					if ( key \u2261 null ) {
						key := "anon:" _ ( "" _ n.raw() );
					}
					seen.set( key, true );
				}

				let next_out := [];
				for ( let n in out ) {
					let key := n.id();
					if ( key \u2261 null ) {
						key := "anon:" _ ( "" _ n.raw() );
					}
					if ( seen.exists(key) ) {
						next_out.push(n);
					}
				}

				out := next_out;
				last if out.empty;
				i++;
			}

			return ev.dedup_nodes( out );
		},
	),

	new Func(
		spelling: "is-first",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur and cur.parent;
				return funk.wrap( cur.ix = 0 );
			}
			die "Too many arguments for is-first()";
		},
	),

	new Func(
		spelling: "is-last",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur and cur.parent and cur.ix \u2262 null;
				const siblings := cur.parent.children
					.grep( fn kid \u2192 kid.key \u2261 cur.key );
				return [] if siblings.empty;
				let pos := 0;
				while ( pos < siblings.length ) {
					const kid := siblings[pos];
					last if kid.id() \u2261 cur.id();
					pos++;
				}
				return [] if pos \u2265 siblings.length;
				return funk.wrap( pos = siblings.length - 1 );
			}
			die "Too many arguments for is-last()";
		},
	),

	new Func(
		spelling: "next",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [ cur.next_sibling ];
			}
			else {
				let out := [];
				for ( let arg in args ) {
					const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
					for ( let n in got ) {
						out.push( n.next_sibling );
					}
				}
				return out;
			}
		},
	),

	new Func(
		spelling: "prev",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [ cur.prev_sibling ];
			}
			else {
				let out := [];
				for ( let arg in args ) {
					const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
					for ( let n in got ) {
						out.push( n.prev_sibling );
					}
				}
				return out;
			}
		},
	),

	new Func(
		spelling: "string",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				return funk.wrap( cur.string_value );
			}
			else {
				let out := [];
				for ( let arg in args ) {
					const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
					for ( let n in got ) {
						out.push( n );
					}
				}
				return out.map( fn x \u2192 funk.wrap_for_array( x.string_value ) );
			}
		},
	),

	new Func(
		spelling: "number",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				return funk.wrap( cur.number_value );
			}
			else {
				let out := [];
				for ( let arg in args ) {
					const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
					for ( let n in got ) {
						out.push( n );
					}
				}
				return out.map( fn x \u2192 funk.wrap_for_array( x.number_value ) );
			}
		},
	),

	new Func(
		spelling: "value",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				return funk.wrap( cur.primitive_value );
			}
			else {
				let out := [];
				for ( let arg in args ) {
					const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );
					for ( let n in got ) {
						out.push( n );
					}
				}
				return out.map( fn x \u2192 funk.wrap_for_array( x.primitive_value ) );
			}
		},
	),

	new Func(
		spelling: "ceil",
		f: mk_single_number_function( "ceil", fn n \u2192 ceil n ),
	),

	new Func(
		spelling: "floor",
		f: mk_single_number_function( "floor", fn n \u2192 floor n ),
	),

	new Func(
		spelling: "round",
		f: mk_single_number_function( "round", fn n \u2192 round n ),
	),

	new Func(
		spelling: "sum",
		f: mk_aggregate_number_function( "sum", fn nums \u2192 Math.sum(nums) ),
	),

	new Func(
		spelling: "min",
		f: mk_aggregate_number_function( "min", fn nums \u2192 Math.min(nums) ),
	),

	new Func(
		spelling: "max",
		f: mk_aggregate_number_function( "max", fn nums \u2192 Math.max(nums) ),
	),

	new Func(
		spelling: "escape",
		f: mk_single_string_function( "escape", fn s \u2192 escape_xml(s) ),
	),

	new Func(
		spelling: "unescape",
		f: mk_single_string_function( "unescape", fn s \u2192 unescape_xml(s) ),
	),

	new Func(
		spelling: "upper-case",
		f: mk_single_string_function( "upper-case", fn s \u2192 uc s ),
	),

	new Func(
		spelling: "lower-case",
		f: mk_single_string_function( "lower-case", fn s \u2192 lc s ),
	),

	new Func(
		spelling: "index-of",
		f: function ( funk, ev, ast, ctx, args ) {
			let nodes := [];
			let search;

			if ( args.empty ) {
				die "Not enough arguments for index-of()";
			}
			else {
				search := try {
					ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
			}

			for ( let a in args[1:] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			return nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String )
				.map( fn x \u2192 funk.wrap_for_array( index(x, search) ) );
		}
	),

	new Func(
		spelling: "last-index-of",
		f: function ( funk, ev, ast, ctx, args ) {
			let nodes := [];
			let search;

			if ( args.empty ) {
				die "Not enough arguments for last-index-of()";
			}
			else {
				search := try {
					ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
			}

			for ( let a in args[1:] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			return nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String )
				.map( fn x \u2192 funk.wrap_for_array( rindex(x, search) ) );
		}
	),

	new Func(
		spelling: "substring",
		f: function ( funk, ev, ast, ctx, args ) {

			let nodes := [];
			let start;
			let len;

			if ( args.length < 2 ) {
				die "Not enough arguments for substring()";
			}
			else {
				start := try {
					ev.eval_expr( args[-2], ev.nested_ctx( ctx ) )[0].number_value;
				} catch {
					0;
				};
				len := try {
					ev.eval_expr( args[-1], ev.nested_ctx( ctx ) )[0].number_value;
				} catch {
					0;
				};
			}

			for ( let a in args[0:-2] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			return nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String )
				.map( fn x \u2192 funk.wrap_for_array( substr(x, start, len) ) );
		}
	),

	new Func(
		spelling: "format",
		f: function ( funk, ev, ast, ctx, args ) {
			let nodes := [];
			let fmt;

			if ( args.empty ) {
				die "Not enough arguments for format()";
			}
			else {
				fmt := try {
					ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
			}

			for ( let a in args[1:] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			return nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String )
				.map( fn x \u2192 funk.wrap_for_array( sprint(fmt, x) ) );
		}
	),

	new Func(
		spelling: "string-length",
		f: mk_single_string_function( "string-length", fn s \u2192 length s ),
	),

	new Func(
		spelling: "match",
		f: mk_match_function(),
	),

	new Func(
		spelling: "matches",
		f: mk_match_function(),
	),

	new Func(
		spelling: "replace",
		f: function ( funk, ev, ast, ctx, args ) {
			let nodes := [];
			let pattern;
			let replacement;

			if ( args.length < 2 ) {
				die "Not enough arguments for replace()";
			}
			else {
				pattern := try {
					ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
				replacement := try {
					ev.eval_expr( args[1], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
			}

			for ( let a in args[2:] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			return nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String )
				.map( fn x \u2192 funk.wrap_for_array( replace( x, pattern, replacement ) ) );
		}
	),

	new Func(
		spelling: "join",
		f: function ( funk, ev, ast, ctx, args ) {
			let nodes := [];
			let joiner;

			if ( args.empty ) {
				die "Not enough arguments for format()";
			}
			else {
				joiner := try {
					ev.eval_expr( args[0], ev.nested_ctx( ctx ) )[0].string_value;
				} catch {
					"";
				};
			}

			for ( let a in args[1:] ) {
				const got := ev.eval_expr( a, ev.nested_ctx( ctx ) );
				for ( let n in got ) {
					nodes.push( n );
				}
			}
			else {
				nodes := ctx.nodeset;
			}

			const strings := nodes
				.map( fn x \u2192 x.string_value )
				.grep( fn x \u2192 x instanceof String );
			return funk.wrap( join( joiner, strings ) );
		}
	),

	new Func(
		spelling: "url",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				return funk.wrap( cur instanceof XmlNodeNode ? cur.raw.namespaceURI() : null );
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
				return got.map(
					fn x \u2192 funk.wrap_for_array(
						x instanceof XmlNodeNode ? x.raw.namespaceURI() : null
					)
				);
			}
			die "Too many arguments for url()";
		},
	),

	new Func(
		spelling: "local-name",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				return funk.wrap(
					cur instanceof XmlNodeNode ? cur.raw.localName()
						: cur instanceof KDLNodeNode ? cur.name()
						: null
				);
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
				return got.map(
					fn x \u2192 funk.wrap_for_array(
						x instanceof XmlNodeNode ? x.raw.localName()
							: x instanceof KDLNodeNode ? x.name()
							: null
					)
				);
			}
			die "Too many arguments for local-name()";
		},
	),

	new Func(
		spelling: "tag",
		f: function ( funk, ev, ast, ctx, args ) {
			if ( args.length = 0 ) {
				const cur := ctx.nodeset.get( 0, null );
				return [] unless cur;
				if ( cur instanceof KDLNodeNode ) {
					let ann := cur.raw().type_annotation();
					return funk.wrap( ann \u2261 null ? null : "" _ ann );
				}
				if ( cur instanceof KDLValueNode ) {
					let ann := cur.raw().type_annotation();
					return funk.wrap( ann \u2261 null ? null : "" _ ann );
				}
				return funk.wrap( cur.has_tagged ? cur.tagged{tag} : null );
			}
			else if ( args.length = 1 ) {
				const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );
				return got.map(
					fn x \u2192 funk.wrap_for_array(
						x instanceof KDLNodeNode
							? (
								x.raw().type_annotation() \u2261 null
									? null
									: "" _ x.raw().type_annotation()
							)
							: x instanceof KDLValueNode
							? (
								x.raw().type_annotation() \u2261 null
									? null
									: "" _ x.raw().type_annotation()
							)
							: x can has_tagged ? x.tagged{tag} : null
					)
				);
			}
			die "Too many arguments for tag()";
		},
	),
];
`;
        virtualFiles["/modules/std/path/z/lexer.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/lexer - Pure Zuzu lexer for ZPath expressions.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides the pure-Zuzu lexer used by ZPath.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< Lexer({ src: String, allowed_operators: Array }) >>\n\nConstructs a ZPath lexer. Returns: C<Lexer>. Tokenizes C<src> using the\nallowed operator table.\n\n=over\n\n=item C<< lexer.peek() >>\n\nParameters: none. Returns: C<Dict>. Returns the current token without\nadvancing.\n\n=item C<< lexer.peek_n(n) >>\n\nParameters: C<n> is a zero-based lookahead offset. Returns: C<Dict>.\nReturns a token ahead of the current position.\n\n=item C<< lexer.peek_kind() >>\n\nParameters: none. Returns: C<String>. Returns the current token kind.\n\n=item C<< lexer.peek_kind_n(n) >>\n\nParameters: C<n> is a zero-based lookahead offset. Returns: C<String>.\nReturns a token kind ahead of the current position.\n\n=item C<< lexer.next_tok() >>\n\nParameters: none. Returns: C<Dict>. Consumes and returns the current\ntoken.\n\n=item C<< lexer.expect(k) >>\n\nParameters: C<k> is the expected token kind. Returns: C<Dict>. Consumes\nand returns the current token, throwing when it has a different kind.\n\n=item C<< lexer.known_operators() >>\n\nParameters: none. Returns: C<Array>. Returns the allowed operator\ndefinitions.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/lexer >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import substr;\n\nclass Lexer {\n	let src := "";\n	let scan_i := 0;\n	let toks := [];\n	let pos := 0;\n	let allowed_operators;\n\n	method __build__ () {\n		die "Expected some operators" unless allowed_operators;\n		toks := self._tokenize(src);\n	}\n\n	method peek () {\n		return toks[pos];\n	}\n\n	method peek_n ( n ) {\n		return toks[pos + n];\n	}\n\n	method peek_kind () {\n		return toks[pos]{k};\n	}\n\n	method peek_kind_n ( n ) {\n		return toks[pos + n]{k};\n	}\n\n	method next_tok () {\n		let tok := toks[pos];\n		pos++;\n		return tok;\n	}\n\n	method expect ( k ) {\n		let t := self.next_tok();\n		die `Expected ${k}, got ${t{k}}` if t{k} \u2262 k;\n		return t;\n	}\n\n	method _is_ws ( c ) {\n		return c \u2262 null and c ~ /\\s/;\n	}\n\n	method _prev_sig ( chars, idx ) {\n		let j := idx - 1;\n		while ( j >= 0 ) {\n			if ( chars[j] ~ /\\s/ ) {\n				j--;\n				next;\n			}\n			return chars[j];\n		}\n		return null;\n	}\n\n	method _next_sig ( chars, idx, n ) {\n		let j := idx + 1;\n		while ( j < n ) {\n			if ( chars[j] ~ /\\s/ ) {\n				j++;\n				next;\n			}\n			return chars[j];\n		}\n		return null;\n	}\n\n	method _is_path_ctx_prev ( c ) {\n		return c \u2261 "[" or c \u2261 "(" or c \u2261 "," or c \u2261 ":" or c \u2261 "?" or c \u2261 "/";\n	}\n\n	method _is_path_ctx_next ( c ) {\n		return c \u2261 "]" or c \u2261 ")" or c \u2261 "," or c \u2261 ":" or c \u2261 "?" or c \u2261 "/";\n	}\n\n	method _ws_on_both ( left, right ) {\n		return self._is_ws(left) and self._is_ws(right);\n	}\n\n	method known_operators () {\n		return allowed_operators;\n	}\n\n	method _sorted_operators () {\n		return self.known_operators()\n			.grep( fn o \u2192 not o.lexer_should_ignore )\n			.sort( fn ( x, y ) \u2192 y.char_length <=> x.char_length );\n	}\n\n	method _operator_at ( chars, i, n, ops ) {\n		let oi := 0;\n		while ( oi < ops.length ) {\n			let op := ops[oi];\n			let spell := op{spelling};\n			let m := length spell;\n			if ( i + m <= n ) {\n				let got := "";\n				let j := 0;\n				while ( j < m ) {\n					got _= chars[i + j];\n					j++;\n				}\n				if ( got \u2261 spell ) {\n					return op;\n				}\n			}\n			oi++;\n		}\n		return null;\n	}\n\n	method _is_name_char ( c ) {\n		return c ~ /[A-Za-z0-9_\\-]/;\n	}\n\n	method _allows_operator_kind ( kind ) {\n		return allowed_operators.first( fn op \u2192 op.get_kind() \u2261 kind )\n			? true\n			: false;\n	}\n\n	method _tokenize ( String source ) {\n		let t := [];\n		let chars := [];\n		let n := length source;\n		let ops := self._sorted_operators();\n		let z := 0;\n		while ( z < n ) {\n			chars.push( substr( source, z, 1 ) );\n			z++;\n		}\n\n		let i := 0;\n		while ( i < n ) {\n			let ch := chars[i];\n\n			if ( ch ~ /\\s/ ) {\n				i++;\n				next;\n			}\n\n			let prev := i > 0 ? chars[i - 1] : null;\n			let nxt := i + 1 < n ? chars[i + 1] : null;\n\n			let prev_nonws := self._prev_sig( chars, i );\n			let next_nonws := self._next_sig( chars, i, n );\n\n			function push_token ( tok ) {\n				tok{ws_before} := self._is_ws(prev) ? true : false;\n				tok{ws_after}  := self._is_ws(nxt)  ? true : false;\n				t.push( tok );\n			}\n\n			function push_sized_token ( tok, after ) {\n				tok{ws_before} := self._is_ws(prev) ? true : false;\n				tok{ws_after}  := self._is_ws(after) ? true : false;\n				t.push( tok );\n			}\n\n			if ( ch \u2261 "/" ) {\n				if (\n					self._ws_on_both( prev, nxt )\n					and prev_nonws \u2262 null and next_nonws \u2262 null\n					and not self._is_path_ctx_prev(prev_nonws)\n					and not self._is_path_ctx_next(next_nonws)\n				) {\n					push_token( { k: "SLASH", v: "/" } );\n					i++;\n					next;\n				}\n				if (\n					( self._is_ws(prev) xor self._is_ws(nxt) )\n					and prev_nonws \u2262 null and next_nonws \u2262 null\n					and not self._is_path_ctx_prev(prev_nonws)\n					and not self._is_path_ctx_next(next_nonws)\n				) {\n					die `Binary operator \'/\' requires whitespace around it`;\n				}\n				t.push( { k: "SLASH_PATH", v: "/" } );\n				i++;\n				next;\n			}\n\n			let op := self._operator_at( chars, i, n, ops );\n			if ( op \u2262 null ) {\n				let spell := op.get_spelling();\n				let need_ws := op.requires_whitespace();\n				let m := length spell;\n				let op_prev := i > 0 ? chars[i - 1] : null;\n				let op_next := i + m < n ? chars[i + m] : null;\n				let path_ambiguous_star :=\n					( spell \u2261 "*" or spell \u2261 "**" )\n					and not self._ws_on_both( op_prev, op_next );\n\n				let left_name := false;\n				let right_name := false;\n				if ( spell ~ /^[A-Za-z_]/ ) {\n					left_name := op_prev \u2262 null and self._is_name_char(op_prev);\n					right_name := op_next \u2262 null and self._is_name_char(op_next);\n				}\n\n				if (\n					not path_ambiguous_star\n					and not left_name\n					and not right_name\n				) {\n					if ( need_ws ) {\n						if ( self._ws_on_both( op_prev, op_next ) ) {\n							push_sized_token( { k: op.get_kind(), v: spell }, op_next );\n							i := i + m;\n							next;\n						}\n						die `Binary operator \'${spell}\' requires whitespace around it`;\n					}\n					push_sized_token( { k: op.get_kind(), v: spell }, op_next );\n					i := i + m;\n					next;\n				}\n			}\n\n			if ( ch \u2261 "(" ) { t.push( { k: "LPAREN", v: "(" } ); i++; next; }\n			if ( ch \u2261 ")" ) { t.push( { k: "RPAREN", v: ")" } ); i++; next; }\n			if ( ch \u2261 "[" ) { t.push( { k: "LBRACK", v: "[" } ); i++; next; }\n			if ( ch \u2261 "]" ) { t.push( { k: "RBRACK", v: "]" } ); i++; next; }\n			if ( ch \u2261 "," ) { t.push( { k: "COMMA", v: "," } ); i++; next; }\n\n			if ( ch \u2261 "." ) {\n				if ( i + 2 < n and chars[i + 1] \u2261 "." and chars[i + 2] \u2261 "*" ) {\n					push_token( { k: "DOTDOTSTAR", v: "..*" } );\n					i := i + 3;\n					next;\n				}\n				if ( i + 1 < n and chars[i + 1] \u2261 "." ) {\n					push_token( { k: "DOTDOT", v: ".." } );\n					i := i + 2;\n					next;\n				}\n				push_token( { k: "DOT", v: "." } );\n				i++;\n				next;\n			}\n\n			if ( ch \u2261 "*" and self._ws_on_both( prev, nxt ) ) {\n				push_token( { k: "STAR", v: "*" } );\n				i++;\n				next;\n			}\n\n			if ( ch \u2261 "*" ) {\n				if ( i + 1 < n and chars[i + 1] \u2261 "*" ) {\n					push_token( { k: "STARSTAR", v: "**" } );\n					i := i + 2;\n					next;\n				}\n				push_token( { k: "STAR_PATH", v: "*" } );\n				i++;\n				next;\n			}\n\n			if ( self._allows_operator_kind( "ELVIS" ) and ch \u2261 "?" and nxt \u2261 ":" ) {\n				let op_next := i + 2 < n ? chars[i + 2] : null;\n				if ( self._ws_on_both( prev, op_next ) ) {\n					t.push( {\n						k: "ELVIS",\n						v: "?:",\n						ws_before: self._is_ws(prev) ? true : false,\n						ws_after: self._is_ws(op_next) ? true : false,\n					} );\n					i := i + 2;\n					next;\n				}\n				die "Elvis operator \'?:\' requires whitespace around it";\n			}\n\n			if ( ch \u2261 "?" or ch \u2261 ":" ) {\n				if ( self._ws_on_both( prev, nxt ) ) {\n					push_token( { k: ch \u2261 "?" ? "QMARK" : "COLON", v: ch } );\n					i++;\n					next;\n				}\n				die `Ternary operator \'${ch}\' requires whitespace around it`;\n			}\n\n			if ( ch \u2261 "\\"" or ch \u2261 "\'" ) {\n				let quote := ch;\n				i++;\n				let s := "";\n				let esc := false;\n				while ( i < n ) {\n					let cc := chars[i];\n					i++;\n					if ( esc ) {\n						if ( cc \u2261 "\\\\" or cc \u2261 quote or cc \u2261 "\\"" or cc \u2261 "\'" ) {\n							s _= cc;\n						}\n						else {\n							s _= self._unescape_char(cc);\n						}\n						esc := false;\n						next;\n					}\n					if ( cc \u2261 "\\\\" ) { esc := true; next; }\n					last if cc \u2261 quote;\n					s _= cc;\n				}\n				push_token( { k: "STRING", v: s, q: quote } );\n				next;\n			}\n\n			if ( ch \u2261 "#" ) {\n				let j := i + 1;\n				let neg := false;\n				if ( j < n and chars[j] \u2261 "-" ) {\n					neg := true;\n					j++;\n				}\n				die "Invalid index \'#\'" if j >= n or not( chars[j] ~ /\\d/ );\n				let num := "";\n				while ( j < n and chars[j] ~ /\\d/ ) {\n					num _= chars[j];\n					j++;\n				}\n				let parsed := 0 + num;\n				parsed := 0 - parsed if neg;\n				push_token( { k: "INDEX", v: parsed } );\n				i := j;\n				next;\n			}\n\n			if ( ch ~ /[0-9]/ ) {\n				let j := i;\n				let num := "";\n				while ( j < n and chars[j] ~ /[0-9.]/ ) {\n					num _= chars[j];\n					j++;\n				}\n				push_token( { k: "NUMBER", v: 0 + num } );\n				i := j;\n				next;\n			}\n\n			let name := self._read_name( chars, i );\n			if ( name{v} \u2262 "" ) {\n				push_token( { k: "NAME", v: name{v} } );\n				i := name{i};\n				next;\n			}\n\n			die `Unexpected character \'${ch}\' at position ${i}`;\n		}\n\n		t.push( { k: "EOF", v: "" } );\n		return t;\n	}\n\n	method _unescape_char ( c ) {\n		return "\\n" if c \u2261 "n";\n		return "\\r" if c \u2261 "r";\n		return "\\t" if c \u2261 "t";\n		return c;\n	}\n\n	method _read_name ( chars, start_i ) {\n		let n := chars.length();\n		let delim := {\n			"\\n": true,\n			"\\r": true,\n			"\\t": true,\n			"(": true,\n			")": true,\n			"[": true,\n			"]": true,\n			"/": true,\n			",": true,\n			"=": true,\n			"&": true,\n			"|": true,\n			"!": true,\n			"<": true,\n			">": true,\n			"#": true,\n			" ": true,\n		};\n		let buf := "";\n		let esc := false;\n		let i := start_i;\n\n		while ( i < n ) {\n			let c := chars[i];\n			if ( esc ) {\n				buf _= c;\n				esc := false;\n				i++;\n				next;\n			}\n\n			if ( c \u2261 "\\\\" ) {\n				esc := true;\n				i++;\n				next;\n			}\n\n			last if delim.exists(c);\n			last if c ~ /\\s/;\n			buf _= c;\n			i++;\n		}\n\n		return { v: "", i: start_i } if buf \u2261 "";\n		return { v: buf, i: i };\n	}\n}\n';
        virtualFiles["/modules/std/path/z/node.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/node - Node wrapper used by std/path/z.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nObjects of this class wrap underlying values and provide traversal and\ncoercion helpers used while evaluating ZPath expressions.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<Node>\n\nBase wrapper for values traversed by ZPath.\n\n=over\n\n=item C<< Node.from_root(obj) >>\n\nParameters: C<obj> is any query root. Returns: C<Node>. Wraps a root\nvalue for traversal.\n\n=item C<< Node.wrap(obj, parent?, key?, ix?) >>\n\nParameters: C<obj> is any value, with optional parent, key, and index\nmetadata. Returns: C<Node>. Wraps a value in the appropriate node\nsubclass.\n\n=item C<< node.hold_parent(owner) >>\n\nParameters: C<owner> is a parent node. Returns: C<Node>. Retains parent\nmetadata on the node.\n\n=item C<< node.raw() >>, C<< node.value() >>, C<< node.primitive_value() >>\n\nParameters: none. Returns: value. Returns the wrapped raw, node, or\nprimitive value.\n\n=item C<< node.parent() >>\n\nParameters: none. Returns: C<Node> or C<null>. Returns the parent node.\n\n=item C<< node.key() >>, C<< node.ix() >>, C<< node.index() >>, C<< node.id() >>\n\nParameters: none. Returns: value. Returns traversal key, index, or\nstable node id metadata.\n\n=item C<< node.type() >>, C<< node.name() >>\n\nParameters: none. Returns: C<String> or C<null>. Returns the node type\nor name.\n\n=item C<< node.tagged() >>\n\nParameters: none. Returns: C<String> or C<null>. Returns a KDL value\ntag when present.\n\n=item C<< node.has_tagged() >>\n\nParameters: none. Returns: C<Boolean>. Returns true when tag metadata is\navailable.\n\n=item C<< node.string_value() >>, C<< node.number_value() >>\n\nParameters: none. Returns: C<String>, C<Number>, or C<null>. Coerces the\nnode for string or numeric ZPath operations.\n\n=item C<< node.can_have_named_children() >>, C<< node.can_have_indexed_children() >>, C<< node.can_have_named_indexed_children() >>\n\nParameters: none. Returns: C<Boolean>. Reports supported child lookup\nmodes.\n\n=item C<< node.named_child(name) >>, C<< node.indexed_child(i) >>, C<< node.named_indexed_child(name, i) >>\n\nParameters: C<name> is a child name and C<i> is an index. Returns:\nC<Node> or C<null>. Looks up child nodes.\n\n=item C<< node.next_child(child) >>, C<< node.prev_child(child) >>, C<< node.next_sibling() >>, C<< node.prev_sibling() >>\n\nParameters: C<child> is a child node where required. Returns: C<Node> or\nC<null>. Traverses adjacent nodes.\n\n=item C<< node.named_attribute(name) >>\n\nParameters: C<name> is an attribute name. Returns: C<Node> or C<null>.\nLooks up one attribute node.\n\n=item C<< node.children() >>, C<< node.attributes() >>\n\nParameters: none. Returns: C<Array>. Returns child or attribute nodes.\n\n=item C<< node.dump() >>\n\nParameters: none. Returns: C<String>. Returns a diagnostic rendering of\nthe node.\n\n=item C<< node.find(zpath) >>\n\nParameters: C<zpath> is a C<ZPath> object or subclass, such as C<ZZPath>.\nReturns: C<Array>. Evaluates a nested path from this node and returns\nselected node objects.\n\n=item C<< node.do_action(action) >>, C<< node.do_action_on_child(child, action) >>\n\nParameters: C<action> is a path action and C<child> is a child node.\nReturns: value. Applies path mutation actions.\n\n=item C<< node.ref() >>, C<< node.ref_on_child(child) >>\n\nParameters: C<child> is a child node where required. Returns:\nC<Function>. Returns a reference-like getter/setter.\n\n=back\n\n=item C<SimpleNode>, C<StringNode>, C<NumberNode>, C<BooleanNode>, C<NullNode>\n\nScalar node wrappers. They inherit the C<Node> API and override\nC<type>, C<string_value>, or C<number_value> where appropriate.\n\n=item C<ArrayNode>, C<SetNode>, C<BagNode>, C<DictNode>, C<PairListNode>, C<PairNode>\n\nCollection node wrappers. They inherit the C<Node> API and override\nchild, attribute, assignment, and reference methods appropriate to their\ncollection type. PairList children are C<PairNode> objects in pair order;\nC<indexed_child> uses global pair index, while C<named_indexed_child> uses\nthe occurrence index among pairs with the same key.\n\n=item C<KDLDocumentNode>, C<KDLNodeNode>, C<KDLValueNode>\n\nKDL node wrappers. They inherit the C<Node> API and expose KDL children,\nattributes, names, value tags, and scalar coercions.\n\n=item C<XmlNodeNode>\n\nXML node wrapper. It inherits the C<Node> API and exposes XML names,\nchildren, attributes, sibling traversal, and scalar text values.\n\n=item C<TimeNode>\n\nC<std/time> wrapper. It inherits the C<Node> API and exposes time\nattributes plus string and numeric values.\n\n=item C<PathNode>\n\nC<std/io> path wrapper. It inherits the C<Node> API and exposes path\nattributes plus string values.\n\n=item C<WidgetNode>\n\nC<std/gui/objects> widget wrapper. It inherits the C<Node> API and\nexposes widget children by widget class name and index, plus public\nwidget properties as assignable attributes.\n\n=back\n\n=head2 Variables\n\n=over\n\n=item C<determine_class>\n\nType: C<Function>. Chooses the concrete node wrapper class for a raw\nvalue.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/node >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/data/cbor import TaggedValue;\nfrom std/data/kdl import KDLDocument, KDLNode, KDLValue;\nfrom std/internals import class_name, load_module, ref_id;\nfrom std/io try import Path;\nfrom std/math import Math;\nfrom std/string import substr;\nfrom std/time import Time;\n\n\nfunction determine_class;\nlet _widget_class_loaded := false;\nlet _widget_class := null;\n\nconst _WIDGET_ATTRS := [\n	{ name: "id", getter: "id", setter: "set_id" },\n	{ name: "enabled", getter: "enabled", setter: "set_enabled" },\n	{ name: "visible", getter: "visible", setter: "set_visible" },\n	{ name: "width", getter: "width", accessor: true },\n	{ name: "height", getter: "height", accessor: true },\n	{ name: "minwidth", getter: "minwidth", accessor: true },\n	{ name: "minheight", getter: "minheight", accessor: true },\n	{ name: "maxwidth", getter: "maxwidth", accessor: true },\n	{ name: "maxheight", getter: "maxheight", accessor: true },\n	{ name: "classes", getter: "classes" },\n	{ name: "title", getter: "title", setter: "set_title", accessor: true },\n	{ name: "text", getter: "text", setter: "set_text", accessor: true },\n	{ name: "value", getter: "value", setter: "set_value", accessor: true },\n	{ name: "placeholder", getter: "placeholder", setter: "set_placeholder", accessor: true },\n	{ name: "for", getter: "for_id", setter: "set_for_id", accessor: true },\n	{ name: "align", getter: "align", accessor: true },\n	{ name: "gap", getter: "gap", accessor: true },\n	{ name: "padding", getter: "padding", accessor: true },\n	{ name: "label", getter: "label", accessor: true },\n	{ name: "collapsible", getter: "collapsible", accessor: true },\n	{ name: "collapsed", getter: "collapsed", accessor: true },\n	{ name: "wrap", getter: "wrap", accessor: true },\n	{ name: "readonly", getter: "readonly", accessor: true },\n	{ name: "multiline", getter: "multiline", accessor: true },\n	{ name: "password", getter: "password", accessor: true },\n	{ name: "required", getter: "required", accessor: true },\n	{ name: "src", getter: "src", accessor: true },\n	{ name: "alt", getter: "alt", accessor: true },\n	{ name: "fit", getter: "fit", accessor: true },\n	{ name: "checked", getter: "checked", accessor: true },\n	{ name: "indeterminate", getter: "indeterminate", accessor: true },\n	{ name: "name", getter: "name", accessor: true },\n	{ name: "disabled", getter: "disabled", accessor: true },\n	{ name: "group", getter: "group", accessor: true },\n	{ name: "multiple", getter: "multiple", accessor: true },\n	{ name: "min", getter: "min", accessor: true },\n	{ name: "max", getter: "max", accessor: true },\n	{ name: "first_day_of_week", getter: "first_day_of_week", accessor: true },\n	{ name: "orientation", getter: "orientation", accessor: true },\n	{ name: "step", getter: "step", accessor: true },\n	{ name: "show_text", getter: "show_text", accessor: true },\n	{ name: "selected", getter: "selected", accessor: true },\n	{ name: "placement", getter: "placement", accessor: true },\n	{ name: "icon", getter: "icon", setter: "set_icon", accessor: true },\n	{ name: "closable", getter: "closable", accessor: true },\n	{ name: "selected_index", getter: "selected_index", accessor: true },\n	{ name: "selected_path", getter: "selected_path", accessor: true },\n	{ name: "variant", getter: "variant", accessor: true },\n];\n\nfunction _zpath_widget_class () {\n	if ( not _widget_class_loaded ) {\n		_widget_class_loaded := true;\n		try {\n			_widget_class := load_module( "std/gui/objects", "Widget" );\n		}\n		catch {\n			_widget_class := null;\n		}\n	}\n	return _widget_class;\n}\n\nfunction _zpath_is_widget ( obj ) {\n	let Widget := _zpath_widget_class();\n	return Widget \u2262 null and obj instanceof Widget;\n}\n\nfunction _zpath_xml_node_type ( obj ) {\n	return null if not( obj can nodeType );\n	try {\n		return int( "" _ obj.nodeType() );\n	}\n	catch {\n	}\n	return null;\n}\n\nfunction _zpath_is_xml_document ( obj ) {\n	return true if _zpath_xml_node_type(obj) = 9;\n	return false if not( obj can documentElement );\n	try {\n		obj.documentElement();\n		return true;\n	}\n	catch {\n	}\n	return false;\n}\n\nfunction _zpath_is_xml_node ( obj ) {\n	return true if _zpath_xml_node_type(obj) \u2262 null;\n	return _zpath_is_xml_document(obj);\n}\n\nfunction _zpath_widget_attr_name ( name ) {\n	return ( name ~ /^@/ ) ? substr( name, 1 ) : name;\n}\n\nfunction _zpath_widget_attr_spec ( name ) {\n	let attr := _zpath_widget_attr_name(name);\n	return _WIDGET_ATTRS.first( fn spec \u2192 spec{name} \u2261 attr );\n}\n\nfunction _zpath_widget_attr_applies ( widget, spec ) {\n	let attr := spec{name};\n	if ( attr in [\n		"id",\n		"enabled",\n		"visible",\n		"width",\n		"height",\n		"minwidth",\n		"minheight",\n		"maxwidth",\n		"maxheight",\n		"classes",\n	] ) {\n		return true;\n	}\n\n	switch ( class_name(widget) : eq ) {\n		case "Window":\n			return attr in [ "title" ];\n		case "VBox", "HBox":\n			return attr in [ "align", "gap", "padding" ];\n		case "Frame":\n			return attr in [ "label", "collapsible", "collapsed" ];\n		case "Label":\n			return attr in [ "text", "for" ];\n		case "Text":\n			return attr in [ "value", "multiline", "readonly", "wrap" ];\n		case "RichText":\n			return attr in [ "value", "multiline", "readonly" ];\n		case "Image":\n			return attr in [ "src", "alt", "fit" ];\n		case "Input":\n			return attr in [\n				"value",\n				"placeholder",\n				"multiline",\n				"readonly",\n				"password",\n				"required",\n			];\n		case "DatePicker":\n			return attr in [ "value", "min", "max", "first_day_of_week" ];\n		case "Checkbox":\n			return attr in [ "label", "checked", "indeterminate" ];\n		case "Radio":\n			return attr in [ "label", "value", "group", "checked" ];\n		case "RadioGroup":\n			return attr in [ "name", "value" ];\n		case "Select":\n			return attr in [ "value", "multiple" ];\n		case "Menu":\n			return attr in [ "text" ];\n		case "MenuItem":\n			return attr in [ "text", "disabled" ];\n		case "Button":\n			return attr in [ "text", "variant" ];\n		case "Separator":\n			return attr in [ "orientation" ];\n		case "Slider":\n			return attr in [ "value", "min", "max", "step", "orientation", "readonly" ];\n		case "Progress":\n			return attr in [ "value", "min", "max", "indeterminate", "show_text" ];\n		case "Tabs":\n			return attr in [ "selected", "placement" ];\n		case "Tab":\n			return attr in [ "title", "value", "icon", "selected", "closable" ];\n		case "ListView":\n			return attr in [ "selected_index", "multiple" ];\n		case "TreeView":\n			return attr in [ "selected_path", "multiple" ];\n	}\n\n	return false;\n}\n\nfunction _zpath_widget_get_attr ( widget, spec ) {\n	let getter := spec{getter};\n	return widget.(getter)();\n}\n\nfunction _zpath_widget_set_attr ( widget, spec, value ) {\n	let setter := spec.get( "setter", null );\n	if ( setter \u2262 null ) {\n		try {\n			return widget.(setter)(value);\n		}\n		catch {\n		}\n	}\n\n	let getter := spec{getter};\n	if ( spec.get( "accessor", false ) ) {\n		try {\n			return widget.(getter)(value);\n		}\n		catch {\n		}\n	}\n\n	die `Widget attribute @${spec{name}} is not assignable`;\n}\n\nclass Node {\n	let raw with set := null;\n	let parent but weak := null;\n	let _parent_keepalive := null;\n	let key := null;\n	let id := null;\n	let ix := null;\n	let tagged with set, has := null;\n\n	static method _xml_node_type_code ( value ) {\n		try {\n			return int( "" _ value.nodeType() );\n		}\n		catch {\n			return null;\n		}\n	}\n\n	static method from_root ( obj ) {\n		return self.wrap(obj);\n	}\n\n	static method wrap ( _obj, parent?, key?, ix? ) {\n\n		let obj := _obj;\n\n		if ( obj instanceof Node ) {\n			return obj;\n		}\n\n		let Klass := determine_class( obj );\n\n		let n := new Klass(\n			raw: obj,\n			parent: parent,\n			key: key,\n			ix: ix,\n		);\n\n		if ( obj instanceof TaggedValue ) {\n			n.set_tagged(obj);\n			while ( obj instanceof TaggedValue ) {\n				obj := obj{value}\n			}\n			n.set_raw(obj);\n		}\n\n		n._build_id_with_parent(parent);\n\n		return n;\n	}\n\n	method hold_parent ( owner ) {\n		_parent_keepalive := owner;\n		return self;\n	}\n\n	method _use_ref_as_id () {\n		return false;\n	}\n\n	method _build_id () {\n		id := self._generate_id;\n	}\n\n	method _build_id_with_parent ( owner ) {\n		id := self._generate_id_with_parent(owner);\n	}\n\n	method _generate_id () {\n		return self._generate_id_with_parent(parent);\n	}\n\n	method _generate_id_with_parent ( owner ) {\n\n		if ( self._use_ref_as_id ) {\n			return "ref:" _ ref_id(raw);\n		}\n\n		if ( owner \u2261 null ) {\n			return "root";\n		}\n\n		if ( ix \u2262 null ) {\n			if ( key \u2262 null ) {\n				return owner.id _ "/" _ key _ "#" _ ix;\n			}\n			return owner.id _ "/#" _ ix;\n		}\n\n		if ( key \u2262 null ) {\n			return owner.id _ "/" _ key;\n		}\n\n		return "rand:" _ floor( 1000 * 1000 * 1000 * Math.rand() );\n	}\n\n	method raw ()    { return raw; }\n	method parent () { return parent; }\n	method key ()    { return key; }\n	method id ()     { return id; }\n	method ix ()     { return ix; }\n	method index ()  { return ix; }\n	method tagged () { return tagged; }\n\n	method type () {\n		return typeof raw;\n	}\n\n	method value () {\n		return raw;\n	}\n\n	method primitive_value () {\n		return raw;\n	}\n\n	method string_value () {\n		let p := self.primitive_value;\n		return p \u2261 null ? null : "" _ p;\n	}\n\n	method number_value () {\n		let v := self.primitive_value();\n		return 0 + v if v ~ /^-?(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)$/;\n		return null;\n	}\n\n	method can_have_named_children () {\n		return false;\n	}\n\n	method can_have_indexed_children () {\n		return false;\n	}\n\n	method can_have_named_indexed_children () {\n		return false;\n	}\n\n	method named_child ( name ) {\n		self.children.first( fn kid \u2192 kid.key \u2261 name );\n	}\n\n	method indexed_child ( i ) {\n		self.children.first( fn kid \u2192 kid.ix \u2261 i );\n	}\n\n	method named_indexed_child ( name, i ) {\n		self.children.first( fn kid \u2192 kid.ix \u2261 i and kid.key \u2261 name );\n	}\n\n	method next_child ( child ) {\n		let i := child.ix;\n		return null if i \u2261 null;\n		return self.indexed_child( i + 1 );\n	}\n\n	method prev_child ( child ) {\n		let i := child.ix;\n		return null if i \u2261 null;\n		return null if i = 0;\n		return self.indexed_child( i - 1 );\n	}\n\n	method next_sibling () {\n		return self.parent.next_child( self );\n	}\n\n	method prev_sibling () {\n		return self.parent.prev_child( self );\n	}\n\n	method named_attribute ( name ) {\n		let attrname := ( name ~ /^@/ ) ? name : `@${name}`;\n		self.attributes.first( fn kid \u2192 kid.name \u2261 attrname );\n	}\n\n	method children () {\n		return [];\n	}\n\n	method attributes () {\n		return [];\n	}\n\n	method name () {\n		return key;\n	}\n\n	method dump () {\n		return {\n			"@type": self.type(),\n			"@id": self.id(),\n			"@key": self.key(),\n			"@index": self.index(),\n			"@value": self.primitive_value(),\n			children: self.children().map( fn c -> c.dump() ),\n			attributes: self.attributes().map( fn a -> a.dump() ),\n		};\n	}\n\n	method find ( zpath ) {\n		from std/path/z import ZPath;\n\n		die "Node.find expects a ZPath object"\n			unless zpath instanceof ZPath;\n\n		return zpath.evaluate(self);\n	}\n\n	method do_action ( action ) {\n		const container_node := self.parent();\n		die "Path assignment target has no parent node"\n			if container_node \u2261 null;\n		return container_node.do_action_on_child( self, action );\n	}\n\n	method ref () {\n		const container_node := self.parent();\n		die "Path assignment target has no parent node"\n			if container_node \u2261 null;\n		return container_node.ref_on_child(self);\n	}\n\n	method do_action_on_child ( child, action ) {\n		die `Path assignment target container \'${self.type()}\' is not assignable`;\n	}\n\n	method ref_on_child ( child ) {\n		die `Path assignment target container \'${self.type()}\' is not assignable`;\n	}\n}\n\nclass SimpleNode extends Node {\n}\n\nclass StringNode extends SimpleNode {\n\n	method string_value () {\n		let raw := self.raw;\n		if ( raw instanceof BinaryString ) {\n			return to_string( raw );\n		}\n		return raw;\n	}\n\n	method type () {\n		return "string";\n	}\n}\n\nclass NumberNode extends SimpleNode {\n	method number_value () {\n		let raw := self.raw;\n		return raw;\n	}\n\n	method type () {\n		return "number";\n	}\n}\n\nclass BooleanNode extends SimpleNode {\n	method type () {\n		return "boolean";\n	}\n}\n\nclass NullNode extends SimpleNode {\n	method type () {\n		return "null";\n	}\n}\n\nclass ArrayNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method type () {\n		return "list";\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		while ( i < raw.length ) {\n			let child := Node.wrap( raw[i], self, null, i );\n			out.push(child);\n			i++;\n		}\n		return out;\n	}\n\n	method can_have_indexed_children () {\n		return false;\n	}\n\n	method do_action_on_child ( child, action ) {\n		return super( child, action ) if action{op} ne ":=";\n\n		const ix := child.ix();\n		die "Path assignment expects numeric array index" if ix \u2261 null;\n		let container := self.raw();\n		container[ix] := action{value};\n		return action{value};\n	}\n\n	method ref_on_child ( child ) {\n		const ix := child.ix();\n		die "Path assignment expects numeric array index" if ix \u2261 null;\n		let container := self.raw();\n		return \\ container[ix];\n	}\n}\n\nclass SetNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		while ( i < raw.length ) {\n			let child := Node.wrap( raw[i], self, null, null );\n			out.push(child);\n			i++;\n		}\n		return out;\n	}\n}\n\nclass BagNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		while ( i < raw.length ) {\n			let child := Node.wrap( raw[i], self, null, null );\n			out.push(child);\n			i++;\n		}\n		return out;\n	}\n}\n\nclass DictNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method type () {\n		return "map";\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		for ( let k in raw.keys() ) {\n			let child := Node.wrap( raw.get(k), self, k );\n			out.push(child);\n		}\n		return out;\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method do_action_on_child ( child, action ) {\n		return super( child, action ) if action{op} ne ":=";\n\n		const key := child.key();\n		die "Path assignment expects string dict key" if key \u2261 null;\n		let container := self.raw();\n		container{(key)} := action{value};\n		return action{value};\n	}\n\n	method ref_on_child ( child ) {\n		const key := child.key();\n		die "Path assignment expects string dict key" if key \u2261 null;\n		let container := self.raw();\n		return \\ container{(key)};\n	}\n}\n\nclass PairListNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method children () {\n		let raw := self.raw;\n		let pairs := raw.to_Array();\n		let out := [];\n		let i := 0;\n		while ( i < pairs.length() ) {\n			let pair := pairs[i];\n			out.push( Node.wrap( pair, self, pair.key, i ) );\n			i++;\n		}\n		return out;\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method can_have_indexed_children () {\n		return true;\n	}\n\n	method can_have_named_indexed_children () {\n		return true;\n	}\n\n	method named_child ( name ) {\n		return self.named_indexed_child( name, 0 );\n	}\n\n	method indexed_child ( i ) {\n		let pairs := self.raw().to_Array();\n		return null if i < 0 or i >= pairs.length();\n		let pair := pairs[i];\n		return Node.wrap( pair, self, pair.key, i );\n	}\n\n	method named_indexed_child ( name, i ) {\n		let pairs := self.raw().to_Array();\n		let seen := 0;\n		let pos := 0;\n		while ( pos < pairs.length() ) {\n			let pair := pairs[pos];\n			if ( pair.key \u2261 name ) {\n				if ( seen = i ) {\n					return Node.wrap( pair, self, pair.key, pos );\n				}\n				seen++;\n			}\n			pos++;\n		}\n		return null;\n	}\n\n	method _replace_value_at ( pair_ix, value ) {\n		let container := self.raw();\n		let pairs := container.to_Array();\n		die "Path assignment expects numeric pairlist index"\n			if pair_ix \u2261 null or pair_ix < 0 or pair_ix >= pairs.length();\n\n		container.clear();\n		let i := 0;\n		while ( i < pairs.length() ) {\n			let pair := pairs[i];\n			container.add( pair.key, i = pair_ix ? value : pair.value );\n			i++;\n		}\n		return value;\n	}\n\n	method do_action_on_child ( child, action ) {\n		return super( child, action ) if action{op} ne ":=";\n\n		return self._replace_value_at( child.ix(), action{value} );\n	}\n\n	method ref_on_child ( child ) {\n		let pair_ix := child.ix();\n		return function ( ... args ) {\n			let current := self.indexed_child(pair_ix);\n			die "Path assignment target pairlist entry no longer exists"\n				if current \u2261 null;\n			return current.raw().value if args.length() = 0;\n			return self._replace_value_at( pair_ix, args[0] );\n		};\n	}\n}\n\nclass PairNode extends Node {\n\n	method attributes () {\n		let raw := self.raw;\n		return [ "key", "value" ]\n			.map( fn a \u2192 Node.wrap( raw.(a)(), self, `@${a}` ) );\n	}\n\n	method do_action_on_child ( child, action ) {\n		return super( child, action ) if action{op} ne ":=";\n		return super( child, action ) if child.key() ne "@value";\n\n		let container := self.parent();\n		return super( child, action )\n			if container \u2261 null or not ( container instanceof PairListNode );\n		return container.do_action_on_child( self, action );\n	}\n\n	method ref_on_child ( child ) {\n		return super(child) if child.key() ne "@value";\n\n		let container := self.parent();\n		return super(child)\n			if container \u2261 null or not ( container instanceof PairListNode );\n		return container.ref_on_child(self);\n	}\n}\n\nclass KDLDocumentNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method type () {\n		return "document";\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		while ( i < raw.nodes().length() ) {\n			let child := raw.nodes()[i];\n			out.push( Node.wrap( child, self, child.name(), i ) );\n			i++;\n		}\n		return out;\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method can_have_indexed_children () {\n		return true;\n	}\n\n	method can_have_named_indexed_children () {\n		return true;\n	}\n\n	method indexed_child ( i ) {\n		return self.children().get( i, null );\n	}\n\n	method named_indexed_child ( name, i ) {\n		let n := 0;\n		for ( let child in self.children() ) {\n			if ( child.key() \u2261 name ) {\n				return child if n \u2261 i;\n				n++;\n			}\n		}\n		return null;\n	}\n}\n\nclass KDLNodeNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method type () {\n		return "element";\n	}\n\n	method name () {\n		return self.raw().name();\n	}\n\n	method children () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		for ( let arg in raw.args() ) {\n			out.push( Node.wrap( arg, self, null, i ) );\n			i++;\n		}\n		for ( let child in raw.children() ) {\n			out.push( Node.wrap( child, self, child.name(), i ) );\n			i++;\n		}\n		return out;\n	}\n\n	method attributes () {\n		let raw := self.raw;\n		let out := [];\n		let i := 0;\n		for ( let pair in raw.props().to_Array() ) {\n			out.push( Node.wrap( pair.value, self, "@" _ pair.key, i ) );\n			i++;\n		}\n		return out;\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method can_have_indexed_children () {\n		return true;\n	}\n\n	method can_have_named_indexed_children () {\n		return true;\n	}\n\n	method indexed_child ( i ) {\n		return self.children().get( i, null );\n	}\n\n	method named_indexed_child ( name, i ) {\n		let n := 0;\n		for ( let child in self.children() ) {\n			if ( child.key() \u2261 name ) {\n				return child if n \u2261 i;\n				n++;\n			}\n		}\n		return null;\n	}\n}\n\nclass KDLValueNode extends Node {\n\n	method type () {\n		return self.raw().type();\n	}\n\n	method value () {\n		return self.raw().native_value();\n	}\n\n	method primitive_value () {\n		return self.raw().native_value();\n	}\n\n	method string_value () {\n		return self.raw().to_String();\n	}\n\n	method number_value () {\n		try {\n			return self.raw().to_Number();\n		}\n		catch {\n			return null;\n		}\n	}\n\n	method has_tagged () {\n		return true;\n	}\n\n	method tagged () {\n		let ann := self.raw().type_annotation();\n		return {\n			tag: ann \u2261 null ? null : "" _ ann,\n			value: self.raw().native_value(),\n		};\n	}\n}\n\nclass XmlNodeNode extends Node {\n\n	method _generate_id () {\n		return\n			try {\n				let i := self.raw.unique_id;\n				i \u2261 null ? super() : `xml:${i}`;\n			}\n			catch {\n				super();\n			};\n	}\n\n	method type () {\n		let raw := self.raw;\n		if ( _zpath_is_xml_document(raw) ) {\n			return "document";\n		}\n		switch ( Node._xml_node_type_code(raw) ) {\n			case 1:\n				return "element";\n			case 2, 18:\n				return "attr";\n			case 3, 4:\n				return "text";\n			case 8:\n				return "comment";\n			case 9:\n				return "document";\n		}\n\n		return super();\n	}\n\n	method name () {\n		let raw := self.raw;\n		switch ( Node._xml_node_type_code(raw) ) {\n			case 1:\n				return raw.nodeName();\n			case 2, 18:\n				return "@" _ raw.nodeName();\n			case 3, 4:\n				return "#text";\n		}\n\n		return super();\n	}\n\n	method next_child ( child ) {\n		return child.next_sibling;\n	}\n\n	method prev_child ( child ) {\n		return child.prev_sibling;\n	}\n\n	method next_sibling () {\n		let x := self.raw.nextSibling;\n		return null if x \u2261 null;\n		return Node.wrap( x, self.parent, x.nodeName );\n	}\n\n	method prev_sibling () {\n		let x := self.raw.previousSibling;\n		return null if x \u2261 null;\n		return Node.wrap( x, self.parent, x.nodeName );\n	}\n\n	method primitive_value () {\n		let raw := self.raw;\n		if ( _zpath_is_xml_document(raw) ) {\n			let de := raw.documentElement();\n			return de \u2261 null ? null : de.textContent();\n		}\n		switch ( Node._xml_node_type_code(raw) ) {\n			case 1:\n				return raw.textContent;\n			case 2, 18:\n				return raw.nodeValue();\n			case 3, 4, 8:\n				return raw.data;\n			case 9:\n				let de := raw.documentElement();\n				return de \u2261 null ? null : de.textContent();\n		}\n\n		return super();\n	}\n\n	method string_value () {\n		let raw := self.raw;\n		if ( _zpath_is_xml_document(raw) ) {\n			let de := raw.documentElement();\n			return de \u2261 null ? null : de.textContent();\n		}\n		switch ( Node._xml_node_type_code(raw) ) {\n			case 1:\n				return raw.textContent;\n			case 2, 18:\n				return raw.nodeValue();\n			case 3, 4, 8:\n				return raw.data;\n			case 9:\n				let de := raw.documentElement();\n				return de \u2261 null ? null : de.textContent();\n		}\n\n		return super();\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method can_have_indexed_children () {\n		return true;\n	}\n\n	method can_have_named_indexed_children () {\n		return true;\n	}\n\n	method children () {\n		let raw := self.raw;\n		if ( _zpath_is_xml_document(raw) ) {\n			let de := raw.documentElement();\n			return de \u2261 null ? []\n				: [ Node.wrap( de, self, de.nodeName(), 0 ) ];\n		}\n		let node_type := Node._xml_node_type_code(raw);\n		if ( node_type = 9 ) {\n			let de := raw.documentElement();\n			return de \u2261 null ? []\n				: [ Node.wrap( de, self, de.nodeName(), 0 ) ];\n		}\n\n		if ( node_type = 1 ) {\n			let kids := [];\n			let count := {};\n			for ( let child in raw.childNodes() ) {\n				let nm := child.nodeName();\n				let n := count.exists(nm) ? count.get( nm ) : 0;\n				count.set( nm, n + 1 );\n				kids.push( Node.wrap( child, self, nm, n ) );\n			}\n			return kids;\n		}\n\n		return [];\n	}\n\n	method attributes () {\n		let raw := self.raw;\n		let out := super();\n		if ( Node._xml_node_type_code(raw) \u2261 1 ) {\n			for ( let attr in raw.attributes() ) {\n				let n := Node.wrap( attr, self, "@" _ attr.nodeName() );\n				out.push(n);\n			}\n		}\n		return out;\n	}\n}\n\nclass TimeNode extends Node {\n\n	method string_value () {\n		let raw := self.raw;\n		return raw.datetime;\n	}\n\n	method number_value () {\n		let raw := self.raw;\n		return raw.epoch;\n	}\n\n	method attributes () {\n		let raw := self.raw;\n		return [ "year", "month", "day", "hour", "min", "sec" ]\n			.map( fn a \u2192 Node.wrap( raw.(a)(), self, `@${a}` ) );\n	}\n}\n\nclass PathNode extends Node {\n\n	method string_value () {\n		let raw := self.raw;\n		return raw.to_String;\n	}\n\n	method attributes () {\n		let raw := self.raw;\n		if ( raw.is_file ) {\n			const stat := raw.stat;\n			return stat.keys.map( fn a \u2192 Node.wrap( stat{a}, self, `@${a}` ) );\n		}\n\n		return super();\n	}\n}\n\nclass WidgetNode extends Node {\n\n	method _use_ref_as_id () {\n		return true;\n	}\n\n	method type () {\n		return "widget";\n	}\n\n	method name () {\n		return class_name( self.raw() ) ?: "Widget";\n	}\n\n	method can_have_named_children () {\n		return true;\n	}\n\n	method can_have_indexed_children () {\n		return true;\n	}\n\n	method can_have_named_indexed_children () {\n		return true;\n	}\n\n	method children () {\n		let out := [];\n		let i := 0;\n		for ( let child in self.raw().children() ) {\n			let nm := class_name(child) ?: "Widget";\n			out.push( Node.wrap( child, self, nm, i ) );\n			i++;\n		}\n		return out;\n	}\n\n	method indexed_child ( i ) {\n		return self.children().get( i, null );\n	}\n\n	method named_indexed_child ( name, i ) {\n		let n := 0;\n		for ( let child in self.children() ) {\n			if ( child.key() \u2261 name ) {\n				return child if n \u2261 i;\n				n++;\n			}\n		}\n		return null;\n	}\n\n	method attributes () {\n		let raw := self.raw();\n		let out := [];\n		let i := 0;\n		for ( let spec in _WIDGET_ATTRS ) {\n			next unless _zpath_widget_attr_applies( raw, spec );\n			try {\n				let value := _zpath_widget_get_attr( raw, spec );\n				out.push( Node.wrap( value, self, "@" _ spec{name}, i ) );\n				i++;\n			}\n			catch {\n			}\n		}\n		return out;\n	}\n\n	method do_action_on_child ( child, action ) {\n		return super( child, action ) if action{op} ne ":=";\n\n		let spec := _zpath_widget_attr_spec( child.key() );\n		return super( child, action ) if spec \u2261 null;\n\n		_zpath_widget_set_attr( self.raw(), spec, action{value} );\n		return action{value};\n	}\n\n	method ref_on_child ( child ) {\n		let spec := _zpath_widget_attr_spec( child.key() );\n		return super(child) if spec \u2261 null;\n\n		let widget := self.raw();\n		return function ( ... args ) {\n			if ( args.length() = 0 ) {\n				return _zpath_widget_get_attr( widget, spec );\n			}\n			_zpath_widget_set_attr( widget, spec, args[0] );\n			return args[0];\n		};\n	}\n}\n\n// Need to define the body of this function late so it can refer back to\n// classes that have been declared.\n\nfunction determine_class ( obj ) {\n	let Klass;\n\n	let real_obj := obj;\n	while ( real_obj instanceof TaggedValue ) {\n		real_obj := real_obj{value};\n	}\n\n	if ( real_obj instanceof Null ) {\n		Klass := NullNode;\n	}\n	else if ( real_obj instanceof Boolean ) {\n		Klass := BooleanNode;\n	}\n	else if ( real_obj instanceof Number ) {\n		Klass := NumberNode;\n	}\n	else if ( real_obj instanceof String or real_obj instanceof BinaryString ) {\n		Klass := StringNode;\n	}\n	else if ( real_obj instanceof Array ) {\n		Klass := ArrayNode;\n	}\n	else if ( real_obj instanceof Bag ) {\n		Klass := BagNode;\n	}\n	else if ( real_obj instanceof Set ) {\n		Klass := SetNode;\n	}\n	else if ( real_obj instanceof Dict ) {\n		Klass := DictNode;\n	}\n	else if ( real_obj instanceof PairList ) {\n		Klass := PairListNode;\n	}\n	else if ( real_obj instanceof Pair ) {\n		Klass := PairNode;\n	}\n	else if ( real_obj instanceof KDLDocument ) {\n		Klass := KDLDocumentNode;\n	}\n	else if ( real_obj instanceof KDLNode ) {\n		Klass := KDLNodeNode;\n	}\n	else if ( real_obj instanceof KDLValue ) {\n		Klass := KDLValueNode;\n	}\n	else if ( _zpath_is_xml_node(real_obj) ) {\n		Klass := XmlNodeNode;\n	}\n	else if ( real_obj instanceof Time ) {\n		Klass := TimeNode;\n	}\n	else if ( Path and ( real_obj instanceof Path ) ) {\n		Klass := PathNode;\n	}\n	else if ( real_obj instanceof Object ) {\n		if ( real_obj can __zpath_node_class__ ) {\n			Klass = real_obj.__zpath_node_class__;\n		}\n	}\n\n	if ( Klass \u2261 null and _zpath_is_widget(real_obj) ) {\n		Klass := WidgetNode;\n	}\n\n	if ( Klass \u2261 null ) {\n		Klass := XmlNodeNode if _zpath_is_xml_node(real_obj);\n	}\n\n	return Klass ?: Node;\n}\n';
        virtualFiles["/modules/std/path/z/operators.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/operators - Operator definitions for ZPath.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module defines the base ZPath operator model and the standard\noperator table used by C<std/path/z>.\n\n=head1 EXPORTS\n\n=head2 Traits\n\n=over\n\n=item C<EvalHelpers>\n\nShared helpers for operator and function definitions.\n\n=over\n\n=item C<< helper.wrap(value) >>\n\nParameters: C<value> is any value. Returns: C<Array>. Wraps C<value> as\na one-item ZPath node array.\n\n=item C<< helper.wrap_for_array(value) >>\n\nParameters: C<value> is any value. Returns: C<Node>. Wraps C<value> as a\nZPath node for array results.\n\n=back\n\n=back\n\n=head2 Classes\n\n=over\n\n=item C<< Operator({ spelling: String, kind: String, precedence: Number, ... }) >>\n\nConstructs an operator definition. Returns: C<Operator>.\n\n=over\n\n=item C<< operator.is_unary() >>, C<< operator.is_binary() >>\n\nParameters: none. Returns: C<Boolean>. Reports whether the operator is\nunary or binary.\n\n=item C<< operator.requires_whitespace() >>\n\nParameters: none. Returns: C<Boolean>. Reports whether the lexer\nrequires whitespace around the operator.\n\n=item C<< operator.lexer_should_ignore() >>\n\nParameters: none. Returns: C<Boolean>. Reports whether the lexer should\nignore this operator definition.\n\n=item C<< operator.is_right_associative() >>\n\nParameters: none. Returns: C<Boolean>. Reports whether the operator is\nright associative.\n\n=item C<< operator.char_length() >>\n\nParameters: none. Returns: C<Number>. Returns the operator spelling\nlength.\n\n=item C<< operator.precedence_is(lvl) >>\n\nParameters: C<lvl> is a precedence level. Returns: C<Boolean>. Returns\ntrue when the operator has that precedence.\n\n=back\n\n=back\n\n=head2 Constants\n\n=over\n\n=item C<STANDARD_OPERATORS>\n\nType: C<Array>. Standard ZPath operator definitions.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/operators >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z/node import Node;\n\nfunction _floaty_modulus ( ln, rn ) {\n	let count := floor( ln / rn ); //\n	return ln - ( count * rn );\n}\n\ntrait EvalHelpers {\n	method _handle_numeric_operand ( ev, ctx, expr ) {\n		const result := ev.eval_expr( expr, ev.nested_ctx( ctx ) );\n		return 0 unless result.length;\n		return ev.to_number( result[0] );\n	}\n\n	method _handle_stringy_operand ( ev, ctx, expr ) {\n		const result := ev.eval_expr( expr, ev.nested_ctx( ctx ) );\n		return 0 unless result.length;\n		return ev.to_number( result[0] );\n	}\n\n	method wrap ( value ) {\n		return [ Node.wrap( value ) ];\n	}\n\n	method wrap_for_array ( value ) {\n		return Node.wrap( value );\n	}\n}\n\nclass Operator with EvalHelpers {\n	let String spelling with get;\n	let String alias with get, has;\n	let String kind with get;\n	let Number precedence with get;\n	let Boolean unary      := false;\n	let Boolean require_ws := false;\n	let Boolean lex_ignore := false;\n	let Boolean right_assoc := false;\n	let Function f;\n\n	method is_unary () {\n		return unary;\n	}\n\n	method is_binary () {\n		return not unary;\n	}\n\n	method requires_whitespace () {\n		return require_ws;\n	}\n\n	method lexer_should_ignore () {\n		return lex_ignore;\n	}\n\n	method is_right_associative () {\n		return right_assoc;\n	}\n\n	method char_length () {\n		return length spelling;\n	}\n\n	method precedence_is ( lvl ) {\n		return precedence = lvl;\n	}\n}\n\nconst STANDARD_OPERATORS := [\n	new Operator(\n		spelling: "||",\n		kind: "OROR",\n		precedence: 2,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n			if ( left_val.length and ev.truthy( left_val[0] ) ) {\n				return op.wrap( true );\n			}\n			const right_val := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n			if ( right_val.length and ev.truthy( right_val[0] ) ) {\n				return op.wrap( true );\n			}\n			return op.wrap( false );\n		},\n	),\n\n	new Operator(\n		spelling: "&&",\n		kind: "ANDAND",\n		precedence: 4,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n			if ( left_val.length and ev.truthy( left_val[0] ) ) {\n				const right_val := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n				if ( right_val.length and ev.truthy( right_val[0] ) ) {\n					return op.wrap( true );\n				}\n			}\n			return op.wrap( false );\n		},\n	),\n\n	new Operator(\n		spelling: "==",\n		kind: "EQEQ",\n		precedence: 12,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_vals  := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n			const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n			let is_eq := false;\n\n			if ( left_vals and right_vals ) {\n				for ( let ln in left_vals ) {\n					last if is_eq;\n					for ( let rn in right_vals ) {\n						last if is_eq;\n						if ( ev.equals( ln, rn ) ) {\n							is_eq := true;\n						}\n					}\n				}\n			}\n\n			return op.wrap( is_eq );\n		},\n	),\n\n	new Operator(\n		spelling: "!=",\n		kind: "NEQ",\n		precedence: 12,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_vals  := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n			const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n			let is_eq := false;\n\n			if ( left_vals and right_vals ) {\n				for ( let ln in left_vals ) {\n					last if is_eq;\n					for ( let rn in right_vals ) {\n						last if is_eq;\n						if ( ev.equals( ln, rn ) ) {\n							is_eq := true;\n						}\n					}\n				}\n			}\n\n			return op.wrap( not is_eq );\n		},\n	),\n\n	new Operator(\n		spelling: ">=",\n		kind: "GE",\n		precedence: 14,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			let left_val  := op._handle_numeric_operand( ev, ctx, left );\n			let right_val := op._handle_numeric_operand( ev, ctx, right );\n			if ( ( left_val \u2261 null ) or ( right_val \u2261 null ) ) {\n				left_val  := op._handle_stringy_operand( ev, ctx, left );\n				right_val := op._handle_stringy_operand( ev, ctx, right );\n				return op.wrap( left_val ge right_val );\n			}\n			return op.wrap( left_val \u2265 right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "<=",\n		kind: "LE",\n		precedence: 14,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			let left_val  := op._handle_numeric_operand( ev, ctx, left );\n			let right_val := op._handle_numeric_operand( ev, ctx, right );\n			if ( ( left_val \u2261 null ) or ( right_val \u2261 null ) ) {\n				left_val  := op._handle_stringy_operand( ev, ctx, left );\n				right_val := op._handle_stringy_operand( ev, ctx, right );\n				return op.wrap( left_val le right_val );\n			}\n			return op.wrap( left_val \u2264 right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "+",\n		kind: "PLUS",\n		require_ws: true,\n		precedence: 16,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val + right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "-",\n		kind: "MINUS",\n		require_ws: true,\n		precedence: 16,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val - right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "%",\n		kind: "PCT",\n		require_ws: true,\n		precedence: 18,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			if ( ( left_val ~ /\\./ ) or ( right_val ~ /\\./ ) ) {\n				return op.wrap( _floaty_modulus( left_val, right_val ) );\n			}\n			return op.wrap( left_val mod right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "*",\n		kind: "TIMES",\n		require_ws: true,\n		precedence: 18,\n		lex_ignore: true,\n		alias: "STAR",\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val \xD7 right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "/",\n		kind: "DIVIDE",\n		require_ws: true,\n		precedence: 18,\n		lex_ignore: true,\n		alias: "SLASH",\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val \xF7 right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "^",\n		kind: "BXOR",\n		precedence: 8,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val ^ right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "&",\n		kind: "BAND",\n		precedence: 10,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val & right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "|",\n		kind: "BOR",\n		precedence: 6,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			const left_val  := op._handle_numeric_operand( ev, ctx, left );\n			const right_val := op._handle_numeric_operand( ev, ctx, right );\n			return op.wrap( left_val | right_val );\n		},\n	),\n\n	new Operator(\n		spelling: ">",\n		kind: "GT",\n		precedence: 14,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			let left_val  := op._handle_numeric_operand( ev, ctx, left );\n			let right_val := op._handle_numeric_operand( ev, ctx, right );\n			if ( ( left_val \u2261 null ) or ( right_val \u2261 null ) ) {\n				left_val  := op._handle_stringy_operand( ev, ctx, left );\n				right_val := op._handle_stringy_operand( ev, ctx, right );\n				return op.wrap( left_val gt right_val );\n			}\n			return op.wrap( left_val > right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "<",\n		kind: "LT",\n		precedence: 14,\n		f: function ( op, ev, ast, ctx, left, right ) {\n			let left_val  := op._handle_numeric_operand( ev, ctx, left );\n			let right_val := op._handle_numeric_operand( ev, ctx, right );\n			if ( ( left_val \u2261 null ) or ( right_val \u2261 null ) ) {\n				left_val  := op._handle_stringy_operand( ev, ctx, left );\n				right_val := op._handle_stringy_operand( ev, ctx, right );\n				return op.wrap( left_val le right_val );\n			}\n			return op.wrap( left_val < right_val );\n		},\n	),\n\n	new Operator(\n		spelling: "!",\n		kind: "NOT",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const got := ev.eval_expr( expr, ctx );\n			const value := got.length() > 0 ? got[0] : null;\n			return op.wrap( not ev.truthy(value) );\n		},\n	),\n\n	new Operator(\n		spelling: "~",\n		kind: "BNOT",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const value := op._handle_numeric_operand( ev, ctx, expr );\n			return op.wrap( ~value );\n		},\n	),\n];\n';
        virtualFiles["/modules/std/path/z/parser.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/z/parser - Pure Zuzu parser for ZPath expressions.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides the pure-Zuzu parser used by ZPath.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< Parser({ lexer_class?, allowed_operators }) >>\n\nConstructs a ZPath parser. Returns: C<Parser>.\n\n=over\n\n=item C<< parser.parse_top_level_terms(src) >>\n\nParameters: C<src> is a ZPath expression string. Returns: C<Array>.\nParses comma-separated top-level expression terms.\n\n=item C<< parser.parse_expression(lx) >>\n\nParameters: C<lx> is a C<Lexer>. Returns: C<Dict>. Parses an expression.\n\n=item C<< parser.parse_ternary(lx) >>\n\nParameters: C<lx> is a C<Lexer>. Returns: C<Dict>. Parses ternary and\nElvis expressions.\n\n=item C<< parser.parse_subexpression(lx, min_prec) >>\n\nParameters: C<lx> is a C<Lexer> and C<min_prec> is a precedence floor.\nReturns: C<Dict>. Parses a precedence-climbing subexpression.\n\n=item C<< parser.parse_primary(lx) >>\n\nParameters: C<lx> is a C<Lexer>. Returns: C<Dict>. Parses a primary\nexpression.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/z/parser >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import trim;\nfrom std/path/z/lexer import Lexer;\n\nclass Parser {\n	let lexer_class;\n	let allowed_operators;\n	let _binop_prec := {};\n	let _unop_prec  := {};\n	let _need_ws    := {};\n	let _right_assoc := {};\n	let _path_terminators := {};\n	let _allow_elvis := false;\n\n	method __build__ () {\n		lexer_class ?:= Lexer;\n		self._init_path_terminators();\n		for ( let op in allowed_operators ) {\n			let spell := op.get_spelling();\n			if ( op.is_unary() ) {\n				_unop_prec.set( spell, op.get_precedence() );\n			}\n			else {\n				if ( op.get_kind() \u2261 "ELVIS" ) {\n					_allow_elvis := true;\n					_path_terminators.set( op.get_kind(), true );\n					next;\n				}\n				_binop_prec.set( spell, op.get_precedence() );\n				_path_terminators.set( op.get_kind(), true );\n				if ( op.has_alias() ) {\n					_path_terminators.set( op.get_alias(), true );\n				}\n				if ( op.requires_whitespace() ) {\n					_need_ws.set( spell, true );\n				}\n				if ( op.is_right_associative() ) {\n					_right_assoc.set( spell, true );\n				}\n			}\n		}\n	}\n\n	method _init_path_terminators () {\n		for ( let k in [\n			"EOF",\n			"COMMA",\n			"RPAREN",\n			"RBRACK",\n			"QMARK",\n			"COLON",\n		] ) {\n			_path_terminators.set( k, true );\n		}\n	}\n\n	method parse_top_level_terms ( src ) {\n		let terms := [];\n		let lexer := new lexer_class(\n			src:               src,\n			allowed_operators: allowed_operators,\n		);\n\n		while ( true ) {\n			let expr := self.parse_expression(lexer);\n			terms.push(expr);\n			if ( lexer.peek_kind() \u2261 "COMMA" ) {\n				lexer.next_tok();\n				next;\n			}\n			lexer.expect("EOF");\n			last;\n		}\n\n		return terms;\n	}\n\n	method _trim ( s ) {\n		return trim(s);\n	}\n\n	method parse_expression ( lx ) {\n		return self.parse_ternary(lx);\n	}\n\n	method parse_ternary ( lx ) {\n		let cond := self.parse_subexpression( lx, 1 );\n\n		if ( lx.peek_kind() \u2261 "QMARK" ) {\n			lx.next_tok();\n			let then := self.parse_expression(lx); // ZZPath should use: self.parse_subexpression( lx, 1 )\n			lx.expect("COLON");\n			let els := self.parse_expression(lx);\n			return { t: "ternary", c: cond, a: then, b: els };\n		}\n		if ( _allow_elvis and lx.peek_kind() \u2261 "ELVIS" ) {\n			lx.next_tok();\n			let fallback := self.parse_expression(lx);\n			return { t: "elvis", c: cond, b: fallback };\n		}\n\n		return cond;\n	}\n\n	method parse_subexpression ( lx, min_prec ) {\n		let left := self._parse_maybe_unary( lx, min_prec );\n\n		while ( true ) {\n			let spell := lx.peek{v};\n			let op_prec := _binop_prec.get( spell, null );\n			last if op_prec \u2261 null or op_prec < min_prec;\n\n			let op := lx.next_tok;\n			if ( _need_ws.exists( spell ) ) {\n				if ( not ( op{ws_before} and op{ws_after} ) ) {\n					die `Binary operator \'${spell}\' requires whitespace around it`;\n				}\n			}\n\n			let next_min := _right_assoc.exists(spell) ? op_prec : op_prec + 1;\n			let right := self.parse_subexpression( lx, next_min );\n			left := { t: "bin", op: spell, l: left, r: right };\n		}\n\n		return left;\n	}\n\n	method _parse_maybe_unary ( lx, min_prec ) {\n		let spell := lx.peek{v};\n		let op_prec := _unop_prec.get( spell, null );\n		if ( op_prec \u2262 null and op_prec >= min_prec ) {\n			let op := lx.next_tok{v};\n			let e  := self._parse_maybe_unary( lx, op_prec );\n			return { t: "un", op: op, e: e };\n		}\n		return self.parse_primary( lx );\n	}\n\n	method parse_primary ( lx ) {\n		let k := lx.peek_kind;\n\n		if ( k \u2261 "NUMBER" ) {\n			return { t: "num", v: lx.next_tok(){v} };\n		}\n		if ( k \u2261 "STRING" ) {\n			return { t: "str", v: lx.next_tok(){v} };\n		}\n		if ( k \u2261 "LPAREN" ) {\n			lx.next_tok();\n			let e := self.parse_expression(lx);\n			lx.expect("RPAREN");\n			return e;\n		}\n\n		if ( k \u2261 "NAME" and lx.peek_kind_n(1) \u2261 "LPAREN" ) {\n			let name := lx.next_tok(){v};\n			lx.expect("LPAREN");\n			let args := [];\n			if ( lx.peek_kind() \u2262 "RPAREN" ) {\n				args.push( self.parse_expression(lx) );\n				while ( lx.peek_kind() \u2261 "COMMA" ) {\n					lx.next_tok();\n					args.push( self.parse_expression(lx) );\n				}\n			}\n			lx.expect("RPAREN");\n			return { t: "fn", n: name, a: args };\n		}\n\n		return self._parse_path_expr(lx);\n	}\n\n	method _is_path_terminator ( k ) {\n		return _path_terminators.exists(k);\n	}\n\n	method _parse_path_expr ( lx ) {\n		let segs := [];\n\n		if ( lx.peek_kind() \u2261 "SLASH_PATH" ) {\n			lx.next_tok();\n			let root := { k: "root", q: [] };\n			segs.push(root);\n\n			if ( lx.peek_kind() \u2261 "LBRACK" ) {\n				root{q} := self._parse_qualifiers(lx);\n			}\n\n			if ( self._is_path_terminator( lx.peek_kind() ) ) {\n				return { t: "path", s: segs };\n			}\n		}\n		else if ( lx.peek_kind() \u2261 "LBRACK" ) {\n			let seg := { k: "dot", q: self._parse_qualifiers(lx) };\n			segs.push(seg);\n			if ( self._is_path_terminator( lx.peek_kind() ) ) {\n				return { t: "path", s: segs };\n			}\n		}\n\n		if (\n			lx.peek_kind() \u2262 "SLASH_PATH"\n			and not self._is_path_terminator( lx.peek_kind() )\n		) {\n			segs.push( self._parse_path_segment(lx) );\n		}\n\n		while ( lx.peek_kind() \u2261 "SLASH_PATH" ) {\n			lx.next_tok();\n			if ( lx.peek_kind() \u2261 "LBRACK" ) {\n				let seg := { k: "star", q: [] };\n				seg{q} := self._parse_qualifiers(lx);\n				segs.push(seg);\n				next;\n			}\n			segs.push( self._parse_path_segment(lx) );\n		}\n\n		return { t: "path", s: segs };\n	}\n\n	method _parse_path_segment ( lx ) {\n		let k := lx.peek_kind();\n		let seg := null;\n\n		if ( k \u2261 "DOT" ) {\n			lx.next_tok();\n			seg := { k: "dot" };\n		}\n		else if ( k \u2261 "DOTDOT" ) {\n			lx.next_tok();\n			seg := { k: "parent" };\n		}\n		else if ( k \u2261 "DOTDOTSTAR" ) {\n			lx.next_tok();\n			seg := { k: "ancestors" };\n		}\n		else if ( k \u2261 "STAR_PATH" ) {\n			lx.next_tok();\n			seg := { k: "star" };\n		}\n		else if ( k \u2261 "STARSTAR" ) {\n			lx.next_tok();\n			seg := { k: "desc" };\n		}\n		else if ( k \u2261 "INDEX" ) {\n			let i := lx.next_tok(){v};\n			seg := { k: "index", i: i };\n		}\n		else if ( k \u2261 "NUMBER" ) {\n			let i := lx.next_tok(){v};\n			seg := { k: "index", i: i };\n		}\n		else if ( k \u2261 "NAME" and lx.peek_kind_n(1) \u2261 "LPAREN" ) {\n			let name := lx.next_tok(){v};\n			lx.expect("LPAREN");\n			let args := [];\n			if ( lx.peek_kind() \u2262 "RPAREN" ) {\n				args.push( self.parse_expression(lx) );\n				while ( lx.peek_kind() \u2261 "COMMA" ) {\n					lx.next_tok();\n					args.push( self.parse_expression(lx) );\n				}\n			}\n			lx.expect("RPAREN");\n			seg := { k: "fnseg", n: name, a: args };\n		}\n		else if ( k \u2261 "NAME" ) {\n			let n := lx.next_tok(){v};\n			seg := { k: "name", n: n };\n		}\n		else {\n			die `Unexpected token in path segment: ${k}`;\n		}\n\n		if ( seg{k} \u2261 "name" and lx.peek_kind() \u2261 "INDEX" ) {\n			seg{i} := lx.next_tok(){v};\n		}\n\n		seg{q} := self._parse_qualifiers(lx);\n		return seg;\n	}\n\n	method _parse_qualifiers ( lx ) {\n		let q := [];\n\n		while ( lx.peek_kind() \u2261 "LBRACK" ) {\n			lx.next_tok();\n			let e := self.parse_expression(lx);\n			lx.expect("RBRACK");\n			q.push(e);\n		}\n\n		return q;\n	}\n}\n';
        virtualFiles["/modules/std/path/zz.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/zz - ZuzuScript-flavoured path selectors.\n\n=head1 SYNOPSIS\n\n  from std/path/zz import ZZPath;\n\n  let data := { users: [ { name: "Ada" } ] };\n  say( ( new ZZPath( path: "/users/#0/name" ) ).first(data) );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module provides the public C<ZZPath> class. It currently reuses the\nZPath traversal, parser, lexer, assignment, and reference\nmachinery while routing expression operators through\nC<std/path/zz/operators> and expression functions through\nC<std/path/zz/functions>.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<ZZEvaluator>\n\nEvaluator class that supplies ZZPath operators and functions.\n\n=over\n\n=item C<< evaluator.operator_definitions() >>\n\nParameters: none. Returns: C<Array>. Returns ZZPath operator\ndefinitions.\n\n=item C<< evaluator.function_definitions() >>\n\nParameters: none. Returns: C<Array>. Returns ZZPath function\ndefinitions.\n\n=back\n\n=item C<< ZZPath({ path: String }) >>\n\nConstructs a ZZPath query object. Returns: C<ZZPath>. Inherits the\npublic query, assignment, and reference methods from C<ZPath>.\n\n=over\n\n=item C<< path.get_evaluator() >>\n\nParameters: none. Returns: C<ZZEvaluator>. Returns the evaluator used\nfor this path.\n\n=item C<< node.find(path) >>\n\nC<ZZPath> inherits from C<ZPath>, so a C<ZZPath> object can be passed to\nC<std/path/z/node> C<Node.find()>.\n\n=back\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/zz >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z import ZPath;\nfrom std/path/z/evaluate import Evaluator as ZEvaluator;\n\nclass ZZEvaluator extends ZEvaluator {\n	method operator_definitions () {\n		from std/path/zz/operators import STANDARD_OPERATORS;\n		return STANDARD_OPERATORS;\n	}\n\n	method function_definitions () {\n		from std/path/zz/functions import STANDARD_FUNCTIONS;\n		return STANDARD_FUNCTIONS;\n	}\n}\n\nclass ZZPath extends ZPath {\n	method get_evaluator () {\n		return new ZZEvaluator();\n	}\n}\n';
        virtualFiles["/modules/std/path/zz/functions.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/zz/functions - Function definitions for ZZPath expressions.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module extends the base ZPath function table with\nZuzuScript-flavoured path expression helpers.\n\n=head1 EXPORTS\n\n=head2 Constants\n\n=over\n\n=item C<STANDARD_FUNCTION_NAMES>\n\nType: C<Array>. Names of inherited ZPath functions available to ZZPath.\n\n=item C<STANDARD_FUNCTIONS>\n\nType: C<Array>. Complete ZZPath function definition table.\n\n=back\n\n=head2 Functions\n\n=over\n\n=item C<< first_arg_node(name, ev, ctx, args) >>\n\nParameters: function name, evaluator, context, and argument AST nodes.\nReturns: C<Node> or C<null>. Resolves the first argument or current\ncontext node.\n\n=item C<< first_number_arg(name, ev, ctx, args) >>, C<< nth_number_arg(name, ev, ctx, args, i) >>\n\nParameters: function name, evaluator, context, arguments, and optional\nindex. Returns: C<Number>. Resolves an argument as a number.\n\n=item C<< first_string_arg(name, ev, ctx, args) >>, C<< nth_string_arg(name, ev, ctx, args, i) >>\n\nParameters: function name, evaluator, context, arguments, and optional\nindex. Returns: C<String>. Resolves an argument as a string.\n\n=item C<< nth_value_arg(name, ev, ctx, args, i) >>\n\nParameters: function name, evaluator, context, arguments, and index.\nReturns: value. Resolves an argument as a primitive value.\n\n=item C<< nth_array_arg(name, ev, ctx, args, i) >>\n\nParameters: function name, evaluator, context, arguments, and index.\nReturns: C<Array>. Resolves an argument as an array value.\n\n=item C<< number_args(ev, ctx, args) >>\n\nParameters: evaluator, context, and argument AST nodes. Returns:\nC<Array>. Resolves all arguments as numbers.\n\n=item C<< first_arg_value(name, ev, ctx, args) >>\n\nParameters: function name, evaluator, context, and arguments. Returns:\nvalue. Resolves the first argument as a primitive value.\n\n=item C<< z_function(spelling) >>\n\nParameters: C<spelling> is a base ZPath function name. Returns:\nC<Function>. Returns the inherited function implementation.\n\n=item C<< string_index_of(funk, ev, ast, ctx, args) >>\n\nParameters: standard ZPath function callback arguments. Returns:\nC<Array>. Implements string C<index-of>.\n\n=item C<< string_rindex(funk, ev, ast, ctx, args) >>\n\nParameters: standard ZPath function callback arguments. Returns:\nC<Array>. Implements string reverse-index lookup.\n\n=item C<< defined_function(funk, ev, ast, ctx, args) >>\n\nParameters: standard ZPath function callback arguments. Returns:\nC<Array>. Implements defined-value testing.\n\n=item C<< empty_function(funk, ev, ast, ctx, args) >>\n\nParameters: standard ZPath function callback arguments. Returns:\nC<Array>. Implements empty-value testing.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/zz/functions >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z/functions import Func, STANDARD_FUNCTIONS as Z_STANDARD_FUNCTIONS;\n\n\nconst STANDARD_FUNCTION_NAMES := [\n	"true",\n	"false",\n	"null",\n	"tag",\n	"url",\n	"local-name",\n	"key",\n	"value",\n	"index",\n	"count",\n	"is-first",\n	"is-last",\n	"next",\n	"prev",\n];\n\nfunction first_arg_node ( name, ev, ctx, args ) {\n	if ( args.length() = 0 ) {\n		return ctx.nodeset.get( 0, null );\n	}\n	if ( args.length() = 1 ) {\n		const got := ev.eval_expr( args[0], ev.nested_ctx( ctx ) );\n		return got.get( 0, null );\n	}\n	die `Too many arguments for ${name}()`;\n}\n\nfunction first_number_arg ( name, ev, ctx, args ) {\n	const node := first_arg_node( name, ev, ctx, args );\n	return ev.to_number(node) ?: 0;\n}\n\nfunction nth_number_arg ( name, ev, ctx, args, i ) {\n	die `Not enough arguments for ${name}()` if args.length() <= i;\n	const got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );\n	return ev.to_number( got.get( 0, null ) ) ?: 0;\n}\n\nfunction nth_string_arg ( name, ev, ctx, args, i ) {\n	die `Not enough arguments for ${name}()` if args.length() <= i;\n	const got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );\n	const value := ev.to_string( got.get( 0, null ) );\n	return value \u2261 null ? "" : "" _ value;\n}\n\nfunction nth_value_arg ( name, ev, ctx, args, i ) {\n	die `Not enough arguments for ${name}()` if args.length() <= i;\n	const got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );\n	const node := got.get( 0, null );\n	return node \u2261 null ? null : node.primitive_value();\n}\n\nfunction nth_array_arg ( name, ev, ctx, args, i ) {\n	die `Not enough arguments for ${name}()` if args.length() <= i;\n	const got := ev.eval_expr( args[i], ev.nested_ctx( ctx ) );\n	if ( got.length() = 1 ) {\n		const one := got[0].primitive_value();\n		return one if one instanceof Array;\n	}\n	return got.map( fn node \u2192 node.primitive_value() );\n}\n\nfunction number_args ( ev, ctx, args ) {\n	let nums := [];\n	if ( args.length() = 0 ) {\n		for ( let node in ctx.nodeset ) {\n			const value := ev.to_number(node);\n			nums.push(value) if value instanceof Number;\n		}\n		return nums;\n	}\n	for ( let arg in args ) {\n		const got := ev.eval_expr( arg, ev.nested_ctx( ctx ) );\n		for ( let node in got ) {\n			const value := ev.to_number(node);\n			nums.push(value) if value instanceof Number;\n		}\n	}\n	return nums;\n}\n\nfunction first_string_arg ( name, ev, ctx, args ) {\n	const node := first_arg_node( name, ev, ctx, args );\n	const value := ev.to_string(node);\n	return value \u2261 null ? "" : "" _ value;\n}\n\nfunction first_arg_value ( name, ev, ctx, args ) {\n	const node := first_arg_node( name, ev, ctx, args );\n	return node \u2261 null ? null : node.primitive_value();\n}\n\nfunction z_function ( spelling ) {\n	const func := Z_STANDARD_FUNCTIONS.first( fn f \u2192 f.has_name(spelling) );\n	die `std/path/z/functions is missing ${spelling}()` if func \u2261 null;\n	return func;\n}\n\nfunction string_index_of ( funk, ev, ast, ctx, args ) {\n	from std/string import index;\n	die "Too many arguments for index-of()" if args.length() > 3;\n	if ( args.length() = 2 ) {\n		return funk.wrap( index(\n			nth_string_arg( "index-of", ev, ctx, args, 0 ),\n			nth_string_arg( "index-of", ev, ctx, args, 1 ),\n		) );\n	}\n	return funk.wrap( index(\n		nth_string_arg( "index-of", ev, ctx, args, 0 ),\n		nth_string_arg( "index-of", ev, ctx, args, 1 ),\n		nth_number_arg( "index-of", ev, ctx, args, 2 ),\n	) );\n}\n\nfunction string_rindex ( funk, ev, ast, ctx, args ) {\n	from std/string import rindex;\n	const name := funk.get_spelling;\n	die `Too many arguments for ${name}()` if args.length() > 3;\n	if ( args.length() = 2 ) {\n		return funk.wrap( rindex(\n			nth_string_arg( name, ev, ctx, args, 0 ),\n			nth_string_arg( name, ev, ctx, args, 1 ),\n		) );\n	}\n	return funk.wrap( rindex(\n		nth_string_arg( name, ev, ctx, args, 0 ),\n		nth_string_arg( name, ev, ctx, args, 1 ),\n		nth_number_arg( name, ev, ctx, args, 2 ),\n	) );\n}\n\nfunction defined_function ( funk, ev, ast, ctx, args ) {\n	const node := first_arg_node( "defined", ev, ctx, args );\n	return funk.wrap( node \u2262 null and node.primitive_value() \u2262 null );\n}\n\nfunction empty_function ( funk, ev, ast, ctx, args ) {\n	const value := first_arg_value( "empty", ev, ctx, args );\n	return funk.wrap( true ) if value \u2261 null;\n\n	if (\n		value instanceof Array or\n		value instanceof Bag or\n		value instanceof Set or\n		value instanceof Dict or\n		value instanceof PairList\n	) {\n		return funk.wrap( value.length() = 0 );\n	}\n\n	die `empty() expects a Collection or null, got ${typeof value}`;\n}\n\n// Start with a base of functions inherited from ZPath:\nconst STANDARD_FUNCTIONS := STANDARD_FUNCTION_NAMES.map( fn n \u2192 z_function(n) );\n\n// Add equivalents for ZuzuScript word-like unary operators:\nSTANDARD_FUNCTIONS.push(\n	new Func(\n		spelling: "abs",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( abs first_number_arg( "abs", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "floor",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( floor first_number_arg( "floor", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "ceil",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( ceil first_number_arg( "ceil", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "round",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( round first_number_arg( "round", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "int",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( int first_number_arg( "int", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "sqrt",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( sqrt first_number_arg( "sqrt", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "uc",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( uc first_string_arg( "uc", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "lc",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( lc first_string_arg( "lc", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "length",\n		f: function ( funk, ev, ast, ctx, args ) {\n			return funk.wrap( length first_string_arg( "length", ev, ctx, args ) );\n		},\n	),\n	new Func(\n		spelling: "not",\n		f: function ( funk, ev, ast, ctx, args ) {\n			const node := first_arg_node( "not", ev, ctx, args );\n			return funk.wrap( not ev.truthy(node) );\n		},\n	),\n	new Func(\n		spelling: "typeof",\n		f: function ( funk, ev, ast, ctx, args ) {\n			const node := first_arg_node( "typeof", ev, ctx, args );\n			const value := node \u2261 null ? null : node.primitive_value();\n			return funk.wrap( typeof value );\n		},\n	),\n	new Func(\n		spelling: "defined",\n		f: defined_function,\n	),\n	new Func(\n		spelling: "empty",\n		f: empty_function,\n	),\n);\n\n// Functions from std/internals:\nSTANDARD_FUNCTIONS.push(\n	new Func(\n		spelling: "string",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/internals import to_String;\n			return funk.wrap( to_String( first_arg_value(\n				"string",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "number",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/internals import to_Number;\n			return funk.wrap( to_Number( first_arg_value(\n				"number",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "boolean",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/internals import to_Boolean;\n			return funk.wrap( to_Boolean( first_arg_value(\n				"boolean",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "regexp",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/internals import to_Regexp;\n			return funk.wrap( to_Regexp( first_arg_value(\n				"regexp",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n);\n\n// Functions from std/math:\nSTANDARD_FUNCTIONS.push(\n	new Func(\n		spelling: "sum",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/math import Math;\n			return funk.wrap( Math.sum( number_args( ev, ctx, args ) ) );\n		},\n	),\n	new Func(\n		spelling: "min",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/math import Math;\n			return funk.wrap( Math.min( number_args( ev, ctx, args ) ) );\n		},\n	),\n	new Func(\n		spelling: "max",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/math import Math;\n			return funk.wrap( Math.max( number_args( ev, ctx, args ) ) );\n		},\n	),\n	new Func(\n		spelling: "clamp",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/math import Math;\n			die "Too many arguments for clamp()" if args.length() > 3;\n			return funk.wrap( Math.clamp(\n				nth_number_arg( "clamp", ev, ctx, args, 0 ),\n				nth_number_arg( "clamp", ev, ctx, args, 1 ),\n				nth_number_arg( "clamp", ev, ctx, args, 2 ),\n			) );\n		},\n	),\n);\n\n// Functions from std/string:\nSTANDARD_FUNCTIONS.push(\n	new Func(\n		spelling: "substr",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import substr;\n			die "Too many arguments for substr()" if args.length() > 3;\n			if ( args.length() = 2 ) {\n				return funk.wrap( substr(\n					nth_string_arg( "substr", ev, ctx, args, 0 ),\n					nth_number_arg( "substr", ev, ctx, args, 1 ),\n				) );\n			}\n			return funk.wrap( substr(\n				nth_string_arg( "substr", ev, ctx, args, 0 ),\n				nth_number_arg( "substr", ev, ctx, args, 1 ),\n				nth_number_arg( "substr", ev, ctx, args, 2 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "index-of",\n		f: string_index_of,\n	),\n	new Func(\n		spelling: "rindex",\n		f: string_rindex,\n	),\n	new Func(\n		spelling: "last-index-of",\n		f: string_rindex,\n	),\n	new Func(\n		spelling: "contains",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import contains;\n			die "Too many arguments for contains()" if args.length() > 2;\n			return funk.wrap( contains(\n				nth_string_arg( "contains", ev, ctx, args, 0 ),\n				nth_string_arg( "contains", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "chr",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import chr;\n			die "Too many arguments for chr()" if args.length() > 1;\n			return funk.wrap( chr( nth_number_arg(\n				"chr",\n				ev,\n				ctx,\n				args,\n				0,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "ord",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import ord;\n			die "Too many arguments for ord()" if args.length() > 2;\n			if ( args.length() = 1 ) {\n				return funk.wrap( ord( nth_string_arg(\n					"ord",\n					ev,\n					ctx,\n					args,\n					0,\n				) ) );\n			}\n			return funk.wrap( ord(\n				nth_string_arg( "ord", ev, ctx, args, 0 ),\n				nth_number_arg( "ord", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "replace",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import replace;\n			die "Too many arguments for replace()" if args.length() > 4;\n			if ( args.length() = 3 ) {\n				return funk.wrap( replace(\n					nth_string_arg( "replace", ev, ctx, args, 0 ),\n					nth_value_arg( "replace", ev, ctx, args, 1 ),\n					nth_string_arg( "replace", ev, ctx, args, 2 ),\n				) );\n			}\n			return funk.wrap( replace(\n				nth_string_arg( "replace", ev, ctx, args, 0 ),\n				nth_value_arg( "replace", ev, ctx, args, 1 ),\n				nth_string_arg( "replace", ev, ctx, args, 2 ),\n				nth_string_arg( "replace", ev, ctx, args, 3 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "search",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import search;\n			die "Too many arguments for search()" if args.length() > 3;\n			if ( args.length() = 2 ) {\n				return funk.wrap( search(\n					nth_string_arg( "search", ev, ctx, args, 0 ),\n					nth_value_arg( "search", ev, ctx, args, 1 ),\n				) );\n			}\n			return funk.wrap( search(\n				nth_string_arg( "search", ev, ctx, args, 0 ),\n				nth_value_arg( "search", ev, ctx, args, 1 ),\n				nth_string_arg( "search", ev, ctx, args, 2 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "starts_with",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import starts_with;\n			die "Too many arguments for starts_with()" if args.length() > 2;\n			return funk.wrap( starts_with(\n				nth_string_arg( "starts_with", ev, ctx, args, 0 ),\n				nth_string_arg( "starts_with", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "ends_with",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import ends_with;\n			die "Too many arguments for ends_with()" if args.length() > 2;\n			return funk.wrap( ends_with(\n				nth_string_arg( "ends_with", ev, ctx, args, 0 ),\n				nth_string_arg( "ends_with", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "matches",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import matches;\n			die "Too many arguments for matches()" if args.length() > 3;\n			if ( args.length() = 2 ) {\n				return funk.wrap( matches(\n					nth_string_arg( "matches", ev, ctx, args, 0 ),\n					nth_value_arg( "matches", ev, ctx, args, 1 ),\n				) );\n			}\n			return funk.wrap( matches(\n				nth_string_arg( "matches", ev, ctx, args, 0 ),\n				nth_value_arg( "matches", ev, ctx, args, 1 ),\n				nth_string_arg( "matches", ev, ctx, args, 2 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "pattern_to_regexp",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import pattern_to_regexp;\n			die "Too many arguments for pattern_to_regexp()"\n				if args.length() > 2;\n			if ( args.length() = 1 ) {\n				return funk.wrap( pattern_to_regexp(\n					nth_string_arg( "pattern_to_regexp", ev, ctx, args, 0 ),\n				) );\n			}\n			return funk.wrap( pattern_to_regexp(\n				nth_string_arg( "pattern_to_regexp", ev, ctx, args, 0 ),\n				nth_value_arg( "pattern_to_regexp", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "quotemeta",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import quotemeta;\n			die "Too many arguments for quotemeta()" if args.length() > 1;\n			return funk.wrap( quotemeta(\n				nth_string_arg( "quotemeta", ev, ctx, args, 0 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "sprint",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import sprint;\n			die "Not enough arguments for sprint()" if args.length() = 0;\n			die "Too many arguments for sprint()" if args.length() > 8;\n\n			const fmt := nth_string_arg( "sprint", ev, ctx, args, 0 );\n			if ( args.length() = 1 ) {\n				return funk.wrap( sprint(fmt) );\n			}\n			if ( args.length() = 2 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n				) );\n			}\n			if ( args.length() = 3 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n					nth_value_arg( "sprint", ev, ctx, args, 2 ),\n				) );\n			}\n			if ( args.length() = 4 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n					nth_value_arg( "sprint", ev, ctx, args, 2 ),\n					nth_value_arg( "sprint", ev, ctx, args, 3 ),\n				) );\n			}\n			if ( args.length() = 5 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n					nth_value_arg( "sprint", ev, ctx, args, 2 ),\n					nth_value_arg( "sprint", ev, ctx, args, 3 ),\n					nth_value_arg( "sprint", ev, ctx, args, 4 ),\n				) );\n			}\n			if ( args.length() = 6 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n					nth_value_arg( "sprint", ev, ctx, args, 2 ),\n					nth_value_arg( "sprint", ev, ctx, args, 3 ),\n					nth_value_arg( "sprint", ev, ctx, args, 4 ),\n					nth_value_arg( "sprint", ev, ctx, args, 5 ),\n				) );\n			}\n			if ( args.length() = 7 ) {\n				return funk.wrap( sprint(\n					fmt,\n					nth_value_arg( "sprint", ev, ctx, args, 1 ),\n					nth_value_arg( "sprint", ev, ctx, args, 2 ),\n					nth_value_arg( "sprint", ev, ctx, args, 3 ),\n					nth_value_arg( "sprint", ev, ctx, args, 4 ),\n					nth_value_arg( "sprint", ev, ctx, args, 5 ),\n					nth_value_arg( "sprint", ev, ctx, args, 6 ),\n				) );\n			}\n			return funk.wrap( sprint(\n				fmt,\n				nth_value_arg( "sprint", ev, ctx, args, 1 ),\n				nth_value_arg( "sprint", ev, ctx, args, 2 ),\n				nth_value_arg( "sprint", ev, ctx, args, 3 ),\n				nth_value_arg( "sprint", ev, ctx, args, 4 ),\n				nth_value_arg( "sprint", ev, ctx, args, 5 ),\n				nth_value_arg( "sprint", ev, ctx, args, 6 ),\n				nth_value_arg( "sprint", ev, ctx, args, 7 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "split",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import split;\n			die "Too many arguments for split()" if args.length() > 3;\n			if ( args.length() = 2 ) {\n				return funk.wrap( split(\n					nth_string_arg( "split", ev, ctx, args, 0 ),\n					nth_value_arg( "split", ev, ctx, args, 1 ),\n				) );\n			}\n			return funk.wrap( split(\n				nth_string_arg( "split", ev, ctx, args, 0 ),\n				nth_value_arg( "split", ev, ctx, args, 1 ),\n				nth_number_arg( "split", ev, ctx, args, 2 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "join",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import join;\n			die "Too many arguments for join()" if args.length() > 2;\n			return funk.wrap( join(\n				nth_string_arg( "join", ev, ctx, args, 0 ),\n				nth_array_arg( "join", ev, ctx, args, 1 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "trim",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import trim;\n			die "Too many arguments for trim()" if args.length() > 1;\n			return funk.wrap( trim( first_string_arg(\n				"trim",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "pad",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import pad;\n			die "Too many arguments for pad()" if args.length() > 4;\n			if ( args.length() = 2 ) {\n				return funk.wrap( pad(\n					nth_string_arg( "pad", ev, ctx, args, 0 ),\n					nth_number_arg( "pad", ev, ctx, args, 1 ),\n				) );\n			}\n			if ( args.length() = 3 ) {\n				return funk.wrap( pad(\n					nth_string_arg( "pad", ev, ctx, args, 0 ),\n					nth_number_arg( "pad", ev, ctx, args, 1 ),\n					nth_string_arg( "pad", ev, ctx, args, 2 ),\n				) );\n			}\n			return funk.wrap( pad(\n				nth_string_arg( "pad", ev, ctx, args, 0 ),\n				nth_number_arg( "pad", ev, ctx, args, 1 ),\n				nth_string_arg( "pad", ev, ctx, args, 2 ),\n				nth_string_arg( "pad", ev, ctx, args, 3 ),\n			) );\n		},\n	),\n	new Func(\n		spelling: "chomp",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import chomp;\n			die "Too many arguments for chomp()" if args.length() > 1;\n			return funk.wrap( chomp( first_string_arg(\n				"chomp",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "title",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import title;\n			die "Too many arguments for title()" if args.length() > 1;\n			return funk.wrap( title( first_string_arg(\n				"title",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "snake",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import snake;\n			die "Too many arguments for snake()" if args.length() > 1;\n			return funk.wrap( snake( first_string_arg(\n				"snake",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "kebab",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import kebab;\n			die "Too many arguments for kebab()" if args.length() > 1;\n			return funk.wrap( kebab( first_string_arg(\n				"kebab",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n	new Func(\n		spelling: "camel",\n		f: function ( funk, ev, ast, ctx, args ) {\n			from std/string import camel;\n			die "Too many arguments for camel()" if args.length() > 1;\n			return funk.wrap( camel( first_string_arg(\n				"camel",\n				ev,\n				ctx,\n				args,\n			) ) );\n		},\n	),\n);\n';
        virtualFiles["/modules/std/path/zz/operators.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/path/zz/operators - Operator definitions for ZZPath expressions.\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nThis module extends the base ZPath operator model with\nZuzuScript-flavoured expression operators.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<Operator>\n\nZZPath operator class extending C<std/path/z/operators> C<Operator>.\n\n=back\n\n=head2 Functions\n\n=over\n\n=item C<< string_operand(ev, ctx, expr) >>, C<< string_operands(ev, ctx, left, right) >>\n\nParameters: evaluator, context, and expression AST nodes. Returns:\nC<String> or C<Array>. Evaluates one or two operands as strings.\n\n=item C<< first_eval_value(values) >>, C<< primitive_eval_value(values) >>\n\nParameters: C<values> is an evaluated node array. Returns: value.\nExtracts the first or primitive value used by ZZPath operators.\n\n=item C<< collection_operand(ev, ctx, expr) >>\n\nParameters: evaluator, context, and expression AST node. Returns:\ncollection value. Evaluates an operand for collection operators.\n\n=item C<< builtin_can(value, method_name) >>\n\nParameters: C<value> is any value and C<method_name> is a method name.\nReturns: C<Boolean>. Tests whether built-in values support a method.\n\n=back\n\n=head2 Constants\n\n=over\n\n=item C<STANDARD_OPERATORS>\n\nType: C<Array>. Complete ZZPath operator definition table.\n\n=item C<logical_negation>, C<logical_and>, C<logical_nand>, C<logical_xor>, C<logical_or>\n\nType: C<Function>. Logical operator implementations.\n\n=item C<numeric_power>, C<numeric_multiplication>, C<numeric_division>, C<numeric_modulus>, C<numeric_addition>, C<numeric_subtraction>, C<numeric_equality>, C<numeric_inequality>, C<numeric_less_than>, C<numeric_greater_than>, C<numeric_less_than_or_equal>, C<numeric_greater_than_or_equal>, C<numeric_compare>\n\nType: C<Function>. Numeric operator implementations.\n\n=item C<string_concatenation>, C<string_equality>, C<string_inequality>, C<string_greater_than>, C<string_greater_than_or_equal>, C<string_less_than>, C<string_less_than_or_equal>, C<string_compare>, C<string_equality_insensitive>, C<string_inequality_insensitive>, C<string_greater_than_insensitive>, C<string_greater_than_or_equal_insensitive>, C<string_less_than_insensitive>, C<string_less_than_or_equal_insensitive>, C<string_compare_insensitive>\n\nType: C<Function>. String operator implementations.\n\n=item C<regexp_match>, C<bitwise_and>, C<bitwise_xor>, C<bitwise_or>, C<set_union>, C<set_intersection>, C<set_difference>, C<collection_membership>, C<collection_non_membership>, C<set_subsetof>, C<set_supersetof>, C<set_equivalentof>, C<type_aware_equality>, C<type_aware_inequality>, C<object_can>\n\nType: C<Function>. Regular expression, bitwise, collection, type-aware,\nand object capability operator implementations.\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/path/zz/operators >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/path/z/operators import Operator as ZOperator;\n\n\nclass Operator extends ZOperator;\n\nconst logical_negation := function ( op, ev, ast, ctx, expr ) {\n	const got := ev.eval_expr( expr, ev.nested_ctx( ctx ) );\n	const value := got.length() > 0 ? got[0] : null;\n	return op.wrap( not ev.truthy(value) );\n};\n\nconst numeric_power := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val ** right_val );\n};\n\nconst numeric_multiplication := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val \xD7 right_val );\n};\n\nconst numeric_division := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val \xF7 right_val );\n};\n\nconst numeric_modulus := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val mod right_val );\n};\n\nconst numeric_addition := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val + right_val );\n};\n\nconst numeric_subtraction := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val - right_val );\n};\n\nconst numeric_equality := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val = right_val );\n};\n\nconst numeric_inequality := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val \u2260 right_val );\n};\n\nconst numeric_less_than := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val < right_val );\n};\n\nconst numeric_greater_than := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val > right_val );\n};\n\nconst numeric_less_than_or_equal := function (\n	op,\n	ev,\n	ast,\n	ctx,\n	left,\n	right,\n) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val \u2264 right_val );\n};\n\nconst numeric_greater_than_or_equal := function (\n	op,\n	ev,\n	ast,\n	ctx,\n	left,\n	right,\n) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val \u2265 right_val );\n};\n\nconst numeric_compare := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val <=> right_val );\n};\n\nfunction string_operand ( ev, ctx, expr ) {\n	const result := ev.eval_expr( expr, ev.nested_ctx( ctx ) );\n	return "" unless result.length;\n	const value := ev.to_string( result[0] );\n	return value \u2261 null ? "" : "" _ value;\n}\n\nfunction string_operands ( ev, ctx, left, right ) {\n	return [\n		string_operand( ev, ctx, left ),\n		string_operand( ev, ctx, right ),\n	];\n}\n\nconst string_concatenation := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] _ values[1] );\n};\n\nconst string_equality := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] eq values[1] );\n};\n\nconst string_inequality := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] ne values[1] );\n};\n\nconst string_greater_than := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] gt values[1] );\n};\n\nconst string_greater_than_or_equal := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] ge values[1] );\n};\n\nconst string_less_than := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] lt values[1] );\n};\n\nconst string_less_than_or_equal := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] le values[1] );\n};\n\nconst string_compare := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] cmp values[1] );\n};\n\nconst string_equality_insensitive := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val eq right_val );\n};\n\nconst string_inequality_insensitive := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val ne right_val );\n};\n\nconst string_greater_than_insensitive := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val gt right_val );\n};\n\nconst string_greater_than_or_equal_insensitive := function (\n	op,\n	ev,\n	ast,\n	ctx,\n	left,\n	right,\n) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val ge right_val );\n};\n\nconst string_less_than_insensitive := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val lt right_val );\n};\n\nconst string_less_than_or_equal_insensitive := function (\n	op,\n	ev,\n	ast,\n	ctx,\n	left,\n	right,\n) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val le right_val );\n};\n\nconst string_compare_insensitive := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	const left_val := lc values[0];\n	const right_val := lc values[1];\n	return op.wrap( left_val cmp right_val );\n};\n\nconst regexp_match := function ( op, ev, ast, ctx, left, right ) {\n	const values := string_operands( ev, ctx, left, right );\n	return op.wrap( values[0] ~ values[1] );\n};\n\nconst bitwise_and := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val & right_val );\n};\n\nconst bitwise_xor := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val ^ right_val );\n};\n\nconst bitwise_or := function ( op, ev, ast, ctx, left, right ) {\n	const left_val  := op._handle_numeric_operand( ev, ctx, left );\n	const right_val := op._handle_numeric_operand( ev, ctx, right );\n	return op.wrap( left_val | right_val );\n};\n\nfunction first_eval_value ( values ) {\n	return values.length() > 0 ? values[0] : null;\n}\n\nfunction primitive_eval_value ( values ) {\n	const first := first_eval_value(values);\n	return first \u2261 null ? null : first.primitive_value();\n}\n\nfunction collection_operand ( ev, ctx, expr ) {\n	const values := ev.eval_expr( expr, ev.nested_ctx( ctx ) );\n	if ( values.length() = 1 ) {\n		return values[0].primitive_value();\n	}\n	return values.map( fn value \u2192 value.primitive_value() );\n}\n\nconst logical_and := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	if ( ev.truthy( first_eval_value(left_vals) ) ) {\n		return ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	}\n	return op.wrap(false);\n};\n\nconst logical_nand := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	if ( not ev.truthy( first_eval_value(left_vals) ) ) {\n		return op.wrap(true);\n	}\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	return op.wrap( ev.truthy( first_eval_value(right_vals) ) ? false : true );\n};\n\nconst logical_xor := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	const left_truth := ev.truthy( first_eval_value(left_vals) );\n	const right_truth := ev.truthy( first_eval_value(right_vals) );\n	return op.wrap( ( left_truth xor right_truth ) ? true : false );\n};\n\nconst logical_or := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	if ( ev.truthy( first_eval_value(left_vals) ) ) {\n		return op.wrap(true);\n	}\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	return op.wrap( ev.truthy( first_eval_value(right_vals) ) ? true : false );\n};\n\nconst set_union := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val union right_val );\n};\n\nconst set_intersection := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val intersection right_val );\n};\n\nconst set_difference := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val \u2216 right_val );\n};\n\nconst collection_membership := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const left_val := primitive_eval_value(left_vals);\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val in right_val );\n};\n\nconst collection_non_membership := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const left_val := primitive_eval_value(left_vals);\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val \u2209 right_val );\n};\n\nconst set_subsetof := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val subsetof right_val );\n};\n\nconst set_supersetof := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val supersetof right_val );\n};\n\nconst set_equivalentof := function ( op, ev, ast, ctx, left, right ) {\n	const left_val := collection_operand( ev, ctx, left );\n	const right_val := collection_operand( ev, ctx, right );\n	return op.wrap( left_val equivalentof right_val );\n};\n\nconst type_aware_equality := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	return op.wrap( ev.equals(\n		first_eval_value(left_vals),\n		first_eval_value(right_vals),\n	) );\n};\n\nconst type_aware_inequality := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	return op.wrap( not ev.equals(\n		first_eval_value(left_vals),\n		first_eval_value(right_vals),\n	) );\n};\n\nfunction builtin_can ( value, method_name ) {\n	return false if value \u2261 null\n		or method_name \u2261 null\n		or method_name eq "";\n\n	if ( value instanceof Array or value instanceof Bag or value instanceof Set ) {\n		return method_name in [\n			"length",\n			"empty",\n			"contains",\n			"push",\n			"to_Array",\n			"to_Bag",\n			"to_Set",\n		];\n	}\n	if ( value instanceof Dict or value instanceof PairList ) {\n		return method_name in [\n			"length",\n			"empty",\n			"exists",\n			"keys",\n			"values",\n			"to_Array",\n		];\n	}\n	if ( value instanceof String or value instanceof BinaryString ) {\n		return method_name in [ "length" ];\n	}\n	return false;\n}\n\nconst object_can := function ( op, ev, ast, ctx, left, right ) {\n	const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );\n	const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );\n	const left_val := primitive_eval_value(left_vals);\n	const right_val := primitive_eval_value(right_vals);\n	return op.wrap(\n		( left_val can (right_val) ) or builtin_can( left_val, right_val )\n	);\n};\n\nconst STANDARD_OPERATORS := [\n	new Operator(\n		spelling: "?:",\n		kind: "ELVIS",\n		precedence: 1,\n		lex_ignore: true,\n	),\n\n	new Operator(\n		spelling: "+",\n		kind: "UPLUS",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const value := op._handle_numeric_operand( ev, ctx, expr );\n			return op.wrap( +value );\n		},\n	),\n\n	new Operator(\n		spelling: "-",\n		kind: "UMINUS",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const value := op._handle_numeric_operand( ev, ctx, expr );\n			return op.wrap( -value );\n		},\n	),\n\n	new Operator(\n		spelling: "\u221A",\n		kind: "SQRT",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const value := op._handle_numeric_operand( ev, ctx, expr );\n			return op.wrap( sqrt value );\n		},\n	),\n\n	new Operator(\n		spelling: "!",\n		kind: "NOT",\n		unary: true,\n		precedence: 20,\n		f: logical_negation,\n	),\n\n	new Operator(\n		spelling: "\xAC",\n		kind: "NOTSYM",\n		unary: true,\n		precedence: 20,\n		f: logical_negation,\n	),\n\n	new Operator(\n		spelling: "**",\n		kind: "POW",\n		require_ws: true,\n		right_assoc: true,\n		precedence: 13,\n		f: numeric_power,\n	),\n\n	new Operator(\n		spelling: "\xD7",\n		kind: "TIMES_SIGN",\n		precedence: 12,\n		f: numeric_multiplication,\n	),\n\n	new Operator(\n		spelling: "*",\n		kind: "TIMES",\n		require_ws: true,\n		precedence: 12,\n		lex_ignore: true,\n		alias: "STAR",\n		f: numeric_multiplication,\n	),\n\n	new Operator(\n		spelling: "\xF7",\n		kind: "DIVIDE_SIGN",\n		precedence: 12,\n		f: numeric_division,\n	),\n\n	new Operator(\n		spelling: "/",\n		kind: "DIVIDE",\n		require_ws: true,\n		precedence: 12,\n		lex_ignore: true,\n		alias: "SLASH",\n		f: numeric_division,\n	),\n\n	new Operator(\n		spelling: "mod",\n		kind: "MOD",\n		precedence: 12,\n		f: numeric_modulus,\n	),\n\n	new Operator(\n		spelling: "+",\n		kind: "PLUS",\n		require_ws: true,\n		precedence: 11,\n		f: numeric_addition,\n	),\n\n	new Operator(\n		spelling: "-",\n		kind: "MINUS",\n		require_ws: true,\n		precedence: 11,\n		f: numeric_subtraction,\n	),\n\n	new Operator(\n		spelling: "=",\n		kind: "EQ",\n		precedence: 5,\n		f: numeric_equality,\n	),\n\n	new Operator(\n		spelling: "\u2260",\n		kind: "NE",\n		precedence: 5,\n		f: numeric_inequality,\n	),\n\n	new Operator(\n		spelling: "<",\n		kind: "LT",\n		precedence: 5,\n		f: numeric_less_than,\n	),\n\n	new Operator(\n		spelling: ">",\n		kind: "GT",\n		precedence: 5,\n		f: numeric_greater_than,\n	),\n\n	new Operator(\n		spelling: "\u2264",\n		kind: "LE_SIGN",\n		precedence: 5,\n		f: numeric_less_than_or_equal,\n	),\n\n	new Operator(\n		spelling: "<=",\n		kind: "LE",\n		precedence: 5,\n		f: numeric_less_than_or_equal,\n	),\n\n	new Operator(\n		spelling: "\u2265",\n		kind: "GE_SIGN",\n		precedence: 5,\n		f: numeric_greater_than_or_equal,\n	),\n\n	new Operator(\n		spelling: ">=",\n		kind: "GE",\n		precedence: 5,\n		f: numeric_greater_than_or_equal,\n	),\n\n	new Operator(\n		spelling: "\u2276",\n		kind: "CMP_SIGN",\n		precedence: 5,\n		f: numeric_compare,\n	),\n\n	new Operator(\n		spelling: "<=>",\n		kind: "CMP",\n		precedence: 5,\n		f: numeric_compare,\n	),\n\n	new Operator(\n		spelling: "\u2277",\n		kind: "CMP_REV_SIGN",\n		precedence: 5,\n		f: numeric_compare,\n	),\n\n	new Operator(\n		spelling: "_",\n		kind: "CONCAT",\n		require_ws: true,\n		precedence: 10,\n		f: string_concatenation,\n	),\n\n	new Operator(\n		spelling: "eq",\n		kind: "STR_EQ",\n		precedence: 5,\n		f: string_equality,\n	),\n\n	new Operator(\n		spelling: "ne",\n		kind: "STR_NE",\n		precedence: 5,\n		f: string_inequality,\n	),\n\n	new Operator(\n		spelling: "gt",\n		kind: "STR_GT",\n		precedence: 5,\n		f: string_greater_than,\n	),\n\n	new Operator(\n		spelling: "ge",\n		kind: "STR_GE",\n		precedence: 5,\n		f: string_greater_than_or_equal,\n	),\n\n	new Operator(\n		spelling: "lt",\n		kind: "STR_LT",\n		precedence: 5,\n		f: string_less_than,\n	),\n\n	new Operator(\n		spelling: "le",\n		kind: "STR_LE",\n		precedence: 5,\n		f: string_less_than_or_equal,\n	),\n\n	new Operator(\n		spelling: "cmp",\n		kind: "STR_CMP",\n		precedence: 5,\n		f: string_compare,\n	),\n\n	new Operator(\n		spelling: "eqi",\n		kind: "STR_EQI",\n		precedence: 5,\n		f: string_equality_insensitive,\n	),\n\n	new Operator(\n		spelling: "nei",\n		kind: "STR_NEI",\n		precedence: 5,\n		f: string_inequality_insensitive,\n	),\n\n	new Operator(\n		spelling: "gti",\n		kind: "STR_GTI",\n		precedence: 5,\n		f: string_greater_than_insensitive,\n	),\n\n	new Operator(\n		spelling: "gei",\n		kind: "STR_GEI",\n		precedence: 5,\n		f: string_greater_than_or_equal_insensitive,\n	),\n\n	new Operator(\n		spelling: "lti",\n		kind: "STR_LTI",\n		precedence: 5,\n		f: string_less_than_insensitive,\n	),\n\n	new Operator(\n		spelling: "lei",\n		kind: "STR_LEI",\n		precedence: 5,\n		f: string_less_than_or_equal_insensitive,\n	),\n\n	new Operator(\n		spelling: "cmpi",\n		kind: "STR_CMPI",\n		precedence: 5,\n		f: string_compare_insensitive,\n	),\n\n	new Operator(\n		spelling: "~",\n		kind: "REGEXP_MATCH",\n		precedence: 5,\n		f: regexp_match,\n	),\n\n	new Operator(\n		spelling: "&",\n		kind: "BAND",\n		precedence: 8,\n		f: bitwise_and,\n	),\n\n	new Operator(\n		spelling: "^",\n		kind: "BXOR",\n		precedence: 7,\n		f: bitwise_xor,\n	),\n\n	new Operator(\n		spelling: "|",\n		kind: "BOR",\n		precedence: 6,\n		f: bitwise_or,\n	),\n\n	new Operator(\n		spelling: "\u22C0",\n		kind: "LAND_SIGN",\n		precedence: 3,\n		f: logical_and,\n	),\n\n	new Operator(\n		spelling: "and",\n		kind: "LAND",\n		precedence: 3,\n		f: logical_and,\n	),\n\n	new Operator(\n		spelling: "\u22BC",\n		kind: "LNAND_SIGN",\n		precedence: 3,\n		f: logical_nand,\n	),\n\n	new Operator(\n		spelling: "nand",\n		kind: "LNAND",\n		precedence: 3,\n		f: logical_nand,\n	),\n\n	new Operator(\n		spelling: "\u22BB",\n		kind: "LXOR_SIGN",\n		precedence: 2,\n		f: logical_xor,\n	),\n\n	new Operator(\n		spelling: "xor",\n		kind: "LXOR",\n		precedence: 2,\n		f: logical_xor,\n	),\n\n	new Operator(\n		spelling: "\u22C1",\n		kind: "LOR_SIGN",\n		precedence: 1,\n		f: logical_or,\n	),\n\n	new Operator(\n		spelling: "or",\n		kind: "LOR",\n		precedence: 1,\n		f: logical_or,\n	),\n\n	new Operator(\n		spelling: "\u22C3",\n		kind: "SET_UNION_SIGN",\n		precedence: 9,\n		f: set_union,\n	),\n\n	new Operator(\n		spelling: "union",\n		kind: "SET_UNION",\n		precedence: 9,\n		f: set_union,\n	),\n\n	new Operator(\n		spelling: "\u22C2",\n		kind: "SET_INTERSECTION_SIGN",\n		precedence: 9,\n		f: set_intersection,\n	),\n\n	new Operator(\n		spelling: "intersection",\n		kind: "SET_INTERSECTION",\n		precedence: 9,\n		f: set_intersection,\n	),\n\n	new Operator(\n		spelling: "\u2216",\n		kind: "SET_DIFFERENCE_SIGN",\n		precedence: 9,\n		f: set_difference,\n	),\n\n	new Operator(\n		spelling: "\\\\",\n		kind: "SET_DIFFERENCE",\n		precedence: 9,\n		require_ws: true,\n		f: set_difference,\n	),\n\n	new Operator(\n		spelling: "\u2208",\n		kind: "MEMBER_SIGN",\n		precedence: 5,\n		f: collection_membership,\n	),\n\n	new Operator(\n		spelling: "in",\n		kind: "MEMBER",\n		precedence: 5,\n		f: collection_membership,\n	),\n\n	new Operator(\n		spelling: "\u2209",\n		kind: "NOT_MEMBER_SIGN",\n		precedence: 5,\n		f: collection_non_membership,\n	),\n\n	new Operator(\n		spelling: "\u2282",\n		kind: "SUBSETOF_SIGN",\n		precedence: 5,\n		f: set_subsetof,\n	),\n\n	new Operator(\n		spelling: "subsetof",\n		kind: "SUBSETOF",\n		precedence: 5,\n		f: set_subsetof,\n	),\n\n	new Operator(\n		spelling: "\u2283",\n		kind: "SUPERSETOF_SIGN",\n		precedence: 5,\n		f: set_supersetof,\n	),\n\n	new Operator(\n		spelling: "supersetof",\n		kind: "SUPERSETOF",\n		precedence: 5,\n		f: set_supersetof,\n	),\n\n	new Operator(\n		spelling: "\u2282\u2283",\n		kind: "EQUIVALENTOF_SIGN",\n		precedence: 5,\n		f: set_equivalentof,\n	),\n\n	new Operator(\n		spelling: "equivalentof",\n		kind: "EQUIVALENTOF",\n		precedence: 5,\n		f: set_equivalentof,\n	),\n\n	new Operator(\n		spelling: "\u2261",\n		kind: "TYPE_EQ_SIGN",\n		precedence: 4,\n		f: type_aware_equality,\n	),\n\n	new Operator(\n		spelling: "==",\n		kind: "TYPE_EQ",\n		precedence: 4,\n		f: type_aware_equality,\n	),\n\n	new Operator(\n		spelling: "\u2262",\n		kind: "TYPE_NE_SIGN",\n		precedence: 4,\n		f: type_aware_inequality,\n	),\n\n	new Operator(\n		spelling: "!=",\n		kind: "TYPE_NE",\n		precedence: 4,\n		f: type_aware_inequality,\n	),\n\n	new Operator(\n		spelling: "can",\n		kind: "CAN",\n		precedence: 5,\n		f: object_can,\n	),\n\n	new Operator(\n		spelling: "~",\n		kind: "BNOT",\n		unary: true,\n		precedence: 20,\n		f: function ( op, ev, ast, ctx, expr ) {\n			const value := op._handle_numeric_operand( ev, ctx, expr );\n			return op.wrap( ~value );\n		},\n	),\n];\n';
        virtualFiles["/modules/std/template/z.zzm"] = '=encoding utf8\n\n=head1 NAME\n\nstd/template/z - Pure ZuzuScript template engine.\n\n=head1 SYNOPSIS\n\n  from std/template/z import ZTemplate;\n\n  let inline := new ZTemplate(\n    string: "Hello {{ user/name }}!",\n  );\n  say( inline.process( { user: { name: "Ada" } } ) );\n\n  let file_tmpl := new ZTemplate(\n    file: "templates/page.zt",\n    escape: "html",\n  );\n  say( file_tmpl.process( data ) );\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and\nElectron. It is partially supported by zuzu-js in the browser: complex,\nHTTP/JSON/ZPath pipeline, self-contained, and trait-object rendering\ncoverage passes, but filesystem-backed template loading and database row\nrendering coverage are unsupported.\n\n=head1 DESCRIPTION\n\nC<std/template/z> is a pure ZuzuScript template renderer.\n\nThe module compiles template text into a cached parse tree and renders\nit against data using C<std/path/z> expressions.\n\n=head1 EXPORTS\n\n=head2 Classes\n\n=over\n\n=item C<< ZTemplate({ string?: String, file?, escape?: String, includes?: Boolean }) >>\n\nConstructs a template from inline text or a file path. Returns:\nC<ZTemplate>.\n\n=over\n\n=item C<< template.process(data) >>\n\nParameters: C<data> is the model used for path lookups. Returns:\nC<String>. Renders the template.\n\n=back\n\n=back\n\n=head1 TAG FORMS\n\n=over 4\n\n=item * C<{{ expr }}>\n\nRender expression output using template default escaping.\n\n=item * C<{{ expr :: raw }}>, C<{{ expr :: html }}>\n\nRender expression output using per-tag escape override.\n\n=item * C<{{# expr }}> ... C<{{/expr}}>\n\nBlock form. Each truthy match renders child nodes.\n\n=item * C<{{> include.zt }}>\n\nInclude another template file. Relative include paths resolve from the\ncurrent template\'s file directory.\n\n=back\n\n=head1 ESCAPING\n\nDefault escape mode is C<html>. Supported escape modes are C<html> and\nC<raw>.\n\nC<html> escapes C<&>, C<< < >>, C<E<gt>>, double quotes, and single\nquotes.\n\n=head1 INCLUDE RULES\n\n=over 4\n\n=item * Include processing is enabled by default.\n\n=item * Pass C<includes: false> to disable include tags.\n\n=item * Relative includes require a file-backed template source.\n\n=item * Circular include chains throw a deterministic error.\n\n=back\n\n=head1 KNOWN DIFFERENCES\n\nThis module is implemented on top of C<std/path/z>. Parser/rendering\ndeltas across runtimes are covered in ztests and should be treated as\nimplementation bugs unless explicitly documented.\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< std/template/z >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n\nfrom std/string import index, substr, trim;\nfrom std/path/z import ZPath;\n\nclass ZTemplate {\n	let string;\n	let file;\n	let String escape := "html";\n	let includes := true;\n	let source_file := null;\n	let Array tree := [];\n	let compiled_paths := {};\n\n	method __build__ () {\n		let has_string := string \u2262 null;\n		let has_file := file \u2262 null;\n\n		if ( has_string and has_file ) {\n			die "Specify only one of \\"string\\" or \\"file\\"";\n		}\n		if ( not has_string and not has_file ) {\n			die "Missing template source: provide \\"string\\" or \\"file\\"";\n		}\n\n		escape := lc( "" _ escape );\n		if ( escape \u2262 "html" and escape \u2262 "raw" ) {\n			die `Invalid escape mode "${escape}"`;\n		}\n\n		if ( has_file ) {\n			let loaded := self._read_template_file(file);\n			string := loaded{text};\n			source_file := loaded{file};\n		}\n\n		tree := self._parse_template(\n			template: string \u2261 null ? "": string,\n			current_file: source_file,\n			seen_files: {},\n			includes: includes,\n		);\n	}\n\n	method process ( data ) {\n		die "process() requires a data model" if data \u2261 null;\n\n		return self._render_nodes(\n			nodes: tree,\n			context: data,\n			eval_meta: {},\n			default_escape: escape,\n		);\n	}\n\n	method _parse_template ( ... PairList args ) {\n		let template := args.get( "template", "" );\n		let current_file := args.get( "current_file", null );\n		let seen_files := args.get( "seen_files", {} );\n		let includes_enabled := args.get( "includes", true );\n		let root := [];\n\n		let stack := [\n			{\n				expr: null,\n				nodes: root,\n			},\n		];\n\n		let pos := 0;\n		while ( true ) {\n			let tag_open := index( template, "{{", pos );\n			last if tag_open < 0;\n\n			let text := substr( template, pos, tag_open - pos );\n			self._push_text( stack[ stack.length() - 1 ]{nodes}, text );\n\n			let tag_close := index( template, "}}", tag_open + 2 );\n			if ( tag_close < 0 ) {\n				die `Unterminated tag at character ${tag_open}`;\n			}\n\n			let raw := substr( template, tag_open + 2, tag_close - tag_open - 2 );\n			let tagged := trim(raw);\n\n			if ( substr( tagged, 0, 1 ) \u2261 "#" ) {\n				let inner := trim( substr( tagged, 1 ) );\n				let parsed := self._parse_expression_spec(inner);\n				let block := {\n					type: "block",\n					expr_src: parsed{expr},\n					nodes: [],\n				};\n				stack[ stack.length() - 1 ]{nodes}.push(block);\n				stack.push( {\n					expr: parsed{expr},\n					nodes: block{nodes},\n				} );\n			}\n			else if ( substr( tagged, 0, 1 ) \u2261 "/" ) {\n				let inner := trim( substr( tagged, 1 ) );\n				let current := stack.pop();\n				if ( current \u2261 null or current{expr} \u2261 null ) {\n					die `Mismatched close tag {{/${inner}}}`;\n				}\n				if ( inner \u2262 "" ) {\n					let parsed := self._parse_expression_spec(inner);\n					if ( current{expr} \u2262 parsed{expr} ) {\n						die `Mismatched close tag {{/${inner}}} for {{${current{expr}}}}`;\n					}\n				}\n			}\n			else if ( tagged \u2262 "" ) {\n				if ( substr( tagged, 0, 1 ) \u2261 ">" ) {\n					die "Template includes are disabled"\n						if not includes_enabled;\n\n					let include_path := trim( substr( tagged, 1 ) );\n					die "Empty include path in template tag"\n						if include_path \u2261 "";\n\n					let resolved := self._resolve_include_path(\n						include_path: include_path,\n						current_file: current_file,\n					);\n\n					let key := self._canonical_path(resolved);\n					if ( seen_files.exists(key) and seen_files.get(key) ) {\n						die `Circular include detected for "${resolved}"`;\n					}\n\n					seen_files.set( key, true );\n					let loaded := self._read_template_file(resolved);\n					let include_nodes := self._parse_template(\n						template: loaded{text},\n						current_file: loaded{file},\n						seen_files: seen_files,\n						includes: includes_enabled,\n					);\n					seen_files.remove(key);\n\n					for ( let node in include_nodes ) {\n						stack[ stack.length() - 1 ]{nodes}.push(node);\n					}\n				}\n				else {\n					let parsed := self._parse_expression_spec(tagged);\n					stack[ stack.length() - 1 ]{nodes}.push( {\n						type: "expr",\n						expr_src: parsed{expr},\n						escape: parsed{escape},\n					} );\n				}\n			}\n\n			pos := tag_close + 2;\n		}\n\n		let tail := substr( template, pos );\n		self._push_text( stack[ stack.length() - 1 ]{nodes}, tail );\n\n		if ( stack.length() > 1 ) {\n			let missing := stack[ stack.length() - 1 ]{expr};\n			die `Missing close tag for {{${missing}}}`;\n		}\n\n		return root;\n	}\n\n	method _push_text ( nodes, text ) {\n		if ( text \u2262 "" ) {\n			nodes.push( {\n				type: "text",\n				text: text,\n			} );\n		}\n	}\n\n	method _read_template_file ( raw_file ) {\n		let path_obj := self._to_path(raw_file);\n		let text := path_obj.slurp_utf8();\n		let canonical := self._canonical_path(path_obj);\n\n		return {\n			text: text,\n			file: canonical,\n		};\n	}\n\n	method _to_path ( raw_file ) {\n		from std/io import Path;\n		if ( raw_file instanceof Path ) {\n			return raw_file;\n		}\n		return new Path( "" _ raw_file );\n	}\n\n	method _canonical_path ( path_obj ) {\n		let obj := self._to_path(path_obj);\n		let canonical := obj.realpath();\n		if ( canonical \u2261 null ) {\n			canonical := obj.absolute();\n		}\n		if ( canonical \u2261 null ) {\n			return obj.to_String;\n		}\n		from std/io import Path;\n		if ( canonical instanceof Path ) {\n			return canonical.to_String;\n		}\n		return "" _ canonical;\n	}\n\n	method _resolve_include_path ( ... PairList args ) {\n		let include_path := args.get( "include_path" );\n		let current_file := args.get( "current_file" );\n\n		let include_obj := self._to_path(include_path);\n		if ( include_obj.is_absolute() ) {\n			return include_obj.to_String;\n		}\n\n		if ( current_file \u2261 null ) {\n			die `Relative include path "${include_path}" requires file-based template source`;\n		}\n\n		let base := self._to_path(current_file).parent();\n		return base.child( include_obj.to_String ).to_String;\n	}\n\n	method _parse_expression_spec ( raw ) {\n		let expr := raw;\n		let escape_mode := null;\n\n		let split := self._find_escape_separator(raw);\n		if ( split \u2262 null ) {\n			let lhs := split[0];\n			let rhs := split[1];\n			if ( rhs \u2261 "html" or rhs \u2261 "raw" ) {\n				expr := lhs;\n				escape_mode := rhs;\n			}\n		}\n\n		expr := trim(expr);\n		if ( expr \u2261 "" ) {\n			die "Empty expression in template tag";\n		}\n\n		return {\n			expr: expr,\n			escape: escape_mode,\n		};\n	}\n\n	method _find_escape_separator ( text ) {\n		let quote := "";\n		let i := 0;\n		while ( i < length text ) {\n			let ch := substr( text, i, 1 );\n			if ( quote \u2262 "" ) {\n				if ( ch \u2261 "\\\\" ) {\n					i += 2;\n					next;\n				}\n				if ( ch \u2261 quote ) {\n					quote := "";\n				}\n				i++;\n				next;\n			}\n\n			if ( ch \u2261 "\\"" or ch \u2261 "\'" ) {\n				quote := ch;\n				i++;\n				next;\n			}\n\n			if ( ch \u2261 ":" and substr( text, i, 2 ) \u2261 "::" ) {\n				let lhs := trim( substr( text, 0, i ) );\n				let rhs := lc( trim( substr( text, i + 2 ) ) );\n				return [ lhs, rhs ];\n			}\n\n			i++;\n		}\n\n		return null;\n	}\n\n	method _render_nodes ( ... PairList args ) {\n		let nodes := args.get( "nodes", [] );\n		let context := args.get( "context", null );\n		let eval_meta := args.get( "eval_meta", {} );\n		let default_escape := args.get( "default_escape", "html" );\n		let out := "";\n\n		for ( let node in nodes ) {\n			if ( node{type} \u2261 "text" ) {\n				out _= node{text};\n			}\n			else if ( node{type} \u2261 "expr" ) {\n				let results := self._evaluate_expression(\n					expr_src: node{expr_src},\n					context: context,\n					eval_meta: eval_meta,\n				);\n				let value := "";\n				for ( let matched in results ) {\n					let sv := matched.string_value();\n					value _= sv \u2261 null ? "" : sv;\n				}\n\n				let escape_mode := node{escape};\n				if ( escape_mode \u2261 null ) {\n					escape_mode := default_escape;\n				}\n\n				if ( escape_mode \u2261 "html" ) {\n					out _= self._escape_html(value);\n				}\n				else {\n					out _= value;\n				}\n			}\n			else if ( node{type} \u2261 "block" ) {\n				let results := self._evaluate_expression(\n					expr_src: node{expr_src},\n					context: context,\n					eval_meta: eval_meta,\n				);\n				for ( let matched in results ) {\n					let primitive := matched.primitive_value();\n					next if not self._truthy(primitive);\n\n					let inner_context := context;\n					let inner_meta := eval_meta;\n					if ( self._node_has_identity(matched) ) {\n						inner_context := matched;\n						inner_meta := { parentset: results };\n					}\n\n					out _= self._render_nodes(\n						nodes: node{nodes},\n						context: inner_context,\n						eval_meta: inner_meta,\n						default_escape: default_escape,\n					);\n				}\n			}\n		}\n\n		return out;\n	}\n\n	method _evaluate_expression ( ... PairList args ) {\n		let expr_src := args.get( "expr_src" );\n		let context := args.get( "context" );\n		let eval_meta := args.get( "eval_meta", {} );\n		if ( not compiled_paths.exists(expr_src) ) {\n			compiled_paths.set(\n				expr_src,\n				self._compile_path(expr_src),\n			);\n		}\n		let zpath := compiled_paths.get(expr_src);\n		return zpath.evaluate( context, eval_meta );\n	}\n\n	method _compile_path ( expr_src ) {\n		return new ZPath( path: expr_src );\n	}\n\n	method _node_has_identity ( node ) {\n		let parent := node.parent();\n		if ( parent \u2261 null ) {\n			return false;\n		}\n\n		return true;\n	}\n\n	method _truthy ( value ) {\n		return value ? true : false;\n	}\n\n	method _escape_html ( text ) {\n		let out := "";\n		let i := 0;\n		while ( i < length text ) {\n			let ch := substr( text, i, 1 );\n			if ( ch \u2261 "&" ) {\n				out _= "&amp;";\n			}\n			else if ( ch \u2261 "<" ) {\n				out _= "&lt;";\n			}\n			else if ( ch \u2261 ">" ) {\n				out _= "&gt;";\n			}\n			else if ( ch \u2261 "\\"" ) {\n				out _= "&quot;";\n			}\n			else if ( ch \u2261 "\'" ) {\n				out _= "&#39;";\n			}\n			else {\n				out _= ch;\n			}\n			i++;\n		}\n		return out;\n	}\n}\n';
        virtualFiles["/modules/std/template/zz.zzm"] = `=encoding utf8

=head1 NAME

std/template/zz - ZZPath-backed template engine.

=head1 SYNOPSIS

  from std/template/zz import ZZTemplate;

  let tmpl := new ZZTemplate(
    string: "Hello {{ name ?: \\"friend\\" }}!",
  );
  say( tmpl.process( { name: "Ada" } ) );

=head1 IMPLEMENTATION SUPPORT

This module is supported by zuzu.pl, zuzu-rust, and zuzu-js on Node and
Electron. It is partially supported by zuzu-js in the browser:
filesystem-backed template loading is unsupported.

=head1 DESCRIPTION

C<std/template/zz> provides C<ZZTemplate>, a subclass of
C<std/template/z>'s C<ZTemplate> which renders template expressions
using C<std/path/zz> instead of C<std/path/z>.

The parser, escaping, include handling, and rendering machinery are
inherited from C<ZTemplate>.

=head1 EXPORTS

=head2 Classes

=over

=item C<< ZZTemplate({ string?: String, file?, escape?: String, includes?: Boolean }) >>

Constructs a template that evaluates expressions with C<std/path/zz>.
Returns: C<ZZTemplate>. It inherits C<process(data)> from C<ZTemplate>,
which takes a model value and returns rendered C<String> output.

=back

=head1 COPYRIGHT AND LICENCE

B<< std/template/zz >> is copyright Toby Inkster.

It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.

=cut

from std/template/z import ZTemplate;
from std/path/zz import ZZPath;

class ZZTemplate extends ZTemplate {
	method _compile_path ( expr_src ) {
		return new ZZPath( path: expr_src );
	}
}
`;
        virtualFiles["/modules/test/more.zzm"] = '=encoding utf8\n\n=head1 NAME\n\ntest/more - Write unit tests and integration tests in ZuzuScript.\n\n=head1 SYNOPSIS\n\n  from test/more import *;\n  from my/project import frobnicate;\n\n  is(frobnicate(21), 42, "frobinated 21 correctly");\n  is(frobnicate(null), null, "frobinate on null input");\n\n  done_testing();\n\n=cut\n\n\nlet Number _COUNT := 0;\nlet Number _PASSED := 0;\nlet Number _FAILED := 0;\nlet Number _LEVEL := 0;\nlet Number _PLAN := -1;\nlet Number _TODO_FAILED := 0;\nlet Number _TODO_PASSED := 0;\n\nlet TODO;\n\nfunction _directive () {\n	if ( TODO ) {\n		if ( TODO instanceof String ) {\n			return ` # TODO ${TODO}`;\n		}\n		else {\n			return " # TODO";\n		}\n	}\n	return "";\n}\n\nfunction _indent () {\n	let i := _LEVEL;\n	let str := "";\n	while ( i > 0 ) {\n		str _= "    ";\n		i--;\n	}\n\n	return str;\n}\n\nclass BailOutException extends Exception;\nclass SkipAllException extends Exception;\n\nfunction _module_name_is_valid ( String module ) {\n	return module ~ /^[A-Za-z_][A-Za-z0-9_]*(\\/[A-Za-z_][A-Za-z0-9_]*)*$/;\n}\n\nfunction _module_is_available ( String module ) {\n	from std/eval import eval;\n\n	try {\n		eval( `do { from ${module} import *; }; true;` );\n		return true;\n	}\n	catch {\n		return false;\n	}\n}\n\nfunction _capability_is_available ( String capability ) {\n	if ( not( capability ~ /^[A-Za-z_][A-Za-z0-9_]*$/ ) ) {\n		die `Invalid capability name: ${capability}`;\n	}\n\n	let deny_key := `deny_${capability}`;\n	if ( deny_key in __system__ ) {\n		return not __system__.get(deny_key);\n	}\n\n	return false;\n}\n\n=head1 IMPLEMENTATION SUPPORT\n\nThis module is supported by all implementations of ZuzuScript.\n\n=head1 DESCRIPTION\n\nC<< test/more >> is a module for test-driven development. It can be used\nfor writing unit tests and integration tests. It generates output in TAP\nL<https://testanything.org/>.\n\nThis module should feel familiar to anybody who has used C<< Test::More >>\nfor Perl, though there are some minor differences.\n\n=head2 Functions\n\n=over\n\n=item C<< pass(String name?) >>\n\nIndicates the named test has passed.\n\n=cut\n\nfunction pass ( String name? ) {\n	++_PASSED;\n	++_COUNT;\n	++_TODO_PASSED if TODO;\n	if ( name \u2261 null ) {\n		say `${_indent()}ok ${_COUNT}${_directive()}`;\n	}\n	else {\n		say `${_indent()}ok ${_COUNT} - ${name}${_directive()}`;\n	}\n\n	return true;\n}\n\n=item C<< fail(String name?) >>\n\nIndicates the named test has failed.\n\n=cut\n\nfunction fail ( String name ) {\n	++_FAILED;\n	++_COUNT;\n	++_TODO_FAILED if TODO;\n	if ( name \u2261 null ) {\n		say `${_indent()}not ok ${_COUNT}${_directive()}`;\n	}\n	else {\n		say `${_indent()}not ok ${_COUNT} - ${name}${_directive()}`;\n	}\n\n	return false;\n}\n\n=item C<< ok(expr, String name?) >>\n\nPasses the named test only if C<expr> is truthy.\n\n=cut\n\nfunction ok ( expr, String name? ) {\n	if (expr) {\n		return pass(name);\n	}\n	else {\n		return fail(name);\n	}\n}\n\nfunction _coerced_equal ( got, expected ) {\n	if ( got \u2261 expected ) {\n		return true;\n	}\n\n	if ( got instanceof Boolean and expected instanceof Number ) {\n		return ( got ? 1: 0 ) = expected;\n	}\n	if ( got instanceof Number and expected instanceof Boolean ) {\n		return got = ( expected ? 1: 0 );\n	}\n\n	return false;\n}\n\n=item C<< is(got, expected, String name?) >>\n\nPasses the named test only if C<< got \u2261 expected >>.\n\n=cut\n\nfunction is ( got, expected, String name? ) {\n\n	if ( not ok( _coerced_equal( got, expected ), name ) ) {\n		from std/dump import Dumper;\n		say `${_indent()}# expected: ${Dumper.dump(expected)}`;\n		say `${_indent()}# got:      ${Dumper.dump(got)}`;\n		return false;\n	}\n\n	return true;\n}\n\n=item C<< isnt(got, unexpected, String name?) >>\n\nPasses the named test only if C<< got \u2262 expected >>.\n\n=cut\n\nfunction isnt ( got, unexpected, String name? ) {\n	return ok( not _coerced_equal( got, unexpected ), name );\n}\n\n=item C<< like(got, expected_re, String name?) >>\n\nPasses the named test only if C<< got ~ expected >>.\n\n=cut\n\nfunction like ( got, Regexp expected_re, String name? ) {\n\n	if ( not ok( got ~ expected_re, name ) ) {\n		say `${_indent()}# expected (regexp): ${expected_re}`;\n		say `${_indent()}# got:               ${got}`;\n		return false;\n	}\n\n	return true;\n}\n\n=item C<< unlike(got, unexpected_re, String name?) >>\n\nFails the named test only if C<< got ~ expected >>.\n\n=cut\n\nfunction unlike ( got, Regexp unexpected_re, String name? ) {\n\n	if ( not ok( not( got ~ unexpected_re ), name ) ) {\n		say `${_indent()}# unexpected (regexp): ${unexpected_re}`;\n		say `${_indent()}# got:                 ${got}`;\n		return false;\n	}\n\n	return true;\n}\n\n=item C<< diag(diagnostic) >>\n\nOutputs the diagnostic.\n\n=cut\n\nfunction diag (diagnostic) {\n	say `${_indent()}# ${diagnostic}`;\n	return true;\n}\n\n=item C<< explain(value) >>\n\nCombines diag with Dumper.dump();\n\n=cut\n\nfunction explain (value) {\n	from std/dump import Dumper;\n	return diag( Dumper.dump(value) );\n}\n\n=item C<< bail_out(String message?) >>\n\nBail out of running further tests.\n\n=cut\n\nfunction bail_out ( String message? ) {\n	let e;\n	if ( message \u2261 null ) {\n		e := new BailOutException( message: "Bail out!" );\n	}\n	else {\n		e := new BailOutException( message: `Bail out! ${message}` );\n	}\n	throw e;\n}\n\n=item C<< skip_all(String reason) >>\n\nSkips the whole test file by emitting a TAP skip-all plan and exiting\nsuccessfully when the runtime provides C<std/proc>.\n\nThis is intended for guards at the beginning of a test script, before\nany tests have run. Browser-like hosts without C<std/proc> use a\nspecial exception fallback that the browser ztest runner treats as a\nskip.\n\n=cut\n\nfunction skip_all ( String reason ) {\n	die "Cannot skip all tests after tests have already run" if _COUNT > 0;\n	die "Cannot skip all tests in a subtest" if _LEVEL > 0;\n	_PLAN := 0;\n	say `1..${_PLAN} # SKIP: ${reason}`;\n\n	from std/proc try import Proc;\n	Proc.exit(0) if Proc \u2262 null;\n	throw new SkipAllException( message: reason );\n}\n\n=item C<< requires_module(String module) >>\n\nSkips the whole test file if the named module cannot be loaded.\n\n=cut\n\nfunction requires_module ( String module ) {\n	if ( not _module_name_is_valid(module) ) {\n		die `Invalid module name: ${module}`;\n	}\n\n	if ( not _module_is_available(module) ) {\n		skip_all( `module ${module} is unavailable` );\n	}\n\n	return true;\n}\n\n=item C<< requires_capability(String capability) >>\n\nSkips the whole test file if the named runtime capability is not\navailable.\n\n=cut\n\nfunction requires_capability ( String capability ) {\n	if ( not _capability_is_available(capability) ) {\n		skip_all( `capability ${capability} is unavailable` );\n	}\n\n	return true;\n}\n\n=item C<< author_testing() >>\n\nSkips the whole test file unless the C<AUTHOR_TESTING> environment\nvariable is set to a true value.\n\n=cut\n\nfunction author_testing () {\n	requires_capability( "proc" );\n	from std/proc try import Env;\n	if ( Env and Env.get( "AUTHOR_TESTING", false ) ) {\n		return true;\n	}\n	skip_all( "requires AUTHOR_TESTING=1" );\n}\n\n=item C<< extended_testing() >>\n\nSkips the whole test file unless the C<EXTENDED_TESTING> environment\nvariable is set to a true value.\n\n=cut\n\nfunction extended_testing () {\n	requires_capability( "proc" );\n	from std/proc try import Env;\n	if ( Env and Env.get( "EXTENDED_TESTING", false ) ) {\n		return true;\n	}\n	skip_all( "requires EXTENDED_TESTING=1" );\n}\n\n=item C<< plan(Number n) >>\n\nIndicate the number of tests you intend on running, before running any\ntests.\n\ndone_testing() can later check the number.\n\n=cut\n\nfunction plan ( Number n ) {\n	die "Must plan() before running any tests" if _COUNT > 0;\n	die "Cannot plan() in a subtest" if _LEVEL > 0;\n	die "Must plan() at least one test" if n < 1;\n	_PLAN := n;\n	say `1..${_PLAN}`;\n}\n\n=item C<< done_testing(Number n?) >>\n\nIndicates that testing is finished.\n\nYou may optionally provide the expected total number of tests, and the\nfunction will throw an exception if that doesn\'t match the number of\ntests which were actually run.\n\nWill also throw an error if you called plan() earlier and the actual\nnumber of tests run differs from your plan.\n\n=cut\n\nfunction done_testing ( Number n? ) {\n	die "Unexpected done_testing() in subtest" if _LEVEL > 0;\n	die `Expected ${n} tests, but ran ${_COUNT}` if n \u2262 null and n \u2260 _COUNT;\n\n	function maybe_fail_count ( should_die ) {\n		if ( _TODO_PASSED > 0 ) {\n			warn `Passed ${_TODO_PASSED} TODO tests!`;\n		}\n		if ( _FAILED > 0 ) {\n			let msg := `Failed ${_FAILED} tests`;\n			msg _= ` (${_TODO_FAILED} todo, ${_FAILED - _TODO_FAILED} true fails)` if _TODO_FAILED > 0;\n			die msg if should_die and ( _FAILED > _TODO_FAILED );\n			warn msg;\n		}\n	}\n\n	if ( _PLAN < 0 ) {\n		say `1..${_COUNT}`;\n	}\n	else if ( _PLAN \u2260 _COUNT ) {\n		maybe_fail_count(false);\n		die `Planned ${_PLAN} tests, but ran ${_COUNT}`;\n	}\n\n	maybe_fail_count(true);\n	return true;\n}\n\n=item C<< subtest(String name, Function f) >>\n\nCalls f() as a subtest.\n\nDon\'t use done_testing() within the function.\n\n=cut\n\nfunction subtest ( String name, Function f ) {\n	let orig_context := {\n		count: _COUNT,\n		passed: _PASSED,\n		failed: _FAILED,\n		level: _LEVEL,\n		todo_passed: _TODO_PASSED,\n		todo_failed: _TODO_FAILED,\n	};\n\n	function restore_context () {\n		_COUNT := orig_context{count};\n		_PASSED := orig_context{passed};\n		_FAILED := orig_context{failed};\n		_LEVEL := orig_context{level};\n		_TODO_PASSED := orig_context{todo_passed};\n		_TODO_FAILED := orig_context{todo_failed};\n	}\n\n	_COUNT := 0;\n	_PASSED := 0;\n	_FAILED := 0;\n	_TODO_PASSED := 0;\n	_TODO_FAILED := 0;\n	_LEVEL++;\n	let is_ok := true;\n\n	try {\n		diag( `Subtest: ${name}` );\n		f();\n		say `${_indent()}1..${_COUNT}`;\n		is_ok := false if _FAILED > _TODO_FAILED;\n		restore_context();\n	}\n	catch ( BailOutException e ) {\n		throw e;\n	}\n	catch ( Exception e ) {\n		is_ok := false;\n		restore_context();\n	}\n\n	return ok( is_ok, name );\n}\n\n=back\n\n=item C<< todo(Boolean c, String reason, Function f) >>\n\nRuns the tests in the given function, but if condition c is true then\nfirst sets TODO to true.\n\nYou can manually set and unset the TODO variable instead.\n\n=cut\n\nfunction todo ( Boolean c, String reason, Function f ) {\n	let orig := TODO;\n	TODO := reason if c;\n	try {\n		f();\n	}\n	catch {\n	}\n	TODO := orig;\n	return not c;\n}\n\n=back\n\n=item C<< exception(Function f) >>\n\nCalls f() and returns any exception thrown.\n\nReturns null if no exception was thrown.\n\n=cut\n\nfunction exception ( Function f ) {\n	try {\n		f();\n		return null;\n	}\n	catch ( BailOutException e ) {\n		throw e;\n	}\n	catch ( Exception e ) {\n		return e;\n	}\n}\n\n=back\n\n=head1 COPYRIGHT AND LICENCE\n\nB<< test/more >> is copyright Toby Inkster.\n\nIt is free software; you may redistribute it and/or modify it under\nthe terms of either the Artistic License 1.0 or the GNU General Public\nLicense version 2.\n\n=cut\n';
        return {
          repoRoot: "/",
          includePaths: ["/__zuzu_browser_modules__/0"],
          jsModules,
          virtualFiles
        };
      }
      module2.exports = {
        createBrowserStdlib: createBrowserStdlib2
      };
    }
  });

  // lib/browser-worker-entry.js
  var require_browser_worker_entry = __commonJS({
    "lib/browser-worker-entry.js"(exports2, module2) {
      "use strict";
      var { createBrowserRuntime } = require_browser_runtime();
      var { BinaryString: BinaryString2 } = require_runtime_helpers();
      var taskRuntime2 = require_task();
      function bytesFromData(value) {
        if (value instanceof Uint8Array) {
          return new BinaryString2(value);
        }
        if (Array.isArray(value)) {
          return new BinaryString2(Uint8Array.from(value));
        }
        return new BinaryString2();
      }
      function errorText(err) {
        if (err && typeof err.to_String === "function") {
          return err.to_String();
        }
        if (err && err.name && err.message) {
          return `${err.name}: ${err.message}`;
        }
        return err && err.message ? err.message : String(err);
      }
      function workerDenyCapabilities(policy = {}) {
        const out = [];
        for (const capability of [
          "fs",
          "net",
          "perl",
          "js",
          "proc",
          "db",
          "clib",
          "gui",
          "worker"
        ]) {
          if (policy[`deny_${capability}`]) {
            out.push(capability);
          }
        }
        return out;
      }
      async function runWorkerJob(payload, defaultOptions = {}) {
        const policy = payload.policy || {};
        const browser = createBrowserRuntime({
          ...defaultOptions,
          repoRoot: policy.repo_root || defaultOptions.repoRoot || "/",
          includePaths: policy.include_paths || defaultOptions.includePaths || [],
          denyCapabilities: workerDenyCapabilities(policy),
          denyModules: policy.deny_modules || defaultOptions.denyModules || [],
          debugLevel: policy.debug_level || 0,
          transpiler: policy.transpiler || defaultOptions.transpiler
        });
        const marshal = browser.runtime.loadModule(
          "std/marshal",
          "/<browser-worker>.zzs"
        );
        if (marshal && typeof marshal.__zuzu_set_runtime_policy === "function") {
          marshal.__zuzu_set_runtime_policy({
            ...policy,
            host_name: "browser"
          });
        }
        const request = marshal.load(bytesFromData(payload.request_bytes));
        if (!Array.isArray(request) || request.length !== 2) {
          throw new Error("Worker.spawn payload did not decode as Array");
        }
        const [callable, workerArgs] = request;
        if (typeof callable !== "function") {
          throw new Error("Worker.spawn payload callable did not decode as Function");
        }
        if (!Array.isArray(workerArgs)) {
          throw new Error("Worker.spawn payload arguments did not decode as Array");
        }
        let result = callable(...workerArgs);
        if (result instanceof taskRuntime2.Task) {
          result = await taskRuntime2.awaitValue(result);
        } else if (result && typeof result.then === "function") {
          result = await result;
        }
        const bytes = marshal.dump(result);
        return Array.from(bytes.bytes);
      }
      var BrowserWorkerInbox = class {
        constructor(marshal, post) {
          this._marshal = marshal;
          this._post = post;
          this._queue = [];
          this._receivers = [];
          this._closed = false;
        }
        _postLater(message) {
          Promise.resolve().then(() => this._post(message));
        }
        _deliver(message) {
          const receiver = this._receivers.shift();
          if (receiver) {
            receiver._resolve(message);
          } else {
            this._queue.push(message);
          }
        }
        _closeRemote() {
          this._closed = true;
          while (this._receivers.length > 0) {
            this._receivers.shift()._reject(
              new taskRuntime2.ChannelClosedException("worker inbox closed")
            );
          }
        }
        send(value = null) {
          let bytes;
          try {
            bytes = this._marshal.dump(value);
          } catch (err) {
            return taskRuntime2.Task.failed(err);
          }
          this._post({
            type: "message",
            bytes: Array.from(bytes.bytes)
          });
          return taskRuntime2.Task.resolved(value);
        }
        recv() {
          if (this._queue.length > 0) {
            return taskRuntime2.Task.resolved(this._queue.shift());
          }
          if (this._closed) {
            return taskRuntime2.Task.failed(
              new taskRuntime2.ChannelClosedException("worker inbox closed")
            );
          }
          const task = new taskRuntime2.Task(null, {
            status: "waiting",
            name: "WorkerInbox.recv",
            cancel: () => {
              this._receivers = this._receivers.filter((item) => item !== task);
            }
          });
          this._receivers.push(task);
          return task;
        }
        close() {
          this._postLater({ type: "close" });
          return taskRuntime2.Task.resolved(null);
        }
      };
      async function runWorkerHandle(payload, defaultOptions = {}, post, registerControl = null) {
        let nextOutgoingSeq = 1;
        const postFrame = (message) => {
          post({
            ...message,
            seq: nextOutgoingSeq++
          });
        };
        const policy = payload.policy || {};
        const browser = createBrowserRuntime({
          ...defaultOptions,
          repoRoot: policy.repo_root || defaultOptions.repoRoot || "/",
          includePaths: policy.include_paths || defaultOptions.includePaths || [],
          denyCapabilities: workerDenyCapabilities(policy),
          denyModules: policy.deny_modules || defaultOptions.denyModules || [],
          debugLevel: policy.debug_level || 0,
          transpiler: policy.transpiler || defaultOptions.transpiler
        });
        const marshal = browser.runtime.loadModule(
          "std/marshal",
          "/<browser-worker>.zzs"
        );
        if (marshal && typeof marshal.__zuzu_set_runtime_policy === "function") {
          marshal.__zuzu_set_runtime_policy({
            ...policy,
            host_name: "browser"
          });
        }
        const request = marshal.load(bytesFromData(payload.request_bytes));
        if (!Array.isArray(request) || request.length !== 2) {
          throw new Error("Worker.spawn_handle payload did not decode as Array");
        }
        const [callable, workerArgs] = request;
        if (typeof callable !== "function") {
          throw new Error("Worker.spawn_handle payload callable did not decode as Function");
        }
        if (!Array.isArray(workerArgs)) {
          throw new Error("Worker.spawn_handle payload arguments did not decode as Array");
        }
        const inbox = new BrowserWorkerInbox(marshal, postFrame);
        const handleControl = (message) => {
          if (!message || typeof message !== "object") {
            return;
          }
          if (message.type === "message") {
            inbox._deliver(marshal.load(bytesFromData(message.bytes)));
          } else if (message.type === "close") {
            inbox._closeRemote();
          } else if (message.type === "cancel") {
            inbox._closeRemote();
            throw new taskRuntime2.CancelledException(
              message.reason || "worker cancelled"
            );
          }
        };
        if (typeof registerControl === "function") {
          registerControl(handleControl);
        }
        let result = callable(inbox, ...workerArgs);
        if (result instanceof taskRuntime2.Task) {
          result = await taskRuntime2.awaitValue(result);
        } else if (result && typeof result.then === "function") {
          result = await result;
        }
        const bytes = marshal.dump(result);
        postFrame({
          type: "result",
          ok: true,
          bytes: Array.from(bytes.bytes)
        });
        Promise.resolve().then(() => postFrame({ type: "close" }));
      }
      function installBrowserWorker2(defaultOptions = {}, root = globalThis) {
        if (!root || typeof root !== "object") {
          return null;
        }
        const post = (message) => {
          if (typeof root.postMessage === "function") {
            root.postMessage(message);
          }
        };
        let activeHandleControl = null;
        let nextControlSeq = 1;
        const pendingControlFrames = /* @__PURE__ */ new Map();
        const pendingUnsequencedControl = [];
        const deliverHandleControl = (payload) => {
          try {
            activeHandleControl(payload);
          } catch (err) {
            activeHandleControl = null;
            nextControlSeq = 1;
            pendingControlFrames.clear();
            pendingUnsequencedControl.length = 0;
            post({
              type: "result",
              ok: false,
              error: errorText(err)
            });
            post({ type: "close" });
          }
        };
        const drainHandleControl = () => {
          if (!activeHandleControl) {
            return;
          }
          while (pendingUnsequencedControl.length > 0 && activeHandleControl) {
            deliverHandleControl(pendingUnsequencedControl.shift());
          }
          while (activeHandleControl && pendingControlFrames.has(nextControlSeq)) {
            const payload = pendingControlFrames.get(nextControlSeq);
            pendingControlFrames.delete(nextControlSeq);
            nextControlSeq++;
            deliverHandleControl(payload);
          }
        };
        const dispatchHandleControl = (payload) => {
          if (Number.isInteger(payload.seq)) {
            pendingControlFrames.set(payload.seq, payload);
          } else {
            pendingUnsequencedControl.push(payload);
          }
          drainHandleControl();
        };
        const handleMessage = (event) => {
          const payload = event && Object.prototype.hasOwnProperty.call(event, "data") ? event.data : event;
          if (payload && (payload.type === "message" || payload.type === "close" || payload.type === "cancel")) {
            dispatchHandleControl(payload);
            return;
          }
          if (payload && payload.type === "start_handle") {
            const controlPost = (message) => post(message);
            runWorkerHandle(
              payload,
              defaultOptions,
              controlPost,
              (handler) => {
                activeHandleControl = handler;
                drainHandleControl();
              }
            ).then(
              () => {
                activeHandleControl = null;
                nextControlSeq = 1;
                pendingControlFrames.clear();
                pendingUnsequencedControl.length = 0;
              },
              (err) => {
                activeHandleControl = null;
                nextControlSeq = 1;
                pendingControlFrames.clear();
                pendingUnsequencedControl.length = 0;
                post({
                  type: "result",
                  ok: false,
                  error: errorText(err)
                });
                post({ type: "close" });
              }
            );
            return;
          }
          runWorkerJob(payload || {}, defaultOptions).then(
            (bytes) => post({
              ok: true,
              bytes
            }),
            (err) => post({
              ok: false,
              error: errorText(err)
            })
          );
        };
        if (typeof root.addEventListener === "function") {
          root.addEventListener("message", handleMessage);
          root.addEventListener("error", (event) => {
            post({
              ok: false,
              error: errorText(
                event && (event.error || event.message) ? event.error || event.message : "worker failed"
              )
            });
          });
          root.addEventListener("unhandledrejection", (event) => {
            post({
              ok: false,
              error: errorText(
                event && event.reason ? event.reason : "worker failed"
              )
            });
          });
        } else {
          root.onmessage = handleMessage;
          root.onerror = (message, _source, _line, _column, error) => {
            post({
              ok: false,
              error: errorText(error || message || "worker failed")
            });
          };
          root.onunhandledrejection = (event) => {
            post({
              ok: false,
              error: errorText(
                event && event.reason ? event.reason : "worker failed"
              )
            });
          };
        }
        return root;
      }
      module2.exports = {
        installBrowserWorker: installBrowserWorker2,
        runWorkerJob
      };
    }
  });

  // ../../../../../tmp/zuzu-browser-build.WePoiO/browser-worker-entry.generated.js
  var { createBrowserStdlib } = require_browser_stdlib_generated();
  globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__ = createBrowserStdlib();
  var { installBrowserWorker } = require_browser_worker_entry();
  installBrowserWorker(globalThis.__ZUZU_BROWSER_DEFAULT_RUNTIME_OPTIONS__);
})();
