marko
Version:
Optimized runtime for Marko templates.
1,296 lines (1,295 loc) • 96.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
//#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/constants/accessor-prefix.debug.ts
const BranchScopes$1 = "BranchScopes:";
const ClosureScopes = "ClosureScopes:";
const ClosureSignalIndex = "ClosureSignalIndex:";
const ConditionalRenderer = "ConditionalRenderer:";
const ControlledObserver = "ControlledObserver:";
const ControlledHandler = "ControlledHandler:";
const ControlledType = "ControlledType:";
const ControlledValue = "ControlledValue:";
const DynamicHTMLLastChild = "DynamicHTMLLastChild:";
const EventAttributes = "EventAttributes:";
const KeyedScopes = "KeyedScopes:";
const Lifecycle = "Lifecycle:";
const Promise$1 = "Promise:";
const TagVariableChange$1 = "TagVariableChange:";
//#endregion
//#region src/common/constants/accessor-prop.debug.ts
const Global = "$global";
const AbortControllers = "#AbortControllers";
const AbortScopes = "#AbortScopes";
const AwaitCounter = "#AwaitCounter";
const BranchAccessor = "#BranchAccessor";
const BranchScopes = "#BranchScopes";
const CatchContent = "#CatchContent";
const ClosestBranch = "#ClosestBranch";
const ClosestBranchId = "#ClosestBranchId";
const Gen$1 = "#Gen";
const DetachedAwait = "#DetachedAwait";
const EndNode = "#EndNode";
const Load = "#Load";
const LoopKey = "#LoopKey";
const ParentBranch = "#ParentBranch";
const PendingEffects = "#PendingEffects";
const PendingRenders = "#PendingRenders";
const PendingScopes = "#PendingScopes";
const PlaceholderBranch = "#PlaceholderBranch";
const PlaceholderContent = "#PlaceholderContent";
const Renderer = "#Renderer";
const StartNode = "#StartNode";
const Subscriptions = "#Subscriptions";
const TagVariable = "#TagVariable";
const TagVariableChange = "#TagVariableChange";
//#endregion
//#region src/common/constants/closure-signal-prop.debug.ts
const ScopeInstancesAccessor = "scopeInstancesAccessor";
const SignalIndexAccessor = "signalIndexAccessor";
const Index = "index";
//#endregion
//#region src/common/constants/keyed-scopes-prop.debug.ts
const PreviousKey = "PreviousKey:";
//#endregion
//#region src/common/constants/load-signal-value.debug.ts
const Value$1 = "value";
const Signal$1 = "signal";
const Scope = "scope";
const Signal = "signal";
const Value = "value";
const Pending = "pending";
const Clone = "clone";
const Setup = "setup";
const Params = "params";
const Owner = "owner";
const Accessor = "accessor";
const LocalClosures = "localClosures";
const LocalClosureValues = "localClosureValues";
//#endregion
//#region src/common/helpers.ts
const htmlAttrNameReg = /^[^a-z_]|[^a-z0-9._:-]/i;
const knownWrongAttrs = {
className: "class",
classList: "class",
htmlFor: "for",
acceptCharset: "accept-charset",
httpEquiv: "http-equiv",
defaultValue: "value",
defaultChecked: "checked",
dangerouslySetInnerHTML: "$!{html}",
key: "<for by>",
ref: "<tag/ref>",
"v-if": "<if>",
"v-else": "<else>",
"v-else-if": "<else if>",
"v-for": "<for>",
"v-show": "<if>",
"v-model": "value:=state",
"v-bind": "...attrs",
"v-html": "$!{html}",
"v-text": "${text}"
};
function getWrongAttrSuggestion(name) {
if (Object.hasOwn(knownWrongAttrs, name)) return knownWrongAttrs[name];
const colon = name.indexOf(":");
if (colon > 0) {
const rest = name.slice(colon + 1);
switch (name.slice(0, colon)) {
case "class": return `class={ ${rest}: condition }`;
case "style": return `style={ ${rest}: value }`;
case "on":
case "v-on": return `on${rest.charAt(0).toUpperCase()}${rest.slice(1)}`;
case "bind":
case "v-model": return `${rest}:=state`;
case "v-bind": return rest;
}
}
}
function _call(fn, v) {
fn(v);
return v;
}
function stringifyClassObject(name, value) {
return value ? name : "";
}
const warnedStyleKeys = /* @__PURE__ */ new Set();
function stringifyStyleObject(name, value) {
if (/[A-Z]/.test(name) && !name.includes("-") && !warnedStyleKeys.has(name)) {
warnedStyleKeys.add(name);
console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`);
}
return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : "";
}
const unsafeStyleAttrReg = /[\\;]/g;
const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\";
function escapeStyleAttr(str) {
return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str;
}
function escapeStyleValue(str) {
let closers = "";
const result = str.replace(/[\\"'{};<>]|\/(?=\*)/g, (c) => c === "<" ? "\\3C " : c === ";" ? "\\3B " : c === "{" ? "\\7B " : "\\" + c);
for (const c of result) if (c === "(") closers = ")" + closers;
else if (c === "[") closers = "]" + closers;
else if (c === closers[0]) closers = closers.slice(1);
return result + closers;
}
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 isPromise(value) {
return value != null && typeof value.then === "function";
}
function normalizeDynamicRenderer(value) {
if (value) {
if (typeof value === "string") return value;
const normalized = value.content || value.default || value;
if (!((typeof normalized === "object" || typeof normalized === "function") && "id" in normalized)) {
if (value.content) throw new Error(`A dynamic tag must be a string tag name (like \`"div"\`) or a Marko template/component, but received an object whose \`content\` is not a template/component.`);
if (typeof value !== "object" && typeof value !== "function") throw new Error(`A dynamic tag must be a string tag name (like \`"div"\`) or a Marko template/component, but received a ${typeof value}.`);
}
if ("id" in normalized) return normalized;
}
}
//#endregion
//#region src/common/errors.ts
const lowercaseEventHandlerReg = /^on[a-z]/;
function assertValidAttrValue(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.`);
if (typeof value === "function") throw new Error(`The \`${name}\` attribute cannot be a function.${/Change$/.test(name) ? " A change handler is only used when its matching controllable attribute combination applies." : ""}`);
const unrenderable = describeUnrenderable(value);
if (unrenderable) throw new Error(`The \`${name}\` attribute cannot be ${unrenderable}.`);
}
function assertValidTextValue(value) {
const unrenderable = describeUnrenderable(value);
if (unrenderable) throw new Error(`Text content cannot be ${unrenderable}.`);
}
function describeUnrenderable(value) {
if (typeof value === "symbol") return "a symbol";
if (typeof value === "object" && value !== null) {
let stringified;
try {
stringified = `${value}`;
} catch {
stringified = "[object Object]";
}
if (/^\[object \w+\]$/.test(stringified)) return stringified === "[object Promise]" ? "a promise (use the `<await>` tag to render its resolved value)" : stringified === "[object Object]" ? "a plain object (it would render as `[object Object]`)" : `a value that renders as \`${stringified}\``;
}
}
function assertValidLoopKey(key, seenKeys) {
if (typeof key !== "string" && typeof key !== "number") throw new Error(`A \`<for>\` tag's \`by\` attribute must return a string or number for each item, but received ${key === null ? "null" : `type "${typeof key}"`}.`);
if (seenKeys) {
if (seenKeys.has(key)) throw new Error(`A \`<for>\` tag's \`by\` attribute must return a unique value for each item, but \`${key}\` was used more than once.`);
seenKeys.add(key);
}
}
function assertValidList(value) {
if (value && typeof value[Symbol.iterator] !== "function") throw new Error(`A \`<for>\` tag's \`of\` attribute must be an iterable, such as an array, but received ${describeForValue(value)}.`);
}
function assertValidRangeBound(name, value) {
if (!isFinite(value)) throw new Error(`A \`<for>\` tag's \`${name}\` attribute must be a finite number, but received ${describeForValue(value)}.`);
}
function describeForValue(value) {
return typeof value === "number" || typeof value === "bigint" ? `\`${value}\`` : value === null ? "null" : `type "${typeof value}"`;
}
function assertValidAttrName(name) {
if (htmlAttrNameReg.test(name)) throw new Error(`Invalid attribute name: ${JSON.stringify(name)}`);
const suggestion = getWrongAttrSuggestion(name);
if (suggestion) throw new Error(`\`${name}\` is not a valid attribute, did you mean \`${suggestion}\`?`);
}
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 ("checkedValue" in attrs) {
(exclusiveAttrs ||= []).push("checkedValue");
if ("checked" in attrs) exclusiveAttrs.push("checked");
} else if (attrs.checkedValueChange) {
(exclusiveAttrs ||= []).push("checkedValueChange");
if ("checked" in attrs) exclusiveAttrs.push("checked");
}
if (attrs.valueChange) (exclusiveAttrs ||= []).push("valueChange");
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
}
}
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) {
assertValidList(list);
if (list) {
let i = 0;
for (const item of list) cb(item, i++);
}
}
function forTo(to, from, step, cb) {
assertValidRangeBound("to", to);
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) {
assertValidRangeBound("until", until);
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/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 forEach(opt, cb) {
if (opt) if (Array.isArray(opt)) for (const item of opt) cb(item);
else cb(opt);
}
function push(opt, item) {
return opt ? Array.isArray(opt) ? (opt.push(item), opt) : [opt, item] : item;
}
//#endregion
//#region src/dom/event.ts
function _on(element, type, handler) {
assertHandlerIsFunction("on" + type[0].toUpperCase() + type.slice(1), handler);
if (element["$" + type] === void 0) delegate(type, handleDelegated);
element["$" + type] = handler || null;
}
const delegate = (type, handler) => handler[type] ||= (document.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/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$1]: runId,
[ClosestBranch]: closestBranch,
[Global]: $global
};
collectingScopes?.push(scope);
return scope;
}
function syncGen(scope) {
scope[Gen$1] = 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);
cleanupScope(scope);
}
}
const destroyNestedScopes = function destroyNestedScopes(scope) {
scope[Gen$1] = 0;
scope[BranchScopes]?.forEach(destroyNestedScopes);
scope[AbortScopes]?.forEach(cleanupScope);
};
function cleanupScope(scope) {
scope[Subscriptions]?.forEach(unsubscribe, scope);
for (const id in scope[AbortControllers]) $signalReset(scope, id);
}
function unsubscribe(subscribers) {
subscribers.delete(this);
}
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$1 + 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$1 + 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 _for_selector(ownerLoopNodeAccessor, ownerValueAccessor, keyValueAccessor, fn) {
const scopeAccessor = BranchScopes$1 + ownerLoopNodeAccessor;
const mapAccessor = KeyedScopes + ownerLoopNodeAccessor;
const prevKeyProp = `${PreviousKey}${ownerValueAccessor}`;
const ownerSignal = (ownerScope) => {
const scopes = toArray(ownerScope[scopeAccessor]);
if (ownerScope["#Gen"] < runId && scopes.length) {
const nextKey = ownerScope[ownerValueAccessor];
queueRender(ownerScope, () => {
const map = keyedScopes(ownerScope, scopeAccessor, mapAccessor, keyValueAccessor);
if (map && prevKeyProp in map) {
const prevScope = map.get(map[prevKeyProp]);
const nextScope = map.get(nextKey);
if (prevScope !== nextScope) {
runLiveBranch(prevScope, fn);
runLiveBranch(nextScope, fn);
}
} else for (const scope of toArray(ownerScope[scopeAccessor])) runLiveBranch(scope, fn);
if (map) map[prevKeyProp] = nextKey;
}, -1, 0, scopes[0]["#Id"]);
}
};
ownerSignal._ = fn;
return ownerSignal;
}
function keyedScopes(ownerScope, scopeAccessor, mapAccessor, keyValueAccessor) {
const map = ownerScope[mapAccessor] ||= /* @__PURE__ */ new Map();
if (!map.size) for (const scope of toArray(ownerScope[scopeAccessor])) {
const key = scope["#LoopKey"] ?? scope[keyValueAccessor];
if (key === void 0) return ownerScope[mapAccessor] = null;
scope[LoopKey] = key;
map.set(key, scope);
}
return map;
}
function runLiveBranch(scope, fn) {
if (scope && scope["#Gen"] > 0 && scope["#Gen"] < runId) fn(scope);
}
function _if_closure(ownerConditionalNodeAccessor, branch, fn) {
const scopeAccessor = BranchScopes$1 + 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();
const { size } = subscribers;
if (subscribers.add(scope).size !== size) trackCleanup(scope, subscribers);
}
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
/** Cloned templates are small, where a TreeWalker's per-step cost dominates. */
let currentNode;
function walk(startNode, walkCodes, branch) {
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) scope[getDebugKey(currentScopeIndex++, currentNode)] = currentNode;
else if (value === 37 || value === 49) {
currentNode.replaceWith(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 = 25 * currentMultiplier + value - 67;
while (value--) walkNextNode();
} else if (value < 107) {
value = 10 * currentMultiplier + value - 97;
while (value--) walkNextSibling();
} else if (value < 117) {
value = 10 * currentMultiplier + value - 107;
while (value--) currentNode = currentNode.parentNode || currentNode;
walkNextSibling();
} 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;
}
const walkNextNode = () => {
if (currentNode.firstChild) return currentNode = currentNode.firstChild;
while (!currentNode.nextSibling && currentNode.parentNode) currentNode = currentNode.parentNode;
walkNextSibling();
};
const walkNextSibling = () => currentNode = currentNode.nextSibling || currentNode;
//#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] = 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 = [], deferredOwners = [], curBranchScopes) => {
return (branchId, branch, endedBranches, accessor, singleNode, parent = visit.parentNode, startVisit = visit, i = orphanBranches.length, j = deferredOwners.length) => {
if (visitType !== "[") {
visitScope[nextToken()] = visitType === ")" || visitType === "}" ? parent : visit;
accessor = BranchScopes$1 + 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["_"] ??= visitScope;
branch[EndNode] = branch[StartNode] = startVisit;
if (visitType === "'") branch[getDebugKey(0, startVisit)] = startVisit;
} else {
curBranchScopes = push(curBranchScopes, branch);
if (accessor) {
visitScope[accessor] = curBranchScopes;
forEach(curBranchScopes, (scope) => scope["_"] ??= visitScope);
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 - 1]["#Id"] > branchId) {
i--;
setParentBranch(orphanBranches.pop(), branch);
}
while (j && deferredOwners[j - 1]["#Id"] > branchId) {
j--;
const owner = deferredOwners.pop();
if (owner["#ClosestBranch"] !== owner) owner[ClosestBranch] = 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);
} else deferredOwners.push(visitScope);
};
};
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/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/dom.ts
function _to_text(value) {
assertValidTextValue(value);
return value || value === 0 ? value + "" : "";
}
function _attr(element, name, value) {
assertValidAttrValue(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 _style_shell(scope, nodeAccessor) {
const element = scope[nodeAccessor];
const id = _id(scope);
_attr_nonce(scope, nodeAccessor);
element.className = id;
_text_content(element, "." + id + "~*{}");
}
function _style_rule_item(element, name, value) {
const text = element.textContent;
const decl = name + ":" + escapeStyleValue(_to_text(value)) + ";";
let start = text.indexOf("{" + name + ":");
if (!~start) start = text.indexOf(";" + name + ":");
_text_content(element, ~start ? text.slice(0, ++start) + decl + text.slice(text.indexOf(";", start) + 1) : text.slice(0, -1) + decl + "}");
}
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, controllable) {
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, controllable);
}
function _attrs_content(scope, nodeAccessor, nextAttrs, controllable) {
_attrs(scope, nodeAccessor, nextAttrs, controllable);
_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, controllable) {
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, controllable);
}
function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip, controllable) {
_attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable);
_attr_content(scope, nodeAccessor, nextAttrs?.content);
}
function attrsInternal(scope, nodeAccessor, nextAttrs, controllable) {
const el = scope[nodeAccessor];
let events = scope[EventAttributes + nodeAccessor];
let skip = void 0;
for (const name in events) events[name] = 0;
if (controllable) {
scope[ControlledType + nodeAccessor] = 5;
scope[ControlledHandler + nodeAccessor] = 0;
if (nextAttrs) skip = controllable(scope, nodeAccessor, nextAttrs);
}
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:
assertValidAttrName(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$1 + nodeAccessor]);
}
for (const accessor in content?.[LocalClosures]) content[LocalClosures][accessor](scope[BranchScopes$1 + nodeAccessor], content[LocalClosureValues][accessor]);
}
function _attrs_script(scope, nodeAccessor) {
const el = scope[nodeAccessor];
const events = scope[EventAttributes + nodeAccessor];
controllableScripts[scope[ControlledType + nodeAccessor]]?.(scope, nodeAccessor);
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;
{
const snapshot = { ...thisObj };
Object.assign(thisObj, thisObj.onMount?.());
for (const prop in snapshot) if (!Object.is(snapshot[prop], thisObj[prop])) throw new Error(`Tried to overwrite existing property "${prop}" in <lifecycle> 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) {
if (parentNode.isConnected) parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
else {
const stop = endNode.nextSibling;
while (startNode !== stop) {
const next = startNode.nextSibling;
parentNode.insertBefore(startNode, referenceNode);
startNode = next;
}
}
return parentNode;
}
function toInsertNode(startNode, endNode) {
return startNode === endNode ? startNode : insertChildNodes(new DocumentFragment(), null, startNode, endNode);
}
//#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/controllable.ts
let inputType = "";
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;
}
}
/** Filled by the latches a compiled page emits, so a page carries only the
* control kinds its tags can be (`_attrs_script` resolves the kind at run time). */
const controllableScripts = {};
/** The render pass equivalent, for a tag whose name is only known at run time;
* a statically named tag passes its claim to `_attrs` instead. */
const controllableRenders = {};
function _enable_controllable_input() {
controllableScripts[0] = _attr_input_checked_script;
controllableScripts[1] = _attr_input_checkedValue_script;
controllableScripts[2] = _attr_input_value_script;
}
function _enable_controllable_textarea() {
controllableScripts[2] = _attr_input_value_script;
}
function _enable_controllable_select() {
controllableScripts[3] = _attr_select_value_script;
}
function _enable_controllable_open() {
controllableScripts[4] = _attr_details_or_dialog_open_script;
}
/** A run-time tag name can be any controllable, so its page enables them all. */
function _enable_controllable() {
_enable_controllable_input();
_enable_controllable_select();
_enable_controllable_open();
controllableRenders.INPUT = _controllable_input;
controllableRenders.TEXTAREA = _controllable_textarea;
controllableRenders.SELECT = _controllable_select;
controllableRenders.DETAILS = controllableRenders.DIALOG = _controllable_open;
}
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 controlledValueKey = ControlledValue + nodeAccessor;
const oldValue = scope[controlledValueKey];
let 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 document.querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) {
if (newValue === void 0 && radio.defaultChecked) newValue = radio.value;