{"version":3,"sources":["../src/index.ts","../src/sortedNodes.ts","../src/html.ts"],"sourcesContent":["/// SPDX-License-Identifier: GPL-3.0-or-later\n/// SPDX-FileCopyrightText: Copyright © 2023-2025 Tony Garnock-Jones <tonyg@leastfixedpoint.com>\n\nimport { AnyValue, Turn, Facet, Dataflow, Dataspace, Ref } from \"@syndicate-lang/core\";\nimport { getSortKey, setSortKey, findInsertionPoint } from './sortedNodes';\nimport { HtmlTemplater, template } from \"./html\";\nexport { HtmlTemplater, template, HtmlFragment } from \"./html\";\nexport * as Html from './html';\nexport * as SortedNodes from './sortedNodes';\n\nexport assertion type LocationHash(hash: string);\nexport type LocationHash = ReturnType<typeof LocationHash>;\n\nexport function boot(ds = Dataspace.local) {\n    spawnLocationHashTracker(ds);\n}\n\ntype Wrapped = {\n    wrapped: EventListenerOrEventListenerObject,\n    options?: AddEventListenerOptions | boolean,\n};\n\nexport type NodeGenerator = (t: HtmlTemplater) => ReturnType<HtmlTemplater>;\n\nfunction isStringOrTemplate(x: any): x is string | HTMLTemplateElement {\n    return typeof x === 'string' || (typeof x === 'object' && x instanceof HTMLTemplateElement);\n}\n\nexport type WidgetOptions = {\n    eventSelector?: string | undefined;\n};\n\nexport class Widget implements EventTarget {\n    readonly facet: Facet;\n    readonly widgetOptions: WidgetOptions;\n    private _node: ChildNode | null = null;\n    private _eventNode: ChildNode | null = null;\n    callbacks = new Map<string, Map<EventListenerOrEventListenerObject, Wrapped>>();\n\n    get node(): ChildNode {\n        return this._node!;\n    }\n\n    get eventNode(): ChildNode {\n        return this._eventNode!;\n    }\n\n    constructor (node: ChildNode, options?: WidgetOptions);\n    constructor (nodeGenerator: NodeGenerator, options?: WidgetOptions);\n    constructor (template: string | HTMLTemplateElement, data: object, options?: WidgetOptions);\n    constructor (arg0: ChildNode | NodeGenerator | string | HTMLTemplateElement, arg1?: object | WidgetOptions, arg2?: WidgetOptions) {\n        let nodeGenerator: NodeGenerator;\n\n        let maybeOptions: WidgetOptions | undefined;\n        if (isStringOrTemplate(arg0)) {\n            nodeGenerator = templateGenerator(arg0, arg1 as object);\n            maybeOptions = arg2;\n        } else if (typeof arg0 === 'function') {\n            nodeGenerator = arg0 as NodeGenerator;\n            maybeOptions = arg1;\n        } else {\n            nodeGenerator = () => [arg0];\n            maybeOptions = arg1;\n        }\n        this.widgetOptions = Object.assign({\n            eventSelector: void 0,\n        }, maybeOptions ?? {});\n\n        this.facet = Turn.activeFacet;\n\n        const cancelAtExit = this.facet.actor.atExit(() => this.node.remove());\n        on stop {\n            this.node.remove();\n            cancelAtExit();\n        }\n\n        const thisTemplate = template();\n        dataflow {\n            const nodes = nodeGenerator(thisTemplate);\n            if (nodes.length !== 1) {\n                throw new Error(`@syndicate-lang/html2: Expected exactly one node from template`);\n            }\n            if (this._node === null) {\n                this._node = nodes[0];\n            } else if (this._node !== nodes[0]) {\n                throw new Error(`@syndicate-lang/html2: Node generator is not stable`);\n            }\n            this._eventNode = this.widgetOptions.eventSelector === void 0\n                ? this._node\n                : (this._nodeAsParent?.querySelector(this.widgetOptions.eventSelector) ?? null);\n            if (this._eventNode === null) {\n                throw new Error(`@syndicate-lang/html2: Missing event node`);\n            }\n        }\n    }\n\n    get _nodeAsParent(): ParentNode | null {\n        if (this._node && 'querySelector' in this._node) {\n            return this._node as unknown as ParentNode;\n        } else {\n            return null;\n        }\n    }\n\n    get parent(): ParentNode | null {\n        return this.node.parentNode;\n    }\n\n    set parent(p: string | ParentNode | null) {\n        this.setParent(p);\n    }\n\n    get sortKey(): AnyValue | null {\n        return getSortKey(this.node);\n    }\n\n    set sortKey(k: AnyValue | null) {\n        setSortKey(this.node, k);\n        const p = this.parent;\n        if (p !== null) {\n            this.setParent(null);\n            this.setParent(p);\n        }\n    }\n\n    setSortKey(k: AnyValue | null): this {\n        this.sortKey = k;\n        return this;\n    }\n\n    setParent(p: string | ParentNode | null, wrt: ParentNode = document): this {\n        if (typeof p === 'string') {\n            p = wrt.querySelector(p);\n        }\n\n        if (this.node.parentNode !== p) {\n            if (p === null) {\n                this.node.remove();\n            } else {\n                const k = this.sortKey;\n                if (k !== null) {\n                    const sib = findInsertionPoint(p, k);\n                    p.insertBefore(this.node, sib);\n                } else {\n                    p.appendChild(this.node);\n                }\n            }\n        }\n\n        return this;\n    }\n\n    querySelector(selector: string): Widget | null;\n    querySelector<T extends Widget>(selector: string, ctor: { new(e: Element): T }): T | null;\n    querySelector<T extends Widget>(selector: string, ctor?: { new(e: Element): T }): Widget | null {\n        const e = this._nodeAsParent?.querySelector(selector);\n        return e ? new (ctor ?? Widget)(e) : null;\n    }\n\n    querySelectorAll(selector: string): Widget[];\n    querySelectorAll<T extends Widget>(selector: string, ctor: { new(e: Element): T }): T[];\n    querySelectorAll<T extends Widget>(selector: string, ctor?: { new(e: Element): T }): Widget[] {\n        const es = this._nodeAsParent?.querySelectorAll(selector);\n        const ws: Widget[] = [];\n        if (es) es.forEach(e => ws.push(new (ctor ?? Widget)(e)));\n        return ws;\n    }\n\n    on(type: string, callback: EventListenerOrEventListenerObject): this {\n        this.addEventListener(type, callback);\n        return this;\n    }\n\n    once(type: string, callback: EventListenerOrEventListenerObject): this {\n        this.addEventListener(type, callback, { once: true });\n        return this;\n    }\n\n    off(type: string, callback: EventListenerOrEventListenerObject): this {\n        this.removeEventListener(type, callback);\n        return this;\n    }\n\n    addEventListener(\n        type: string,\n        callback: EventListenerOrEventListenerObject | null,\n        options?: AddEventListenerOptions | boolean,\n    ): void {\n        if (callback === null) return;\n\n        let cbs = this.callbacks.get(type);\n        if (cbs === void 0) {\n            cbs = new Map();\n            this.callbacks.set(type, cbs);\n        } else {\n            if (cbs.has(callback)) return;\n        }\n\n        const entry: Wrapped = {\n            wrapped: (typeof callback === 'function')\n                ? evt => this.facet.turn(() => callback(evt))\n                : evt => this.facet.turn(() => callback.handleEvent(evt)),\n            options,\n        };\n        cbs.set(callback, entry);\n\n        this.eventNode.addEventListener(type, entry.wrapped, options);\n    }\n\n    dispatchEvent(event: Event): boolean {\n        return this.eventNode.dispatchEvent(event);\n    }\n\n    removeEventListener(\n        type: string,\n        callback: EventListenerOrEventListenerObject | null,\n        options?: boolean | EventListenerOptions | undefined,\n    ): void {\n        if (callback === null) return;\n\n        const cbs = this.callbacks.get(type);\n        if (cbs === void 0) return;\n\n        const r = cbs.get(callback);\n        if (r === void 0) return;\n\n        this.eventNode.removeEventListener(type, r.wrapped, options);\n\n        cbs.delete(callback);\n        if (cbs.size === 0) this.callbacks.delete(type);\n    }\n}\n\nexport type ValueWidgetOptions = {\n    triggerEvent?: 'change' | 'input' | undefined,\n} & WidgetOptions;\n\nexport class ValueWidget extends Widget {\n    readonly valueWidgetOptions: ValueWidgetOptions;\n    _value: Dataflow.Field<string>;\n    _valueAsNumber: Dataflow.Field<number>;\n    _checked: Dataflow.Field<boolean>;\n\n    constructor (node: ChildNode, options?: ValueWidgetOptions);\n    constructor (nodeGenerator: NodeGenerator, options?: ValueWidgetOptions);\n    constructor (template: string | HTMLTemplateElement, data: object, options?: ValueWidgetOptions);\n    constructor (arg0: ChildNode | NodeGenerator | string | HTMLTemplateElement, arg1?: object | ValueWidgetOptions, arg2?: ValueWidgetOptions) {\n        super(arg0 as any, arg1 as any, arg2 as any);\n\n        this.valueWidgetOptions = Object.assign({\n            triggerEvent: void 0,\n        } as ValueWidgetOptions, this.widgetOptions);\n\n        field value: string = '';\n        this._value = value;\n\n        field valueAsNumber: number = NaN;\n        this._valueAsNumber = valueAsNumber;\n\n        field checked: boolean = false;\n        this._checked = checked;\n\n        const hasValue = 'value' in this.eventNode;\n        const hasChecked = 'checked' in this.eventNode;\n        if (hasValue || hasChecked) {\n            this.on(this.valueWidgetOptions.triggerEvent ?? 'change', () => this.readValues());\n            this.readValues();\n\n            if (hasValue) {\n                dataflow { this.valueAsNumber = this._valueAsNumber.value; }\n                dataflow { this.value = this._value.value; }\n            }\n            if (hasChecked) {\n                dataflow { this.checked = this._checked.value; }\n            }\n        }\n    }\n\n    readValues() {\n        const n = this.eventNode as any;\n        this.suppressCycleWarning();\n        this._value.value = n.value ?? '';\n        this._valueAsNumber.value = n.valueAsNumber ?? NaN;\n        this._checked.value = n.checked ?? false;\n    }\n\n    get value(): string {\n        return this._value.value;\n    }\n\n    set value(v: string) {\n        (this.eventNode as any).value = v;\n        this._value.value = v;\n    }\n\n    get valueAsNumber(): number {\n        return this._valueAsNumber.value;\n    }\n\n    set valueAsNumber(v: number) {\n        (this.eventNode as any).value = Number.isNaN(v) ? '' : '' + v;\n        this._valueAsNumber.value = v;\n    }\n\n    get checked(): boolean {\n        return this._checked.value;\n    }\n\n    set checked(v: boolean) {\n        (this.eventNode as any).checked = v;\n        this._checked.value = v;\n    }\n\n    suppressCycleWarning(): void {\n        this._value.suppressCycleWarning();\n        this._valueAsNumber.suppressCycleWarning();\n        this._checked.suppressCycleWarning();\n    }\n}\n\nfunction spawnLocationHashTracker(ds: Ref) {\n    spawn named 'LocationHashTracker' {\n        at ds {\n            field hashValue: string = '/';\n\n            const loadHash = () => {\n                var h = decodeURIComponent(window.location.hash);\n                if (h.length && h[0] === '#') {\n                    h = h.slice(1);\n                }\n                hashValue.value = h || '/';\n            };\n            const facet = Turn.activeFacet;\n            const handlerClosure = () => facet.turn(loadHash);\n\n            window.addEventListener('hashchange', handlerClosure);\n            on stop window.removeEventListener('hashchange', handlerClosure);\n\n            loadHash();\n            assert LocationHash(hashValue.value);\n\n            on message LocationHash($newHash: string) => {\n                window.location.hash = newHash;\n            }\n        }\n    }\n}\n\nexport function templateGenerator(\n    template0: string | HTMLTemplateElement,\n    data: object,\n): NodeGenerator {\n    const template = typeof template0 === 'string' ? document.querySelector(template0) : template0;\n    if (template === null) throw new Error('Cannot find template: ' + template0);\n    const body = `return t => t\\`${template.innerHTML.trim().split('`').join('\\\\`')}\\``;\n    const kvs = Object.entries(data);\n    const keys = kvs.map(e => e[0]);\n    const values = kvs.map(e => e[1]);\n    const factory = new Function(... keys, body);\n    return factory(... values);\n}\n","/// SPDX-License-Identifier: GPL-3.0-or-later\n/// SPDX-FileCopyrightText: Copyright © 2016-2025 Tony Garnock-Jones <tonyg@leastfixedpoint.com>\n\nimport { AnyValue, stringify, parse, is, compare } from '@syndicate-lang/core';\n\nexport const SYNDICATE_SORT_KEY = '__syndicate_sort_key';\n\nexport function setSortKey(n: HTMLOrSVGElement | Node, key: AnyValue | null) {\n    if (key === null) {\n        if ('dataset' in n) {\n            // html element nodes etc.\n            delete n.dataset[SYNDICATE_SORT_KEY];\n        } else {\n            // text nodes, svg nodes, etc etc.\n            delete (n as any)[SYNDICATE_SORT_KEY];\n        }\n    } else {\n        const v = stringify(key);\n        if ('dataset' in n) {\n            // html element nodes etc.\n            n.dataset[SYNDICATE_SORT_KEY] = v;\n        } else {\n            // text nodes, svg nodes, etc etc.\n            (n as any)[SYNDICATE_SORT_KEY] = v;\n        }\n    }\n}\n\nexport function getSortKey(n: HTMLOrSVGElement | Node): AnyValue | null {\n    if ('dataset' in n && n.dataset[SYNDICATE_SORT_KEY]) {\n        return parse(n.dataset[SYNDICATE_SORT_KEY]!);\n    }\n    if ((n as any)[SYNDICATE_SORT_KEY]) {\n        return parse((n as any)[SYNDICATE_SORT_KEY]);\n    }\n    return null;\n}\n\nexport function hasSortKey(n: HTMLOrSVGElement | Node, key: AnyValue): boolean {\n    let v = getSortKey(n);\n    return (v !== null) && is(v, key);\n}\n\nfunction firstChildNodeIndex_withSortKey(n: Node): number {\n    for (let i = 0; i < n.childNodes.length; i++) {\n        if (getSortKey(n.childNodes[i]) !== null) return i;\n    }\n    return n.childNodes.length;\n}\n\n// If *no* nodes have a sort key, returns a value that yields an empty\n// range in conjunction with firstChildNodeIndex_withSortKey.\nfunction lastChildNodeIndex_withSortKey(n: Node): number {\n    for (let i = n.childNodes.length - 1; i >= 0; i--) {\n        if (getSortKey(n.childNodes[i]) !== null) return i;\n    }\n    return n.childNodes.length - 1;\n}\n\nfunction isGreaterThan(a: AnyValue, b: AnyValue): boolean {\n    return compare(a, b) > 0;\n}\n\nexport function findInsertionPoint(n: Node, key: AnyValue): ChildNode | null {\n    let lo = firstChildNodeIndex_withSortKey(n);\n    let hi = lastChildNodeIndex_withSortKey(n) + 1;\n    // lo <= hi, and [lo, hi) have sort keys.\n\n    while (lo < hi) { // when lo === hi, there's nothing more to examine.\n        let probe = (lo + hi) >> 1;\n        let probeSortKey = getSortKey(n.childNodes[probe])!;\n\n        if (isGreaterThan(probeSortKey, key)) {\n            hi = probe;\n        } else {\n            lo = probe + 1;\n        }\n    }\n\n    // lo === hi now.\n    if (lo < n.childNodes.length) {\n        return n.childNodes[lo];\n    } else {\n        return null;\n    }\n}\n","/// SPDX-License-Identifier: GPL-3.0-or-later\n/// SPDX-FileCopyrightText: Copyright © 2016-2025 Tony Garnock-Jones <tonyg@leastfixedpoint.com>\n\nimport { randomId } from \"@syndicate-lang/core\";\n\nexport function escape(s: string): string {\n    return s\n        .replace(/&/g, \"&amp;\")\n        .replace(/</g, \"&lt;\")\n        .replace(/>/g, \"&gt;\")\n        .replace(/\"/g, \"&quot;\")\n        .replace(/'/g, \"&#39;\");\n}\n\nexport type HtmlFragment = string | number | Node | Array<HtmlFragment>;\n\nconst tag = randomId(8, true);\nconst onePlaceholderRe = new RegExp(`x-${tag}-(\\\\d+)-${tag}-x`);\nconst allPlaceholdersRe = new RegExp(`(<template id=\"x-${tag}-(\\\\d+)-${tag}-x\"></template>|x-${tag}-(\\\\d+)-${tag}-x)`, 'g');\nfunction placeholder(variableParts: Array<HtmlFragment>, n: number): string {\n    const all_stringy = (f: HtmlFragment): boolean => {\n        if (Array.isArray(f)) return f.every(all_stringy);\n        if (typeof f === 'object') return false;\n        return true;\n    };\n    if (all_stringy(variableParts[n])) {\n        return `x-${tag}-${n}-${tag}-x`;\n    } else {\n        return `<template id=\"x-${tag}-${n}-${tag}-x\"></template>`;\n    }\n}\n\nfunction splitByPlaceholders(s: string): { constantParts: string[], placeholders: number[] } {\n    let match: RegExpExecArray | null = null;\n    let lastConstantStart = 0;\n    const constantParts: string[] = [];\n    const placeholders: number[] = [];\n    while ((match = allPlaceholdersRe.exec(s)) !== null) {\n        constantParts.push(s.substring(lastConstantStart, match.index));\n        placeholders.push(parseInt(match[2] ?? match[3], 10));\n        lastConstantStart = allPlaceholdersRe.lastIndex;\n    }\n    constantParts.push(s.substring(lastConstantStart));\n    return { constantParts, placeholders };\n}\n\nfunction renderFragment(f: HtmlFragment, escapeStrings: boolean): string[] {\n    const result: string[] = [];\n    function walk(f: HtmlFragment) {\n        if (Array.isArray(f)) {\n            f.forEach(walk);\n        } else {\n            switch (typeof f) {\n                case 'string': result.push(escapeStrings ? escape(f) : f); break;\n                case 'number': result.push('' + f); break;\n                default: throw new Error(\"Cannot render Node in attribute context\");\n            }\n        }\n    }\n    walk(f);\n    return result;\n}\n\nfunction followPath(topNode: ParentNode, path: number[]): Node {\n    let n = topNode.childNodes[path[0]];\n    for (let j = 1; j < path.length; j++) n = n.childNodes[path[j]];\n    return n;\n}\n\ninterface VariableLocation {\n    update(variableParts: HtmlFragment[]): void;\n}\n\ninterface VariablePlaceholder {\n    install(placeholderNode: Node): VariableLocation;\n}\n\nclass NodeInserter implements VariablePlaceholder {\n    constructor(public variablePartIndex: number) {}\n\n    install(placeholderNode: Node): VariableLocation {\n        return new NodeInsertionLocation(this.variablePartIndex, placeholderNode);\n    }\n}\n\nclass NodeInsertionLocation implements VariableLocation {\n    insertedNodes: Node[];\n    referenceNode: ChildNode | null;\n    parentNode: ParentNode;\n\n    constructor(public variablePartIndex: number, placeholderNode: Node) {\n        this.insertedNodes = [placeholderNode];\n        this.referenceNode = placeholderNode.nextSibling;\n        this.parentNode = placeholderNode.parentNode!;\n    }\n\n    update(variableParts: HtmlFragment[]): void {\n        this.insertedNodes.forEach(n => {\n            if (n.parentNode === this.parentNode) this.parentNode.removeChild(n);\n        });\n        this.insertedNodes.length = 0;\n\n        const walk = (f: HtmlFragment) => {\n            if (Array.isArray(f)) {\n                f.forEach(walk);\n            } else {\n                switch (typeof f) {\n                    case 'string': this.insertedNodes.push(document.createTextNode(f)); break;\n                    case 'number': this.insertedNodes.push(document.createTextNode('' + f)); break;\n                    case 'object':\n                        if (f !== null && 'nodeType' in f) {\n                            this.insertedNodes.push(f);\n                            break;\n                        }\n                        /* fall through */\n                    default: {\n                        let info;\n                        try {\n                            info = '' + f;\n                        } catch (_e) {\n                            info = (f as any).toString();\n                        }\n                        this.insertedNodes.push(\n                            document.createTextNode(`<ERROR: invalid HtmlFragment: ${info}>`));\n                        break;\n                    }\n                }\n            }\n        }\n        walk(variableParts[this.variablePartIndex]);\n\n        this.insertedNodes.forEach(n => this.parentNode.insertBefore(n, this.referenceNode));\n    }\n}\n\nclass AttributesInserter implements VariablePlaceholder {\n    constructor(public variablePartIndex: number) {}\n\n    install(node: Node): VariableLocation {\n        if (!(node instanceof Element)) throw new Error(\"Cannot attach attributes to non-element\");\n        return new AttributesInsertionLocation(this.variablePartIndex, node);\n    }\n}\n\nclass AttributesInsertionLocation implements VariableLocation {\n    attrNames: string[] = [];\n\n    constructor(public variablePartIndex: number, public node: Element) {}\n\n    update(variableParts: HtmlFragment[]): void {\n        this.attrNames.forEach(n => {\n            this.node.removeAttribute(n);\n            if (n === 'checked' && 'checked' in this.node) this.node.checked = false;\n        });\n        this.attrNames.length = 0;\n\n        const e = document.createElement('template');\n        const v = variableParts[this.variablePartIndex];\n        e.innerHTML = `<x-dummy ${renderFragment(v, false).join('')}></x-dummy>`;\n        Array.from(e.content.firstElementChild!.attributes).forEach(a => {\n            this.attrNames.push(a.name);\n            this.node.setAttribute(a.name, a.value);\n            if (a.name === 'value' && 'value' in this.node) this.node.value = a.value;\n            if (a.name === 'checked' && 'checked' in this.node) this.node.checked = true;\n        });\n    }\n}\n\ntype TemplateAttributeValue = {\n    attrName: string,\n    constantParts: string[],\n    placeholders: number[],\n};\n\nclass AttributeValueInserter implements VariablePlaceholder {\n    constructor(public spec: TemplateAttributeValue) {}\n\n    install(node: Node): VariableLocation {\n        if (!(node instanceof Element)) {\n            throw new Error(`Cannot attach attribute ${this.spec.attrName} to non-element`);\n        }\n        return new AttributeValueInsertionLocation(this.spec, node);\n    }\n}\n\nclass AttributeValueInsertionLocation implements VariableLocation {\n    constructor(public spec: TemplateAttributeValue, public node: Element) {}\n\n    update(variableParts: HtmlFragment[]): void {\n        const pieces = [this.spec.constantParts[0]];\n        this.spec.placeholders.forEach((n, i) => {\n            pieces.push(...renderFragment(variableParts[n], false));\n            pieces.push(this.spec.constantParts[i + 1]);\n        });\n        this.node.setAttribute(this.spec.attrName, pieces.join(''));\n        if (this.spec.attrName === 'value' && 'value' in this.node) this.node.value = pieces.join('');\n    }\n}\n\nclass CompoundPlaceholder implements VariablePlaceholder {\n    constructor(public placeholders: VariablePlaceholder[]) {}\n\n    install(node: Node): VariableLocation {\n        return new CompoundLocation(this.placeholders.map(p => p.install(node)));\n    }\n}\n\nclass CompoundLocation implements VariableLocation {\n    constructor(public locations: VariableLocation[]) {}\n\n    update(variableParts: HtmlFragment[]): void {\n        this.locations.forEach(l => l.update(variableParts));\n    }\n}\n\nexport class HtmlFragmentInstance {\n    nodes: ChildNode[];\n    constructor(\n        public container: ParentNode,\n        public locations: VariableLocation[],\n    ) {\n        this.nodes = Array.from(this.container.childNodes);\n    }\n\n    reset(): Element[] {\n        const placeholders = this.nodes.map(_n => makePlaceholder());\n        placeholders.forEach((p, i) => {\n            const n = this.nodes[i];\n            if (n.parentNode === null) return;\n            if (n.parentNode === this.container) return;\n            n.parentNode.insertBefore(p, n);\n            n.parentNode.removeChild(n);\n        });\n        while (this.container.childNodes.length > 0) { this.container.removeChild(this.container.childNodes[0]); }\n        this.nodes.forEach(n => this.container.appendChild(n));\n        return placeholders;\n    }\n\n    extract(placeholders: Element[]): ChildNode[] {\n        const result = Array.from(this.container.childNodes);\n        placeholders.forEach((p, i) => {\n            const n = this.nodes[i];\n            if (p.parentNode === null) return;\n            p.parentNode.insertBefore(n, p);\n            p.parentNode.removeChild(p);\n        });\n        return result;\n    }\n\n    update(variableParts: HtmlFragment[]): ChildNode[] {\n        const placeholders = this.reset();\n        this.locations.forEach(l => l.update(variableParts));\n        return this.extract(placeholders);\n    }\n}\n\nfunction makePlaceholder(): Element {\n    return document.createElement('x-placeholder');\n}\n\nexport class HtmlFragmentBuilder {\n    template: HTMLTemplateElement = document.createElement('template');\n    placeholderActions: { path: number[], placeholder: VariablePlaceholder }[] = [];\n\n    constructor(constantParts: TemplateStringsArray, variableParts: Array<HtmlFragment>) {\n        // The variableParts are only needed to figure out what kind of placeholder to use: if\n        // ONLY stringy things are found at a given location, placeholder text is used; if any\n        // kind of node is found, a placeholder element is used.\n\n        const pieces: string[] = [];\n        constantParts.raw.forEach((r, i) => {\n            if (i > 0) pieces.push(placeholder(variableParts, i - 1));\n            pieces.push(r);\n        });\n        this.template.innerHTML = pieces.join('');\n        this.indexPlaceholders();\n    }\n\n    private indexTextNode(n: Text, path: number[]): ChildNode | null {\n        const { constantParts, placeholders } =\n            splitByPlaceholders(n.textContent ?? '');\n        constantParts.forEach((c, i) => {\n            if (i > 0) {\n                n.parentNode?.insertBefore(makePlaceholder(), n);\n            }\n            n.parentNode?.insertBefore(document.createTextNode(c), n);\n        });\n        const nextN = n.nextSibling;\n        n.parentNode?.removeChild(n);\n        placeholders.forEach((n, i) => {\n            const currentPath = path.slice();\n            currentPath[currentPath.length - 1] += i * 2 + 1;\n            this.placeholderActions.push({\n                path: currentPath,\n                placeholder: new NodeInserter(n),\n            });\n        });\n        path[path.length - 1] += constantParts.length + placeholders.length;\n        return nextN;\n    }\n\n    private indexElement(e: Element, path: number[]) {\n        const vars: VariablePlaceholder[] = [];\n        for (let i = 0; i < e.attributes.length; i++) {\n            const attr = e.attributes[i];\n            const attrName = attr.name;\n            const nameIsPlaceholder = attrName.match(onePlaceholderRe);\n            if (nameIsPlaceholder !== null) {\n                e.removeAttributeNode(attr);\n                i--;\n                const n = parseInt(nameIsPlaceholder[1], 10);\n                vars.push(new AttributesInserter(n));\n            } else {\n                const { constantParts, placeholders } =\n                    splitByPlaceholders(attr.value);\n                if (constantParts.length !== 1) {\n                    vars.push(new AttributeValueInserter({attrName, constantParts, placeholders}));\n                }\n            }\n        }\n        if (vars.length) {\n            this.placeholderActions.push({\n                path: path.slice(),\n                placeholder: vars.length === 1 ? vars[0] : new CompoundPlaceholder(vars),\n            });\n        }\n    }\n\n    private indexPlaceholders() {\n        const path: number[] = [];\n        const walk = (parentNode: ParentNode) => {\n            path.push(0);\n            let nextN = parentNode.firstChild;\n            while (nextN !== null) {\n                const n = nextN;\n                switch (n.nodeType) {\n                    case Node.TEXT_NODE:\n                        nextN = this.indexTextNode(n as Text, path);\n                        break;\n                    case Node.ELEMENT_NODE: {\n                        const e = n as Element;\n                        nextN = e.nextSibling;\n                        const idMatch = (e.tagName === 'TEMPLATE') ? e.id.match(onePlaceholderRe) : null;\n                        if (idMatch !== null) {\n                            // A specialized variant of indexTextNode.\n                            e.parentNode?.insertBefore(makePlaceholder(), e);\n                            e.parentNode?.removeChild(e);\n                            this.placeholderActions.push({\n                                path: path.slice(),\n                                placeholder: new NodeInserter(parseInt(idMatch[1], 10)),\n                            });\n                        } else {\n                            this.indexElement(e, path)\n                            walk(e);\n                        }\n                        path[path.length - 1]++;\n                        break;\n                    }\n                    default:\n                        nextN = n.nextSibling;\n                        path[path.length - 1]++;\n                        break;\n                }\n            }\n            path.pop();\n        };\n        walk(this.template.content);\n    }\n\n    clone(): HtmlFragmentInstance {\n        const container = this.template.content.cloneNode(true) as ParentNode;\n        const locations = this.placeholderActions.map(({ path, placeholder }) =>\n            placeholder.install(followPath(container, path)));\n        return new HtmlFragmentInstance(container, locations);\n    }\n}\n\n// Nifty trick: TemplateStringsArray instances are interned so it makes sense to key a cache\n// based on their object identity!\nconst templateCache = new WeakMap<TemplateStringsArray, HtmlFragmentBuilder>();\n\nexport type HtmlTemplater =\n    (constantParts: TemplateStringsArray, ... variableParts: Array<HtmlFragment>)\n    => ChildNode[];\n\nexport function template(): HtmlTemplater {\n    const instanceCache = new WeakMap<TemplateStringsArray, HtmlFragmentInstance>();\n    return (constantParts, ... variableParts) => {\n        let b = templateCache.get(constantParts);\n        if (b === void 0) {\n            b = new HtmlFragmentBuilder(constantParts, variableParts);\n            templateCache.set(constantParts, b);\n        }\n        let i = instanceCache.get(constantParts);\n        if (i === void 0) {\n            i = b.clone();\n            instanceCache.set(constantParts, i);\n        }\n        return i.update(variableParts);\n    };\n}\n"],"mappings":"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","names":["src_exports","__export","html_exports","LocationHash","sortedNodes_exports","ValueWidget","Widget","boot","template","templateGenerator","__toCommonJS","__SYNDICATE__","import_core","sortedNodes_exports","__export","SYNDICATE_SORT_KEY","findInsertionPoint","getSortKey","hasSortKey","setSortKey","import_core","n","key","v","firstChildNodeIndex_withSortKey","i","lastChildNodeIndex_withSortKey","isGreaterThan","a","b","lo","hi","probe","probeSortKey","html_exports","__export","HtmlFragmentBuilder","HtmlFragmentInstance","escape","template","import_core","tag","onePlaceholderRe","allPlaceholdersRe","placeholder","variableParts","n","all_stringy","f","splitByPlaceholders","_a","match","lastConstantStart","constantParts","placeholders","renderFragment","escapeStrings","result","walk","followPath","topNode","path","j","NodeInserter","variablePartIndex","placeholderNode","NodeInsertionLocation","info","_e","AttributesInserter","node","AttributesInsertionLocation","e","v","a","AttributeValueInserter","spec","AttributeValueInsertionLocation","pieces","i","CompoundPlaceholder","CompoundLocation","p","locations","l","container","_n","makePlaceholder","r","_b","c","nextN","currentPath","vars","attr","attrName","nameIsPlaceholder","parentNode","idMatch","templateCache","instanceCache","b","LocationHash","boot","ds","spawnLocationHashTracker","isStringOrTemplate","x","Widget","_Widget","arg0","arg1","arg2","nodeGenerator","maybeOptions","templateGenerator","cancelAtExit","thisTemplate","template","_a","_b","nodes","p","getSortKey","k","setSortKey","wrt","sib","findInsertionPoint","selector","ctor","e","es","ws","type","callback","options","cbs","entry","evt","event","r","ValueWidget","value","valueAsNumber","checked","hasValue","hasChecked","_c","n","v","currentSyndicateFacet","currentSyndicateTarget","hashValue","loadHash","h","facet","handlerClosure","__vs","newHash","template0","data","body","kvs","keys","values"]}