marko
Version:
Optimized runtime for Marko templates.
1,321 lines • 77.1 kB
JavaScript
//#region src/common/attr-tag.ts
const empty = [];
const rest = Symbol("Attribute Tag");
function attrTag(attrs) {
attrs[Symbol.iterator] = attrTagIterator;
attrs[rest] = empty;
return attrs;
}
function attrTags(first, attrs) {
if (first) {
if (first[rest] === empty) first[rest] = [attrs];
else first[rest].push(attrs);
return first;
}
return attrTag(attrs);
}
function* attrTagIterator() {
yield this;
yield* this[rest];
}
//#endregion
//#region src/common/errors.ts
const lowercaseEventHandlerReg = /^on[a-z]/;
function _el_read_error() {
throw new Error("Element references can only be read in scripts and event handlers.");
}
function _hoist_read_error() {
throw new Error("Hoisted values can only be read in scripts and event handlers.");
}
function _assert_hoist(value) {
if (typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
}
function assertExclusiveAttrs(attrs, onError = throwErr) {
if (attrs) {
let exclusiveAttrs;
if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
if (attrs.checkedValue) {
(exclusiveAttrs ||= []).push("checkedValue");
if (attrs.checked) exclusiveAttrs.push("checked");
} else if (attrs.checkedValueChange) {
(exclusiveAttrs ||= []).push("checkedValueChange");
if (attrs.checked) exclusiveAttrs.push("checked");
}
if (attrs.valueChange) (exclusiveAttrs ||= []).push("valueChange");
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
}
}
function assertValidEventHandlerAttr(name, value) {
if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`);
}
function assertHandlerIsFunction(name, value) {
if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`);
}
function assertValidTagName(tagName) {
if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`);
}
function throwErr(msg) {
throw new Error(msg);
}
function joinWithAnd(a) {
switch (a.length) {
case 0: return "";
case 1: return a[0];
case 2: return `${a[0]} and ${a[1]}`;
default: return `${a.slice(0, -1).join(", ")}, and ${a[a.length - 1]}`;
}
}
//#endregion
//#region src/common/for.ts
function forIn(obj, cb) {
for (const key in obj) cb(key, obj[key]);
}
function forOf(list, cb) {
if (list) {
let i = 0;
for (const item of list) cb(item, i++);
}
}
function forTo(to, from, step, cb) {
const start = from || 0;
const delta = step || 1;
for (let steps = (to - start) / delta, i = 0; i <= steps; i++) cb(start + i * delta);
}
function forUntil(until, from, step, cb) {
const start = from || 0;
const delta = step || 1;
for (let steps = (until - start) / delta, i = 0; i < steps; i++) cb(start + i * delta);
}
//#endregion
//#region src/common/helpers.ts
const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i;
function _call(fn, v) {
fn(v);
return v;
}
function stringifyClassObject(name, value) {
return value ? name : "";
}
function stringifyStyleObject(name, value) {
return value || value === 0 ? name + ":" + value : "";
}
const toDelimitedString = function toDelimitedString(val, delimiter, stringify) {
let str = "";
let sep = "";
let part;
if (val) if (typeof val !== "object") str += val;
else if (Array.isArray(val)) for (const v of val) {
part = toDelimitedString(v, delimiter, stringify);
if (part) {
str += sep + part;
sep = delimiter;
}
}
else for (const name in val) {
part = stringify(name, val[name]);
if (part) {
str += sep + part;
sep = delimiter;
}
}
return str;
};
function isEventHandler(name) {
return /^on[A-Z-]/.test(name);
}
function getEventHandlerName(name) {
return name[2] === "-" ? name.slice(3) : name.slice(2).toLowerCase();
}
function isNotVoid(value) {
return value != null && value !== false;
}
function normalizeDynamicRenderer(value) {
if (value) {
if (typeof value === "string") return value;
const normalized = value.content || value.default || value;
if ("id" in normalized) return normalized;
}
}
//#endregion
//#region src/common/meta.ts
const DYNAMIC_TAG_SCRIPT_REGISTER_ID = "_dynamicTagScript";
//#endregion
//#region src/common/opt.ts
function toArray(opt) {
return opt ? Array.isArray(opt) ? opt : [opt] : [];
}
function push(opt, item) {
return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
}
//#endregion
//#region src/dom/event.ts
const defaultDelegator = /* @__PURE__ */ createDelegator();
function _on(element, type, handler) {
assertHandlerIsFunction("on" + type[0].toUpperCase() + type.slice(1), handler);
if (element["$" + type] === void 0) defaultDelegator(element, type, handleDelegated);
element["$" + type] = handler || null;
}
/* @__NO_SIDE_EFFECTS__ */
function createDelegator() {
const kEvents = Symbol();
return function ensureDelegated(node, type, handler) {
((node = node.getRootNode())[kEvents] ||= {})[type] ||= (node.addEventListener(type, handler, true), 1);
};
}
function handleDelegated(ev) {
let target = !rendering && ev.target;
Object.defineProperty(ev, "currentTarget", {
configurable: true,
get() {
console.error("Event.currentTarget is not supported in Marko's delegated events. Instead use an element reference or the second parameter of the event handler.");
return null;
}
});
while (target) {
target["$" + ev.type]?.(ev, target);
target = ev.bubbles && !ev.cancelBubble && target.parentNode;
}
delete ev.currentTarget;
}
//#endregion
//#region src/dom/resolve-cursor-position.ts
const R = /[^\p{L}\p{N}]/gu;
function resolveCursorPosition(inputType, initialPosition, initialValue, updatedValue) {
if ((initialPosition || initialPosition === 0) && (initialPosition !== initialValue.length || /kw/.test(inputType))) {
const before = initialValue.slice(0, initialPosition);
const after = initialValue.slice(initialPosition);
if (updatedValue.startsWith(before)) return initialPosition;
if (updatedValue.endsWith(after)) return updatedValue.length - after.length;
let count = before.replace(R, "").length;
let pos = 0;
while (count && updatedValue[pos]) if (updatedValue[pos++].replace(R, "")) count--;
return pos;
}
return -1;
}
//#endregion
//#region src/dom/parse-html.ts
const parsers = {};
function parseHTML(html, ns) {
const parser = parsers[ns] ||= document.createElementNS(ns, "template");
parser.innerHTML = html;
return parser.content || parser;
}
//#endregion
//#region src/dom/scope.ts
let nextScopeId = 1e6;
let collectingScopes;
function createScope($global, closestBranch) {
const scope = {
["#Id"]: nextScopeId++,
["#Gen"]: runId,
["#ClosestBranch"]: closestBranch,
["$global"]: $global
};
collectingScopes?.push(scope);
return scope;
}
function syncGen(scope) {
scope["#Gen"] = runId;
}
function _assert_init(scope, accessor) {
if (scope["#Gen"] === runId || !(accessor in scope)) throw new ReferenceError(`Cannot access '${accessor}' before initialization`);
return scope[accessor];
}
function collectScopes(fn) {
const prev = collectingScopes;
collectingScopes = [];
try {
fn();
return collectingScopes;
} finally {
collectingScopes = prev;
}
}
function skipScope() {
return nextScopeId++;
}
function findBranchWithKey(scope, key) {
let branch = scope["#ClosestBranch"];
while (branch && branch[key] == null) branch = branch["#ParentBranch"];
return branch;
}
function destroyBranch(branch) {
branch["#ParentBranch"]?.["#BranchScopes"]?.delete(branch);
destroyNestedScopes(branch);
}
function destroyScope(scope) {
if (scope["#Gen"]) {
destroyNestedScopes(scope);
resetControllers(scope);
}
}
const destroyNestedScopes = function destroyNestedScopes(scope) {
scope["#Gen"] = 0;
scope["#BranchScopes"]?.forEach(destroyNestedScopes);
scope["#AbortScopes"]?.forEach(resetControllers);
};
function resetControllers(scope) {
for (const id in scope["#AbortControllers"]) $signalReset(scope, id);
}
function removeAndDestroyBranch(branch) {
destroyBranch(branch);
removeChildNodes(branch["#StartNode"], branch["#EndNode"]);
}
function insertBranchBefore(branch, parentNode, nextSibling) {
insertChildNodes(parentNode, nextSibling, branch["#StartNode"], branch["#EndNode"]);
}
function tempDetachBranch(branch) {
const fragment = new DocumentFragment();
fragment.namespaceURI = branch["#StartNode"].parentNode.namespaceURI;
insertChildNodes(fragment, null, branch["#StartNode"], branch["#EndNode"]);
}
//#endregion
//#region src/dom/schedule.ts
let runTask;
let isScheduled;
let channel;
function schedule() {
if (!isScheduled) {
if (console.createTask) {
const task = console.createTask("queue");
runTask = () => task.run(run);
} else runTask = run;
isScheduled = 1;
queueMicrotask(flushAndWaitFrame);
}
}
function flushAndWaitFrame() {
requestAnimationFrame(triggerMacroTask);
runTask();
}
function triggerMacroTask() {
if (!channel) {
channel = new MessageChannel();
channel.port1.onmessage = () => {
isScheduled = 0;
{
const run = runTask;
runTask = void 0;
run();
}
};
}
channel.port2.postMessage(0);
}
//#endregion
//#region src/dom/signals.ts
function _let(id, fn) {
const valueAccessor = id.slice(0, id.lastIndexOf("/"));
id = +id.slice(id.lastIndexOf("/") + 1);
return (scope, value) => {
if (rendering) {
if (scope["#Gen"] === runId) {
scope[valueAccessor] = value;
fn?.(scope);
}
} else if ((scope[valueAccessor] !== value || !(valueAccessor in scope)) && (scope[valueAccessor] = value, fn)) {
schedule();
queueRender(scope, fn, id);
}
return value;
};
}
function _let_change(id, fn) {
const valueAccessor = id.slice(0, id.lastIndexOf("/"));
const valueChangeAccessor = "TagVariableChange:" + valueAccessor;
const base = _let(id, fn);
return (scope, value, valueChange) => {
if (rendering) if ((scope[valueChangeAccessor] = valueChange) && (scope[valueAccessor] !== value || !(valueAccessor in scope))) {
scope[valueAccessor] = value;
fn?.(scope);
} else base(scope, value);
else if (scope[valueChangeAccessor]) scope[valueChangeAccessor](value);
else base(scope, value);
return value;
};
}
function _const(valueAccessor, fn) {
return ((scope, value) => {
if (scope[valueAccessor] !== value || !(valueAccessor in scope)) {
scope[valueAccessor] = value;
fn?.(scope);
}
});
}
function _or(id, fn, defaultPending = 1, scopeIdAccessor = "#Id") {
return (scope) => {
if (scope["#Gen"] === runId) if (id in scope) {
if (!--scope[id]) fn(scope);
} else scope[id] = defaultPending;
else queueRender(scope, fn, id, 0, scope[scopeIdAccessor]);
};
}
function _for_closure(ownerLoopNodeAccessor, fn) {
const scopeAccessor = "BranchScopes:" + ownerLoopNodeAccessor;
const ownerSignal = (ownerScope) => {
const scopes = toArray(ownerScope[scopeAccessor]);
if (scopes.length) queueRender(ownerScope, () => {
for (const scope of scopes) if (scope["#Gen"] > 0 && scope["#Gen"] < runId) fn(scope);
}, -1, 0, scopes[0]["#Id"]);
};
ownerSignal._ = fn;
return ownerSignal;
}
function _if_closure(ownerConditionalNodeAccessor, branch, fn) {
const scopeAccessor = "BranchScopes:" + ownerConditionalNodeAccessor;
const branchAccessor = "ConditionalRenderer:" + ownerConditionalNodeAccessor;
const ownerSignal = (scope) => {
const ifScope = scope[scopeAccessor];
if (ifScope && ifScope["#Gen"] > 0 && ifScope["#Gen"] < runId && (scope[branchAccessor] || 0) === branch) queueRender(ifScope, fn, -1);
};
ownerSignal._ = fn;
return ownerSignal;
}
function subscribeToScopeSet(ownerScope, accessor, scope) {
const subscribers = ownerScope[accessor] ||= /* @__PURE__ */ new Set();
if (!subscribers.has(scope)) {
subscribers.add(scope);
$signal(scope, -1).addEventListener("abort", () => ownerScope[accessor].delete(scope));
}
}
function _closure(...closureSignals) {
const [firstSignal] = closureSignals;
const scopeInstances = firstSignal["scopeInstancesAccessor"];
const signalIndex = firstSignal["signalIndexAccessor"];
for (let i = closureSignals.length; i--;) closureSignals[i]["index"] = i;
return (scope) => {
if (scope[scopeInstances]) {
for (const childScope of scope[scopeInstances]) if (childScope["#Gen"] > 0 && childScope["#Gen"] < runId) queueRender(childScope, closureSignals[childScope[signalIndex] || 0], -1);
}
};
}
function _closure_get(valueAccessor, fn, getOwnerScope, resumeId) {
const closureSignal = ((scope) => {
scope[closureSignal["signalIndexAccessor"]] = closureSignal["index"];
fn(scope);
subscribeToScopeSet(getOwnerScope ? getOwnerScope(scope) : scope["_"], closureSignal["scopeInstancesAccessor"], scope);
});
closureSignal["scopeInstancesAccessor"] = "ClosureScopes:" + valueAccessor;
closureSignal["signalIndexAccessor"] = "ClosureSignalIndex:" + valueAccessor;
resumeId && _resume(resumeId, closureSignal);
return closureSignal;
}
function _child_setup(setup) {
setup._ = (scope, owner) => {
scope["_"] = owner;
queueRender(scope, setup, -1);
};
return setup;
}
function _var(scope, childAccessor, signal) {
scope[childAccessor]["#TagVariable"] = (value) => signal(scope, value);
}
const _return = (scope, value) => scope["#TagVariable"]?.(value);
function _return_change(scope, changeHandler) {
if (changeHandler) scope["#TagVariableChange"] = changeHandler;
}
const _var_change = (scope, value, name = "This") => {
if (typeof scope["#TagVariableChange"] !== "function") throw new TypeError(`${name} is a readonly tag variable.`);
scope["#TagVariableChange"](value);
};
const tagIdsByGlobal = /* @__PURE__ */ new WeakMap();
function _id({ ["$global"]: $global }) {
const id = tagIdsByGlobal.get($global) || 0;
tagIdsByGlobal.set($global, id + 1);
return "c" + $global.runtimeId + $global.renderId + id.toString(36);
}
function _script(id, fn) {
_resume(id, fn);
return (scope) => {
queueEffect(scope, fn);
};
}
function _el_read(value) {
if (rendering) _el_read_error();
return value;
}
function* traverse(scope, path, i = path.length - 1) {
if (rendering) _hoist_read_error();
if (scope) if (Symbol.iterator in scope) for (const childScope of scope.values()) yield* traverse(childScope, path, i);
else {
const item = scope[path[i]];
if (i) yield* traverse(item, path, i - 1);
else yield typeof item === "function" ? item() : item;
}
}
function _hoist(...path) {
return (scope) => {
const fn = () => traverse(scope, path).next().value;
fn[Symbol.iterator] = () => traverse(scope, path);
return fn;
};
}
function _hoist_resume(id, ...path) {
return _resume(id, _hoist(...path));
}
//#endregion
//#region src/dom/walker.ts
const walker = /* @__PURE__ */ document.createTreeWalker(document);
function walk(startNode, walkCodes, branch) {
walker.currentNode = startNode;
walkInternal(0, walkCodes, branch);
}
const walkInternal = function walkInternal(currentWalkIndex, walkCodes, scope) {
let value;
let currentMultiplier;
let storedMultiplier = 0;
let currentScopeIndex = 0;
for (; currentWalkIndex < walkCodes.length;) {
value = walkCodes.charCodeAt(currentWalkIndex++);
currentMultiplier = storedMultiplier;
storedMultiplier = 0;
if (value === 32) {
const node = walker.currentNode;
scope[getDebugKey(currentScopeIndex++, node)] = node;
} else if (value === 37 || value === 49) {
walker.currentNode.replaceWith(walker.currentNode = scope[getDebugKey(currentScopeIndex++, "#text")] = new Text());
if (value === 49) scope[getDebugKey(currentScopeIndex++, "#scopeOffset")] = skipScope();
} else if (value === 38) return currentWalkIndex;
else if (value === 47 || value === 48) {
currentWalkIndex = walkInternal(currentWalkIndex, walkCodes, scope[getDebugKey(currentScopeIndex++, "#childScope")] = createScope(scope["$global"], scope["#ClosestBranch"]));
if (value === 48) scope[getDebugKey(currentScopeIndex++, "#scopeOffset")] = skipScope();
} else if (value < 92) {
value = 20 * currentMultiplier + value - 67;
while (value--) walker.nextNode();
} else if (value < 107) {
value = 10 * currentMultiplier + value - 97;
while (value--) walker.nextSibling();
} else if (value < 117) {
value = 10 * currentMultiplier + value - 107;
while (value--) walker.parentNode();
walker.nextSibling();
} else {
if (value < 117 || value > 126) throw new Error(`Unknown walk code: ${value}`);
storedMultiplier = currentMultiplier * 10 + value - 117;
}
}
};
function getDebugKey(index, node) {
if (typeof node === "string") return `${node}/${index}`;
else if (node.nodeType === 3) return `#text/${index}`;
else if (node.nodeType === 8) return `#comment/${index}`;
else if (node.nodeType === 1) return `#${node.tagName.toLowerCase()}/${index}`;
return index;
}
//#endregion
//#region src/dom/renderer.ts
function createBranch($global, renderer, parentScope, parentNode) {
const branch = createScope($global);
branch["_"] = renderer["owner"] || parentScope;
setParentBranch(branch, parentScope?.["#ClosestBranch"]);
branch["#Renderer"] = renderer;
renderer["clone"]?.(branch, parentNode.namespaceURI);
return branch;
}
function setParentBranch(branch, parentBranch) {
if (parentBranch) {
branch["#ParentBranch"] = parentBranch;
(parentBranch["#BranchScopes"] ||= /* @__PURE__ */ new Set()).add(branch);
}
branch["#ClosestBranch"] = branch;
}
function createAndSetupBranch($global, renderer, parentScope, parentNode) {
return setupBranch(renderer, createBranch($global, renderer, parentScope, parentNode));
}
function setupBranch(renderer, branch) {
if (renderer["setup"]) queueRender(branch, renderer["setup"], -1);
return branch;
}
function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
setup = setup ? setup._ || setup : void 0;
params ||= void 0;
const clone = template ? (branch, ns) => {
((cloneCache[ns] ||= {})[template] ||= createCloneableHTML(template, ns))(branch, walks);
} : (branch) => {
walk(branch["#StartNode"] = branch["#EndNode"] = new Text(), walks, branch);
};
return (owner) => {
return {
["id"]: id,
["clone"]: clone,
["owner"]: owner,
["setup"]: setup,
["params"]: params,
["accessor"]: dynamicScopesAccessor
};
};
}
function _content_resume(id, template, walks, setup, params, dynamicScopesAccessor) {
return _resume(id, _content(id, template, walks, setup, params, dynamicScopesAccessor));
}
function _content_closures(renderer, closureFns) {
const closureSignals = {};
for (const key in closureFns) closureSignals[key] = _const(key, closureFns[key]);
return (owner, closureValues) => {
const instance = renderer(owner);
instance["localClosures"] = closureSignals;
instance["localClosureValues"] = closureValues;
return instance;
};
}
const cloneCache = {};
function createCloneableHTML(html, ns) {
const { firstChild, lastChild } = parseHTML(html, ns);
const parent = document.createElementNS(ns, "t");
insertChildNodes(parent, null, firstChild, lastChild);
return firstChild === lastChild && firstChild.nodeType < 8 ? (branch, walks) => {
walk(branch["#StartNode"] = branch["#EndNode"] = firstChild.cloneNode(true), walks, branch);
} : (branch, walks) => {
const clone = parent.cloneNode(true);
walk(clone.firstChild, walks, branch);
branch["#StartNode"] = clone.firstChild;
branch["#EndNode"] = clone.lastChild;
};
}
//#endregion
//#region src/dom/resume.ts
const registeredValues = {};
let curRenders;
let branchesEnabled;
let embedRenders;
let readyIds;
function enableBranches() {
if (!branchesEnabled) {
branchesEnabled = 1;
skipDestroyedRenders();
}
}
function ready(readyId) {
(readyIds ||= /* @__PURE__ */ new Set()).add(readyId);
for (const renderId in curRenders) runResumeEffects(curRenders[renderId]);
}
function initEmbedded(readyId, runtimeId) {
if (!embedRenders) {
embedRenders = /* @__PURE__ */ new Map();
new MutationObserver(() => {
for (const [anchor, [renderId, scopes]] of embedRenders) if (!anchor.isConnected) {
embedRenders.delete(anchor);
delete curRenders[renderId];
for (const id in scopes) destroyScope(scopes[id]);
}
}).observe(document, {
childList: true,
subtree: true
});
}
ready(readyId);
init(runtimeId);
}
function init(runtimeId = "M") {
if (curRenders) {
if (curRenders !== self[runtimeId]) throw new Error(`Marko initialized multiple times with different $global.runtimeId's.`);
return;
}
const renders = self[runtimeId];
const defineRuntime = (desc) => Object.defineProperty(self, runtimeId, desc);
const initRuntime = (renders) => {
defineRuntime({ value: curRenders = ((renderId) => {
const render = curRenders[renderId] = renders[renderId] || renders(renderId);
const walk = render.w;
const scopeLookup = {};
const getScope = (id) => scopeLookup[id] || (+id ? initScope(scopeLookup[id] = { ["#Id"]: +id }) : initGlobal());
const initGlobal = () => scopeLookup[0] ||= {
runtimeId,
renderId
};
const initScope = (scope) => {
scope["#Gen"] = 1;
scope["$global"] = initGlobal();
if (branchesEnabled && scope["#ClosestBranchId"]) scope["#ClosestBranch"] = getScope(scope["#ClosestBranchId"]);
return scope;
};
const applyScopes = (partials) => {
let scopeId = partials[0];
for (let i = 1; i < partials.length; i++) {
const partial = partials[i];
if (typeof partial === "number") scopeId += partial;
else {
if (scopeId) initScope(Object.assign(scopeLookup[scopeId] ||= (partial["#Id"] = scopeId, partial), partial));
else Object.assign(initGlobal(), partial);
scopeId++;
}
}
};
const serializeContext = ((data, registryId) => typeof data === "number" ? registryId ? registeredValues[registryId](getScope(data)) : getScope(data) : applyScopes(data));
const createVisitBranches = (branchScopesStack = [], branchStarts = [], orphanBranches = [], curBranchScopes) => {
return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length) => {
if (visitType !== "[") {
visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit;
accessor = "BranchScopes:" + lastToken;
singleNode = visitType !== "]" && visitType !== ")";
nextToken();
}
while (branchId = +lastToken) {
(endedBranches ||= []).push(branch = getScope(branchId));
setParentBranch(branch, branch["#ClosestBranch"]);
if (branch["#AwaitCounter"] = render.p?.[branchId]) branch["#AwaitCounter"].m = render.m;
if (singleNode) {
while (startVisit.previousSibling && ~visits.indexOf(startVisit = startVisit.previousSibling));
branch["#EndNode"] = branch["#StartNode"] = startVisit;
if (visitType === "'") branch[getDebugKey(0, startVisit)] = startVisit;
} else {
curBranchScopes = push(curBranchScopes, branch);
if (accessor) {
visitScope[accessor] = curBranchScopes;
curBranchScopes = branchScopesStack.pop();
}
startVisit = branchStarts.pop();
if (parent !== startVisit.parentNode) parent.prepend(startVisit);
branch["#StartNode"] = startVisit;
branch["#EndNode"] = visit.previousSibling === startVisit ? startVisit : parent.insertBefore(new Text(), visit);
}
while (i && orphanBranches[--i]["#Id"] > branchId) setParentBranch(orphanBranches.pop(), branch);
nextToken();
}
if (endedBranches) {
for (const ended of endedBranches) orphanBranches.push(ended);
if (singleNode) visitScope[accessor] = endedBranches.length > 1 ? endedBranches.reverse() : endedBranches[0];
}
if (visitType === "[") {
if (!endedBranches) {
branchScopesStack.push(curBranchScopes);
curBranchScopes = void 0;
}
branchStarts.push(visit);
}
};
};
const nextToken = () => lastToken = visitText.slice(lastTokenIndex, (lastTokenIndex = visitText.indexOf(" ", lastTokenIndex) + 1 || visitText.length + 1) - 1);
const processResumes = (resumes = [], effects) => {
let i = 0;
for (; i < resumes.length; i++) {
const serialized = resumes[i];
if (typeof serialized === "string") {
lastTokenIndex = 0;
visitText = serialized;
while (nextToken()) if (/\D/.test(lastToken)) lastEffect = registeredValues[lastToken];
else effects.push(lastEffect, getScope(lastToken));
} else if (Array.isArray(serialized)) {
if (!(readyIds && serialized.every((dep) => readyIds.has(dep) && !render.b[dep].length))) break;
} else if (readyIds && typeof serialized === "number") break;
else {
const scopes = serialized(serializeContext);
if (Array.isArray(scopes)) applyScopes(scopes);
}
}
resumes.splice(0, i);
return i;
};
let lastEffect;
let visits;
let visit;
let visitText;
let visitType;
let visitScope;
let lastToken;
let lastTokenIndex;
let visitBranches;
let embedAnchor;
serializeContext._ = registeredValues;
if (render.m) throw new Error(`Marko rendered multiple times with $global.runtimeId as ${JSON.stringify(runtimeId)} and $global.renderId as ${JSON.stringify(renderId)}. Ensure each render into a page has a unique $global.renderId.`);
render.m = (effects) => {
processResumes(render.r, effects);
if (readyIds && render.b) for (let progress = 1; progress;) {
progress = 0;
for (const readyId of readyIds) {
const resumes = render.b[readyId];
if (resumes && processResumes(resumes, effects)) progress = 1;
}
}
let retained = 0;
for (visit of visits = render.v) {
lastTokenIndex = render.i.length;
visitText = visit.data;
visitType = visitText[lastTokenIndex++];
visitScope = getScope(nextToken());
if (visitType === "*") {
const prev = visit.previousSibling;
visitScope[nextToken()] = prev && (prev.nodeType < 8 || prev.data) ? prev : visit.parentNode.insertBefore(new Text(), visit);
} else if (branchesEnabled) (visitBranches ||= createVisitBranches())();
else if (render.b) visits[retained++] = visit;
}
if (embedRenders && !embedAnchor && visit) embedRenders.set(embedAnchor = visit.parentNode.insertBefore(new Text(), visit.nextSibling), [renderId, scopeLookup]);
visits.length = retained;
return effects;
};
render.w = () => {
walk();
runResumeEffects(render);
};
return render;
}) });
};
if (renders) {
initRuntime(renders);
for (const renderId in renders) runResumeEffects(curRenders(renderId));
} else defineRuntime({
configurable: true,
set: initRuntime
});
}
let isResuming;
function runResumeEffects(render) {
try {
isResuming = 1;
runEffects(render.m([]), 1);
} finally {
isResuming = 0;
}
}
function getRegisteredWithScope(id, scope) {
const val = registeredValues[id];
return scope ? val(scope) : val;
}
function _resume(id, obj) {
return registeredValues[id] = obj;
}
function _var_resume(id, signal) {
_resume(id, (scope) => (value) => signal(scope, value));
return signal;
}
function _el(id, accessor) {
return _resume(id, (scope) => () => _el_read(scope[accessor]));
}
//#endregion
//#region src/dom/controllable.ts
let inputType = "";
const controllableDelegate = /* @__PURE__ */ createDelegator();
function _attr_input_checked_default(scope, nodeAccessor, checked) {
const el = scope[nodeAccessor];
const normalizedChecked = isNotVoid(checked);
if (el.defaultChecked !== normalizedChecked) {
const restoreValue = scope["#Gen"] < runId ? el.checked : normalizedChecked;
el.defaultChecked = normalizedChecked;
if (restoreValue !== normalizedChecked) el.checked = restoreValue;
}
}
function _attr_input_checked(scope, nodeAccessor, checked, checkedChange) {
const el = scope[nodeAccessor];
const normalizedChecked = isNotVoid(checked);
assertHandlerIsFunction("checkedChange", checkedChange);
scope["ControlledHandler:" + nodeAccessor] = checkedChange;
scope["ControlledType:" + nodeAccessor] = checkedChange ? 0 : 5;
if (checkedChange && scope["#Gen"] < runId) el.checked = normalizedChecked;
else _attr_input_checked_default(scope, nodeAccessor, normalizedChecked);
}
function _attr_input_checked_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
syncControllableFormInput(el, hasCheckboxChanged, () => {
const checkedChange = scope["ControlledHandler:" + nodeAccessor];
if (checkedChange) {
const newValue = el.checked;
el.checked = !newValue;
checkedChange(newValue);
run();
}
});
}
function _attr_input_checkedValue_default(scope, nodeAccessor, checkedValue, value) {
const multiple = Array.isArray(checkedValue);
const normalizedValue = normalizeStrProp(value);
const normalizedCheckedValue = multiple ? checkedValue.map(normalizeStrProp) : normalizeStrProp(checkedValue);
_attr(scope[nodeAccessor], "value", value);
_attr_input_checked_default(scope, nodeAccessor, multiple ? normalizedCheckedValue.includes(normalizedValue) : normalizedValue === normalizedCheckedValue);
}
function _attr_input_checkedValue(scope, nodeAccessor, checkedValue, checkedValueChange, value) {
const el = scope[nodeAccessor];
const multiple = Array.isArray(checkedValue);
const normalizedCheckedValue = scope["ControlledValue:" + nodeAccessor] = multiple ? checkedValue.map(normalizeStrProp) : normalizeStrProp(checkedValue);
assertHandlerIsFunction("checkedValueChange", checkedValueChange);
scope["ControlledHandler:" + nodeAccessor] = checkedValueChange;
scope["ControlledType:" + nodeAccessor] = checkedValueChange ? 1 : 5;
if (checkedValueChange && scope["#Gen"] < runId) {
el.checked = multiple ? normalizedCheckedValue.includes(normalizeStrProp(value)) : normalizeStrProp(value) === normalizedCheckedValue;
_attr(el, "value", value);
} else _attr_input_checkedValue_default(scope, nodeAccessor, checkedValue, value);
}
function _attr_input_checkedValue_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
if (isResuming && el.defaultChecked) if (scope["ControlledValue:" + nodeAccessor]) scope["ControlledValue:" + nodeAccessor].push(el.value);
else scope["ControlledValue:" + nodeAccessor] = el.value;
syncControllableFormInput(el, hasCheckboxChanged, () => {
const checkedValueChange = scope["ControlledHandler:" + nodeAccessor];
if (checkedValueChange) {
const oldValue = scope["ControlledValue:" + nodeAccessor];
const newValue = Array.isArray(oldValue) ? updateList(oldValue, el.value, el.checked) : el.checked ? el.value : void 0;
if (el.name && el.type[0] === "r") {
for (const radio of el.getRootNode().querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) radio.checked = Array.isArray(oldValue) ? oldValue.includes(radio.value) : oldValue === radio.value;
} else el.checked = !el.checked;
checkedValueChange(newValue);
run();
}
});
}
function _attr_input_value_default(scope, nodeAccessor, value) {
const el = scope[nodeAccessor];
const normalizedValue = normalizeAttrValue(value) || "";
if (el.defaultValue !== normalizedValue) {
const restoreValue = scope["#Gen"] < runId ? el.value : normalizedValue;
el.defaultValue = normalizedValue;
setInputValue(el, restoreValue);
}
}
function _attr_input_value(scope, nodeAccessor, value, valueChange) {
const el = scope[nodeAccessor];
const normalizedValue = normalizeAttrValue(value) || "";
assertHandlerIsFunction("valueChange", valueChange);
scope["ControlledHandler:" + nodeAccessor] = valueChange;
scope["ControlledValue:" + nodeAccessor] = normalizedValue;
scope["ControlledType:" + nodeAccessor] = valueChange ? 2 : 5;
if (valueChange && scope["#Gen"] < runId) setInputValue(el, normalizedValue);
else _attr_input_value_default(scope, nodeAccessor, normalizedValue);
}
function _attr_input_value_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
if (isResuming) scope["ControlledValue:" + nodeAccessor] = el.defaultValue;
syncControllableFormInput(el, hasValueChanged, (ev) => {
const valueChange = scope["ControlledHandler:" + nodeAccessor];
if (valueChange) {
inputType = ev?.inputType;
valueChange(el.value);
run();
setInputValue(el, scope["ControlledValue:" + nodeAccessor]);
inputType = "";
}
});
}
function setInputValue(el, value) {
if (el.value !== value) {
const updatedPosition = resolveCursorPosition(inputType, el.getRootNode().activeElement === el && el.selectionStart, el.value, el.value = value);
if (~updatedPosition) el.setSelectionRange(updatedPosition, updatedPosition);
}
}
function _attr_select_value_default(scope, nodeAccessor, value) {
let restoreValue;
const el = scope[nodeAccessor];
const live = scope["#Gen"] < runId;
const multiple = Array.isArray(value);
const normalizedValue = multiple ? value.map(normalizeStrProp) : normalizeStrProp(value);
pendingEffects.unshift(() => {
for (const opt of el.options) {
const selected = multiple ? normalizedValue.includes(opt.value) : opt.value === normalizedValue;
if (opt.defaultSelected !== selected) {
if (live) restoreValue ??= getSelectValue(el, multiple);
opt.defaultSelected = selected;
}
}
if (restoreValue !== void 0) setSelectValue(el, restoreValue, multiple);
}, scope);
}
function _attr_select_value(scope, nodeAccessor, value, valueChange) {
const el = scope[nodeAccessor];
const existing = scope["#Gen"] < runId;
const multiple = Array.isArray(value);
const normalizedValue = scope["ControlledValue:" + nodeAccessor] = multiple ? value.map(normalizeStrProp) : normalizeStrProp(value);
assertHandlerIsFunction("valueChange", valueChange);
scope["ControlledHandler:" + nodeAccessor] = valueChange;
scope["ControlledType:" + nodeAccessor] = valueChange ? 3 : 5;
if (valueChange && existing) pendingEffects.unshift(() => setSelectValue(el, normalizedValue, multiple), scope);
else _attr_select_value_default(scope, nodeAccessor, normalizedValue);
}
function _attr_select_value_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
const onChange = () => {
const valueChange = scope["ControlledHandler:" + nodeAccessor];
if (valueChange) {
const oldValue = scope["ControlledValue:" + nodeAccessor];
const multiple = Array.isArray(oldValue);
const newValue = getSelectValue(el, multiple);
setSelectValue(el, oldValue, multiple);
valueChange(newValue);
run();
}
};
if (isResuming) if (el.multiple) {
scope["ControlledValue:" + nodeAccessor] = [];
for (const opt of el.options) if (opt.defaultSelected) scope["ControlledValue:" + nodeAccessor].push(opt.value);
} else {
scope["ControlledValue:" + nodeAccessor] = "";
for (const opt of el.options) if (opt.defaultSelected) {
scope["ControlledValue:" + nodeAccessor] = opt.value;
break;
}
}
syncControllableFormInput(el, hasSelectChanged, onChange);
new MutationObserver(() => {
const value = scope["ControlledValue:" + nodeAccessor];
if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((value, i) => value != el.selectedOptions[i].value) : el.value !== value) onChange();
}).observe(el, {
childList: true,
subtree: true
});
}
function setSelectValue(el, value, multiple) {
if (multiple) for (const opt of el.options) opt.selected = value.includes(opt.value);
else el.value = value;
}
function getSelectValue(el, multiple) {
return multiple ? Array.from(el.selectedOptions, (opt) => opt.value) : el.value;
}
function _attr_details_or_dialog_open_default(scope, nodeAccessor, open) {
if (scope["#Gen"] === runId) scope[nodeAccessor].open = isNotVoid(open);
}
function _attr_details_or_dialog_open(scope, nodeAccessor, open, openChange) {
const normalizedOpen = scope["ControlledValue:" + nodeAccessor] = isNotVoid(open);
assertHandlerIsFunction("openChange", openChange);
scope["ControlledHandler:" + nodeAccessor] = openChange;
scope["ControlledType:" + nodeAccessor] = openChange ? 4 : 5;
if (openChange && scope["#Gen"] < runId) scope[nodeAccessor].open = normalizedOpen;
else _attr_details_or_dialog_open_default(scope, nodeAccessor, normalizedOpen);
}
function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
new MutationObserver(() => {
const openChange = scope["ControlledHandler:" + nodeAccessor];
if (openChange && el.open === !scope["ControlledValue:" + nodeAccessor]) {
const newValue = el.open;
el.open = !newValue;
openChange(newValue);
run();
}
}).observe(el, {
attributes: true,
attributeFilter: ["open"]
});
}
function syncControllableFormInput(el, hasChanged, onChange) {
el._ = onChange;
controllableDelegate(el, "input", handleChange);
if (el.form) controllableDelegate(el.form, "reset", handleFormReset);
if (isResuming && hasChanged(el)) queueMicrotask(onChange);
}
function handleChange(ev) {
ev.target._?.(ev);
}
function handleFormReset(ev) {
const handlers = [];
for (const el of ev.target.elements) if (el._ && hasFormElementChanged(el)) handlers.push(el._);
requestAnimationFrame(() => {
if (!ev.defaultPrevented) for (const change of handlers) change();
});
}
function hasValueChanged(el) {
return el.value !== el.defaultValue;
}
function hasCheckboxChanged(el) {
return el.checked !== el.defaultChecked;
}
function hasSelectChanged(el) {
for (const opt of el.options) if (opt.selected !== opt.defaultSelected) return true;
}
function hasFormElementChanged(el) {
return el.options ? hasSelectChanged(el) : hasValueChanged(el) || hasCheckboxChanged(el);
}
function normalizeStrProp(value) {
return normalizeAttrValue(value) || "";
}
function updateList(arr, val, push) {
const index = arr.indexOf(val);
return (push ? !~index && [...arr, val] : ~index && arr.slice(0, index).concat(arr.slice(index + 1))) || arr;
}
//#endregion
//#region src/dom/dom.ts
function _to_text(value) {
return value || value === 0 ? value + "" : "";
}
function _attr(element, name, value) {
assertValidEventHandlerAttr(name, value);
setAttribute(element, name, normalizeAttrValue(value));
}
function setAttribute(element, name, value) {
if (element.getAttribute(name) != value) if (value === void 0) element.removeAttribute(name);
else element.setAttribute(name, value);
}
function _attr_class(element, value) {
setAttribute(element, "class", toDelimitedString(value, " ", stringifyClassObject) || void 0);
}
function _attr_class_items(element, items) {
for (const key in items) _attr_class_item(element, key, items[key]);
}
function _attr_class_item(element, name, value) {
element.classList.toggle(name, !!value);
}
function _attr_style(element, value) {
setAttribute(element, "style", toDelimitedString(value, ";", stringifyStyleObject) || void 0);
}
function _attr_style_items(element, items) {
for (const key in items) _attr_style_item(element, key, items[key]);
}
function _attr_style_item(element, name, value) {
element.style.setProperty(name, _to_text(value));
}
function _attr_nonce(scope, nodeAccessor) {
_attr(scope[nodeAccessor], "nonce", scope["$global"].cspNonce);
}
function _text(node, value) {
const normalizedValue = _to_text(value);
if (node.data !== normalizedValue) node.data = normalizedValue;
}
function _text_content(node, value) {
const normalizedValue = _to_text(value);
if (node.textContent !== normalizedValue) node.textContent = normalizedValue;
}
function _attrs(scope, nodeAccessor, nextAttrs) {
const el = scope[nodeAccessor];
for (let i = el.attributes.length; i--;) {
const { name } = el.attributes.item(i);
if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) el.removeAttribute(name);
}
assertExclusiveAttrs(nextAttrs);
attrsInternal(scope, nodeAccessor, nextAttrs);
}
function _attrs_content(scope, nodeAccessor, nextAttrs) {
_attrs(scope, nodeAccessor, nextAttrs);
_attr_content(scope, nodeAccessor, nextAttrs?.content);
}
function hasAttrAlias(element, attr, nextAttrs) {
return attr === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
}
function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
const el = scope[nodeAccessor];
const partial = {};
for (let i = el.attributes.length; i--;) {
const { name } = el.attributes.item(i);
if (!skip[name] && !(nextAttrs && name in nextAttrs)) el.removeAttribute(name);
}
for (const name in nextAttrs) {
const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
if (!skip[key]) partial[key] = nextAttrs[name];
}
assertExclusiveAttrs({
...nextAttrs,
...skip
});
attrsInternal(scope, nodeAccessor, partial);
}
function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip) {
_attrs_partial(scope, nodeAccessor, nextAttrs, skip);
_attr_content(scope, nodeAccessor, nextAttrs?.content);
}
function attrsInternal(scope, nodeAccessor, nextAttrs) {
const el = scope[nodeAccessor];
let events = scope["EventAttributes:" + nodeAccessor];
let skip;
for (const name in events) events[name] = 0;
switch (el.tagName) {
case "INPUT":
if ("checked" in nextAttrs || "checkedChange" in nextAttrs) _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
else if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
else if ("value" in nextAttrs || "valueChange" in nextAttrs) _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
else break;
skip = /^(?:value|checked(?:Value)?)(?:Change)?$/;
break;
case "SELECT":
if ("value" in nextAttrs || "valueChange" in nextAttrs) {
_attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
skip = /^value(?:Change)?$/;
}
break;
case "TEXTAREA":
if ("value" in nextAttrs || "valueChange" in nextAttrs) {
_attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
skip = /^value(?:Change)?$/;
}
break;
case "DETAILS":
case "DIALOG":
if ("open" in nextAttrs || "openChange" in nextAttrs) {
_attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
skip = /^open(?:Change)?$/;
}
break;
}
for (const name in nextAttrs) {
const value = nextAttrs[name];
switch (name) {
case "class":
_attr_class(el, value);
break;
case "style":
_attr_style(el, value);
break;
default:
if (htmlAttrNameReg.test(name)) throw new Error(`Invalid attribute name: ${JSON.stringify(name)}`);
if (isEventHandler(name)) (events ||= scope["EventAttributes:" + nodeAccessor] = {})[getEventHandlerName(name)] = value;
else if (!(skip?.test(name) || name === "content" && el.tagName !== "META")) _attr(el, name, value);
break;
}
}
}
function _attr_content(scope, nodeAccessor, value) {
const content = normalizeClientRender(value);
if (scope["ConditionalRenderer:" + nodeAccessor] !== (scope["ConditionalRenderer:" + nodeAccessor] = content?.["id"])) {
setConditionalRenderer(scope, nodeAccessor, content, createAndSetupBranch);
if (content?.["accessor"]) subscribeToScopeSet(content["owner"], content["accessor"], scope["BranchScopes:" + nodeAccessor]);
}
for (const accessor in content?.["localClosures"]) content["localClosures"][accessor](scope["BranchScopes:" + nodeAccessor], content["localClosureValues"][accessor]);
}
function _attrs_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
const events = scope["EventAttributes:" + nodeAccessor];
switch (scope["ControlledType:" + nodeAccessor]) {
case 0:
_attr_input_checked_script(scope, nodeAccessor);
break;
case 1:
_attr_input_checkedValue_script(scope, nodeAccessor);
break;
case 2:
_attr_input_value_script(scope, nodeAccessor);
break;
case 3:
_attr_select_value_script(scope, nodeAccessor);
break;
case 4:
_attr_details_or_dialog_open_script(scope, nodeAccessor);
break;
}
for (const name in events) _on(el, name, events[name]);
}
function _html(scope, value, accessor) {
const firstChild = scope[accessor];
const parentNode = firstChild.parentNode;
const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
const newContent = parseHTML(_to_text(value), parentNode.namespaceURI);
insertChildNodes(parentNode, firstChild, scope[accessor] = newContent.firstChild || newContent.appendChild(new Text()), scope["DynamicHTMLLastChild:" + accessor] = newContent.lastChild);
removeChildNodes(firstChild, lastChild);
}
function normalizeClientRender(value) {
const renderer = normalizeDynamicRenderer(value);
if (renderer) if (renderer["id"]) return renderer;
else throw new Error(`Invalid \`content\` attribute. Received ${typeof value}`);
}
function normalizeAttrValue(value) {
if (isNotVoid(value)) return value === true ? "" : value + "";
}
function _lifecycle(scope, thisObj, index = 0) {
const accessor = "Lifecycle:" + index;
const instance = scope[accessor];
if (instance) {
Object.assign(instance, thisObj);
instance.onUpdate?.();
} else {
scope[accessor] = thisObj;
thisObj.onMount?.();
$signal(scope, accessor).onabort = () => thisObj.onDestroy?.();
}
}
function removeChildNodes(startNode, endNode) {
const stop = endNode.nextSibling;
while (startNode !== stop) {
const next = startNode.nextSibling;
startNode.remove();
startNode = next;
}
}
function insertChildNodes(parentNode, referenceNode, startNode, endNode) {
parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
}
function toInsertNode(startNode, endNode) {
if (startNode === endNode) return startNode;
const parent = new DocumentFragment();
const stop = endNode.nextSibling;
while (startNode !== stop) {
const next = startNode.nextSibling;
parent.appendChild(startNode);
startNode = next;
}
return parent;
}
//#endregion
//#region src/dom/control-flow.ts
function _await_promise(nodeAccessor, params) {
const promiseAccessor = "Promise:" + nodeAccessor;
const branchAccessor = "BranchScopes:" + nodeAccessor;
_enable_catch();
return (scope, promise) => {
let awaitBranch = scope[branchAccessor];
const tryPlaceholder = findBranchWithKey(scope, "#PlaceholderContent");
const tryBranch = tryPlaceholder || awaitBranch;
let awaitCounter = tryBranch["#AwaitCounter"];
placeholderShown.add(pendingEffects);
if (tryPlaceholder) {
if (!scope[promiseAccessor]) {
if (awaitBranch) awaitBranch["#PendingRenders"] ||= [];
awaitCounter = addAwaitCounter(scope, tryPlaceholder);
}
} else {
if (!awaitCounter?.i) awaitCounter = tryBranch["#AwaitCounter"] = {
i: 0,
c() {
if (--awaitCounter.i) return 1;
if (tryBranch === scope[branchAccessor]) {
if (scope[nodeAccessor].parentNode) scope[nodeAccessor].replaceWith(scope[branchAccessor]["#StartNode"].parentNode);
} else dismissPlaceholder(tryBranch);
queueEffect(tryBranch, runPendingEffects);
}
};
if (!scope[promiseAccessor]) {
if (awaitBranch) awaitBranch["#PendingRenders"] ||= [];
if (!awaitCounter.i++) requestAnimationFrame(() => awaitCounter.i && runEffects(prepareEffects(() => queueRender(scope, () => {
if (!awaitBranch["#DetachedAwait"]) {
awaitBranch["#StartNode"].parentNode.insertBefore(scope[nodeAccessor], awaitBranch["#StartNode"]);
tempDetachBranch(tryBranch);
}
}, -1))));
}
}
const thisPromise = scope[promiseAccessor] = promise.then((data) => {
if (thisPromise === scope[promiseAccessor]) {
const referenceNode = scope[nodeAccessor];
scope[promiseAccessor] = 0;
queueAsyncRender(scope, () => {
if ((awaitBranch = scope[branchAccessor])["#DetachedAwait"]) {
awaitBranch["#PendingScopes"] = awaitBranch["#PendingScopes"]?.forEach(syncGen);
setupBranch(awaitBranch["#DetachedAwait"], awaitBranch);
awaitBranch["#DetachedAwait"] = 0;
insertBranchBefore(awaitBranch, scope[nodeAccessor].parentNode, scope[nodeAccessor]);
referenceNode.remove();
}
params?.(awaitBranch, [data]);
const pendingRenders = awaitBranch["#PendingRenders"];
awaitBranch["#PendingRenders"] = 0;
pendingRenders?.forEach(queuePendingRender);
placeholderShown.add(pendingEffects);
awaitCounter.c();
if (awaitCounter.m) {
const fnScopes = /* @__PURE__ */ new Map();
const effects = awaitCounter.m([]);
for (let i = 0; i < pendingEffects.length;) {
const fn = pendingEffects[i++];
let scopes = fnScopes.get(fn);
if (!scopes) fnScopes.set(fn, scopes = /* @__PURE__ */ new Set());
scopes.add(pendingEffects[i++]);
}
for (let i = 0; i < effects.length;) {
const fn = effects[i++];
const scope = effects[i++];
if (!fnScopes.get(fn)?.has(scope)) queueEffect(scope, fn);
}
}
});
}
}, (error) => {
if (thisPromise === scope[promiseAccessor]) {
awaitCounter.i = scope[promiseAccessor] = 0;
queueAsyncRender(scope, renderCatch, error);
}
});
};
}
function _await_content(nodeAccessor, template, walks, setup) {
const branchAccessor = "BranchScopes:" + nodeAccessor;
const renderer = _content("", template, walks, setup)();
return (scope) => {
const pendingScopes = collectScopes(() => (scope[branchAccessor] = createBranch(scope["$global"], renderer, scope, scope[nodeAccessor].parentNode))["#DetachedAwait"] = renderer);
scope[branchAccessor]["#PendingScopes"] = pendingScopes;
};
}
function addAwaitCounter(scope, tryBranch = fi