@wcstack/state 2.6.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.ja.md +97 -41
  2. package/README.md +99 -41
  3. package/dist/auto.min.js +1 -1
  4. package/dist/auto.min.js.map +1 -1
  5. package/dist/define.d.ts +295 -0
  6. package/dist/define.js +1 -0
  7. package/dist/index.d.ts +252 -94
  8. package/dist/index.esm.js +1 -23342
  9. package/dist/index.esm.js.map +1 -1
  10. package/dist/manifest.esm.js +21 -37
  11. package/dist/parser.d.ts +37 -39
  12. package/dist/parser.esm.js +147 -1153
  13. package/dist/split/chunks/binder.js +2 -0
  14. package/dist/split/chunks/binder.js.map +1 -0
  15. package/dist/split/chunks/checkDependency.js +2 -0
  16. package/dist/split/chunks/checkDependency.js.map +1 -0
  17. package/dist/split/chunks/diagnosticsHooks.js +2 -0
  18. package/dist/split/chunks/diagnosticsHooks.js.map +1 -0
  19. package/dist/split/chunks/errorGuidance.js +2 -0
  20. package/dist/split/chunks/errorGuidance.js.map +1 -0
  21. package/dist/split/chunks/features.d.ts +29 -0
  22. package/dist/split/chunks/filterRegistry.js +2 -0
  23. package/dist/split/chunks/filterRegistry.js.map +1 -0
  24. package/dist/split/chunks/getAllPropertyDescriptors.js +2 -0
  25. package/dist/split/chunks/getAllPropertyDescriptors.js.map +1 -0
  26. package/dist/split/chunks/lifecycleHooks.js +2 -0
  27. package/dist/split/chunks/lifecycleHooks.js.map +1 -0
  28. package/dist/split/chunks/mount.js +2 -0
  29. package/dist/split/chunks/mount.js.map +1 -0
  30. package/dist/split/chunks/pathDiagnostics.js +2 -0
  31. package/dist/split/chunks/pathDiagnostics.js.map +1 -0
  32. package/dist/split/chunks/registerComponents.js +2 -0
  33. package/dist/split/chunks/registerComponents.js.map +1 -0
  34. package/dist/split/chunks/setAll.js +2 -0
  35. package/dist/split/chunks/setAll.js.map +1 -0
  36. package/dist/split/chunks/version.js +2 -0
  37. package/dist/split/chunks/version.js.map +1 -0
  38. package/dist/split/chunks/watchRuntime.js +2 -0
  39. package/dist/split/chunks/watchRuntime.js.map +1 -0
  40. package/dist/split/core.d.ts +1417 -0
  41. package/dist/split/core.js +2 -0
  42. package/dist/split/core.js.map +1 -0
  43. package/dist/split/features/devtools.d.ts +9 -0
  44. package/dist/split/features/devtools.js +2 -0
  45. package/dist/split/features/devtools.js.map +1 -0
  46. package/dist/split/features/diagnostics.d.ts +11 -0
  47. package/dist/split/features/diagnostics.js +2 -0
  48. package/dist/split/features/diagnostics.js.map +1 -0
  49. package/dist/split/features/formats.d.ts +10 -0
  50. package/dist/split/features/formats.js +2 -0
  51. package/dist/split/features/formats.js.map +1 -0
  52. package/dist/split/features/recursion.d.ts +9 -0
  53. package/dist/split/features/recursion.js +2 -0
  54. package/dist/split/features/recursion.js.map +1 -0
  55. package/dist/split/features/scopes.d.ts +10 -0
  56. package/dist/split/features/scopes.js +2 -0
  57. package/dist/split/features/scopes.js.map +1 -0
  58. package/dist/split/features/ssr.d.ts +9 -0
  59. package/dist/split/features/ssr.js +2 -0
  60. package/dist/split/features/ssr.js.map +1 -0
  61. package/dist/split/features/temporal.d.ts +9 -0
  62. package/dist/split/features/temporal.js +2 -0
  63. package/dist/split/features/temporal.js.map +1 -0
  64. package/package.json +13 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binder.js","sources":["../../../../../src/protocol/binder.ts","../../../../../src/mustache/convertMustacheToComments.ts","../../../../../src/structural/define.ts","../../../../../src/bindTextParser/parseFilterArgs.ts","../../../../../src/bindTextParser/parseFilters.ts","../../../../../src/bindTextParser/utils.ts","../../../../../src/bindTextParser/parsePropPart.ts","../../../../../src/bindTextParser/parseStatePart.ts","../../../../../src/bindTextParser/parseBindTextsForElement.ts","../../../../../src/bindings/parseCommentNode.ts","../../../../../src/bindTextParser/parseBindTextForEmbeddedNode.ts","../../../../../src/bindings/initializeBindingPromiseByNode.ts","../../../../../src/getCustomElement.ts","../../../../../src/platform/customElementRegistry.ts","../../../../../src/protocol/wcBindableReader.ts","../../../../../src/bindTextParser/expandSpread.ts","../../../../../src/structural/resolveNodePath.ts","../../../../../src/bindings/getBindingInfos.ts","../../../../../src/bindings/getBindingsByNode.ts","../../../../../src/bindings/lightDomComponentScope.ts","../../../../../src/bindings/getSubscriberNodes.ts","../../../../../src/bindings/collectNodesAndBindingInfos.ts","../../../../../src/list/loopContextByNode.ts","../../../../../src/list/lastListValueByAbsoluteStateAddress.ts","../../../../../src/list/stateListBaseline.ts","../../../../../src/proxy/symbols.ts","../../../../../src/address/AbsoluteStateAddress.ts","../../../../../src/address/TreePath.ts","../../../../../src/address/liftAddress.ts","../../../../../src/apply/rootNodeByFragment.ts","../../../../../src/address/calcWildcardLen.ts","../../../../../src/list/wildcardLevel.ts","../../../../../src/list/getListIndexByBindingInfo.ts","../../../../../src/binding/getAbsoluteStateAddressByBinding.ts","../../../../../src/binding/getBindingSetByAbsoluteStateAddress.ts","../../../../../src/address/StateAddress.ts","../../../../../src/binding/getStateAddressByBindingInfo.ts","../../../../../src/event/handlerBindingRegistry.ts","../../../../../src/event/checkboxHandler.ts","../../../../../src/event/captureHandlerRejection.ts","../../../../../src/token/Token.ts","../../../../../src/event/EventToken.ts","../../../../../src/event/eventTokenRegistry.ts","../../../../../src/event/eventTokenHandler.ts","../../../../../src/command/CommandToken.ts","../../../../../src/event/handler.ts","../../../../../src/event/radioHandler.ts","../../../../../src/event/isPossibleTwoWay.ts","../../../../../src/propagation/propagation.ts","../../../../../src/proxy/occurrenceWrite.ts","../../../../../src/event/twowayHandler.ts","../../../../../src/bindings/observerSkip.ts","../../../../../src/bindings/DefinitionCoordinator.ts","../../../../../src/bindings/initialSync.ts","../../../../../src/bindings/BindingSession.ts","../../../../../src/bindings/replaceToReplaceNode.ts","../../../../../src/core/componentApplyHooks.ts","../../../../../src/apply/getFilteredValue.ts","../../../../../src/apply/applyChangeToCheckbox.ts","../../../../../src/createEmptyArray.ts","../../../../../src/apply/applyChangeToCommand.ts","../../../../../src/bindings/bindingsByContent.ts","../../../../../src/bindings/indexBindingsByContent.ts","../../../../../src/polyfills.ts","../../../../../src/getUUID.ts","../../../../../src/list/createListIndex.ts","../../../../../src/list/listIndexesByList.ts","../../../../../src/cache/cacheEntryByAbsoluteStateAddress.ts","../../../../../src/protocol/transitionRunner.ts","../../../../../src/updater/updater.ts","../../../../../src/dependency/keyedDependency.ts","../../../../../src/list/createListDiff.ts","../../../../../src/list/stableListOrder.ts","../../../../../src/list/swapBaselineList.ts","../../../../../src/bindings/bindingSessionByContent.ts","../../../../../src/bindings/nodesByContent.ts","../../../../../src/bindings/bindLoopContextToContent.ts","../../../../../src/structural/planByContent.ts","../../../../../src/structural/activateContent.ts","../../../../../src/createEmptySet.ts","../../../../../src/structural/contentsByNode.ts","../../../../../src/bindings/planFilters.ts","../../../../../src/structural/createContent.ts","../../../../../src/bindings/initializeBindings.ts","../../../../../src/structural/rowPlan.ts","../../../../../src/apply/viewTransitionNaming.ts","../../../../../src/apply/applyChangeToFor.ts","../../../../../src/apply/applyChangeToIf.ts","../../../../../src/apply/ssrPropertyStore.ts","../../../../../src/trustedTypes.ts","../../../../../src/apply/applyChangeToProperty.ts","../../../../../src/event/getInputAttributeMirror.ts","../../../../../src/apply/applyChangeToText.ts","../../../../../src/apply/applyChangeToWebComponent.ts","../../../../../src/apply/getValue.ts","../../../../../src/list/getIndexValueByLoopContext.ts","../../../../../src/apply/scheduleDeferredApply.ts","../../../../../src/apply/applyChange.ts","../../../../../src/apply/applyChangeToClass.ts","../../../../../src/apply/applyChangeToAttribute.ts","../../../../../src/apply/applyChangeToStyle.ts","../../../../../src/apply/applyChangeToRadio.ts","../../../../../src/apply/applyChangeFromBindings.ts","../../../../../src/waitForStateInitialize.ts","../../../../../src/buildBindings.ts","../../../../../src/core/featureEntries.ts","../../../../../src/core/ssrHooks.ts","../../../../../src/stateElementByName.ts","../../../../../src/structural/fragmentInfoByUUID.ts","../../../../../src/bindings/getParseBindTextResults.ts","../../../../../src/structural/createNotFilter.ts","../../../../../src/structural/expandShorthandPaths.ts","../../../../../src/structural/getNodePath.ts","../../../../../src/structural/getFragmentNodeInfos.ts","../../../../../src/structural/optimizeFragment.ts","../../../../../src/structural/collectStructuralFragments.ts","../../../../../src/bindings/binder.ts"],"sourcesContent":["// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/binder.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// binder protocol — how a package that inserts DOM hands those nodes to whoever\n// owns data bindings on the page.\n//\n// The dual of transition-runner: that one hands a *mutation* to whoever animates\n// it, this one hands *new nodes* to whoever binds them.\n//\n// A `data-wcs` binding exists only for nodes @wcstack/state walked when it built\n// its bindings. Nodes that arrive later — the content of a route that was not\n// active at that moment, a <wcs-head> child reflected into <head> — were never\n// walked, so their bindings silently do nothing, however often they are inserted.\n// @wcstack/router must not depend on @wcstack/state (zero runtime dependencies,\n// independently publishable), so state installs a binder on a well-known global\n// symbol and inserters look it up lazily.\n//\n// No binder installed means nothing happens — byte-for-byte the behavior these\n// packages had before the protocol existed.\n//\n// docs/binder-protocol-design.md is the normative description.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/binder.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/binder.ts). Those copies are generated — do not edit them.\n\n/**\n * Global key the binder installs itself under. `Symbol.for` so independently\n * loaded copies of this file (two CDN bundles on one page) still agree.\n */\nexport const BINDER_KEY = Symbol.for(\"wcstack.binder\");\n\nexport interface IWcsBinder {\n readonly protocol: \"wcs-binder\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /**\n * Take a subtree that has just entered the document and bind whatever\n * declarations it carries.\n *\n * Contract (docs/binder-protocol-design.md §2):\n * - Synchronous. Initial values are applied before this returns, so the\n * caller never shows one frame of unbound markup.\n * - Idempotent. A subtree that is already bound is left alone, so a caller\n * may hand over the same nodes on every insertion without tracking which\n * ones are new.\n * - Binding survives later relocation, so this need not be called again when\n * the same nodes are moved (measured: design doc §8-3).\n * - Never throws for markup reasons; a subtree with no declarations is a\n * no-op.\n */\n bind(subtree: Node): void;\n}\n\n/**\n * The installed binder, or null when there is none or it speaks a version this\n * reader does not.\n *\n * Looked up on every call rather than cached, for the same reason\n * transition-runner does: the page's composition can change at any point, and a\n * stale cache would keep calling into a binder that is no longer there.\n */\nexport function getBinder(): IWcsBinder | null {\n const candidate = (globalThis as Record<symbol, unknown>)[BINDER_KEY] as IWcsBinder | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-binder\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.bind !== \"function\") return null;\n return candidate;\n}\n\n/**\n * Subtrees offered before a binder existed, and the set of everything a binder\n * has taken. Both live on global symbols so that independently loaded copies of\n * this file — the router's and state's — share one queue.\n *\n * The queue is needed because of load order: the router's auto bundle runs\n * before state's, so `<wcs-head>` reflects its children into `<head>` while\n * there is still nothing to bind them. Offering them to a binder that arrives\n * later is the difference between working and silently blank.\n */\nconst PENDING_KEY = Symbol.for(\"wcstack.binder.pending\");\nconst TAKEN_KEY = Symbol.for(\"wcstack.binder.taken\");\n\nfunction pendingQueue(): Node[] {\n const globals = globalThis as Record<symbol, unknown>;\n let queue = globals[PENDING_KEY] as Node[] | undefined;\n if (queue === undefined) {\n queue = [];\n globals[PENDING_KEY] = queue;\n }\n return queue;\n}\n\nfunction takenSet(): WeakSet<Node> {\n const globals = globalThis as Record<symbol, unknown>;\n let taken = globals[TAKEN_KEY] as WeakSet<Node> | undefined;\n if (taken === undefined) {\n taken = new WeakSet<Node>();\n globals[TAKEN_KEY] = taken;\n }\n return taken;\n}\n\n/**\n * Hand `subtree` to the installed binder, or hold it for one that arrives later.\n *\n * Returns whether a binder took it *now*. A `false` does not yet mean the markup\n * is doomed — check {@link wasBoundBy} once module scripts have run.\n */\nexport function bindSubtree(subtree: Node): boolean {\n const binder = getBinder();\n if (binder === null) {\n pendingQueue().push(subtree);\n return false;\n }\n takenSet().add(subtree);\n binder.bind(subtree);\n return true;\n}\n\n/** Whether any binder has taken this subtree. */\nexport function wasBoundBy(subtree: Node): boolean {\n return takenSet().has(subtree);\n}\n\n/**\n * Bind everything offered before this binder existed. Called by the binder right\n * after it installs itself.\n */\nexport function flushPendingBinds(): void {\n const binder = getBinder();\n if (binder === null) return;\n const queue = pendingQueue();\n if (queue.length === 0) return;\n const pending = queue.splice(0, queue.length);\n const taken = takenSet();\n for (const subtree of pending) {\n taken.add(subtree);\n binder.bind(subtree);\n }\n}\n","import { config } from \"../config.js\";\nimport { SVG_NAMESPACE } from \"../define.js\";\n\nconst MUSTACHE_REGEX = /\\{\\{\\s*(.+?)\\s*\\}\\}/g;\nconst SKIP_TAGS = new Set([\"SCRIPT\", \"STYLE\"]);\n\nexport function convertMustacheToComments(root: Document | Element | DocumentFragment): void {\n if (!config.enableMustache) {\n return;\n }\n\n convertTextNodes(root);\n\n const templates = Array.from(root.querySelectorAll(\"template\"));\n\n for (const template of templates) {\n if (template.namespaceURI === SVG_NAMESPACE) {\n const newTemplate = document.createElement(\"template\");\n const childNodes = Array.from(template.childNodes);\n for(let i = 0; i < childNodes.length; i++) {\n const childNode = childNodes[i];\n newTemplate.content.appendChild(childNode);\n }\n for(const attr of template.attributes) {\n newTemplate.setAttribute(attr.name, attr.value);\n }\n template.replaceWith(newTemplate);\n convertMustacheToComments(newTemplate.content);\n } else {\n convertMustacheToComments(template.content);\n }\n }\n}\n\nfunction convertTextNodes(root: Document | Element | DocumentFragment): void {\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT);\n const textNodes: Text[] = [];\n\n while (walker.nextNode()) {\n textNodes.push(walker.currentNode as Text);\n }\n\n for (const textNode of textNodes) {\n if (textNode.parentElement && SKIP_TAGS.has(textNode.parentElement.tagName)) {\n continue;\n }\n replaceTextNode(textNode);\n }\n}\n\nfunction replaceTextNode(textNode: Text): void {\n const text = textNode.data;\n MUSTACHE_REGEX.lastIndex = 0;\n\n if (!MUSTACHE_REGEX.test(text)) {\n return;\n }\n\n MUSTACHE_REGEX.lastIndex = 0;\n const fragment = document.createDocumentFragment();\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = MUSTACHE_REGEX.exec(text)) !== null) {\n if (match.index > lastIndex) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));\n }\n\n const bindText = match[1];\n fragment.appendChild(document.createComment(`@@: ${bindText}`));\n\n lastIndex = match.index + match[0].length;\n }\n\n if (lastIndex < text.length) {\n fragment.appendChild(document.createTextNode(text.slice(lastIndex)));\n }\n\n textNode.parentNode!.replaceChild(fragment, textNode);\n}\n","import { BindingType } from \"../types.js\";\n\nexport const STRUCTURAL_BINDING_TYPE_SET: Set<BindingType> = new Set([\n \"if\",\n \"elseif\",\n \"else\",\n \"for\",\n]);\n","/**\n * フィルタ引数リストのパース。`filter(a, b)` の `a, b` 部分を受け取る。\n *\n * トリムの規則は「**クォートの外側だけ**」。`fix( 2 )` のような書き癖を吸収するために\n * 素の引数は前後をトリムするが、クォートは「ここは literal」という宣言なので中身の\n * 空白は残す。両方まとめてトリムしていたため `pad(5, ' ')` が空文字パディング\n * (=無変化)に化けており、空白区切りの `join(' / ')` も指定できなかった。\n */\n\n/** 引数 1 つを確定する。クォート由来の文字が入った範囲より外側だけをトリムする。 */\nfunction finalizeArg(text: string, firstQuoteStart: number, lastQuoteEnd: number): string {\n // 先頭側: 最初のクォート文字より前だけが削れる(クォートが無ければ全体が対象)\n const startLimit = firstQuoteStart === -1 ? text.length : firstQuoteStart;\n let start = 0;\n while (start < startLimit && /\\s/.test(text[start])) {\n start++;\n }\n // 末尾側: 最後のクォート文字より後ろだけが削れる(クォートが無ければ全体が対象)\n const endLimit = lastQuoteEnd === -1 ? 0 : lastQuoteEnd;\n let end = text.length;\n while (end > endLimit && /\\s/.test(text[end - 1])) {\n end--;\n }\n return text.slice(start, end);\n}\n\nimport { LINT_HINT } from \"../errorGuidance\";\nimport { raiseError } from \"../raiseError\";\n\n/** 引用符の無い引数の型(要件 B9): true / false / null / 数値は型付き、それ以外は文字列 */\nconst NUMBER_LITERAL = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\nfunction toLiteral(text: string, quoted: boolean): unknown {\n if (quoted) return text;\n if (text === \"true\") return true;\n if (text === \"false\") return false;\n if (text === \"null\") return null;\n return NUMBER_LITERAL.test(text) ? Number(text) : text;\n}\n\nexport function parseFilterArgs(argsText: string): string[] {\n return parseFilterArgsWithLiterals(argsText).args;\n}\n\n/** 引数の原文と、その型付きの値(要件 B9)を一緒に返す。原文は引用符を外したもの */\nexport function parseFilterArgsWithLiterals(argsText: string): { args: string[]; literals: unknown[] } {\n const args: string[] = [];\n const literals: unknown[] = [];\n let current = '';\n let inQuote: string | null = null;\n let hasQuote = false;\n let firstQuoteStart = -1;\n let lastQuoteEnd = -1;\n\n const flush = (): void => {\n const arg = finalizeArg(current, firstQuoteStart, lastQuoteEnd);\n args.push(arg);\n literals.push(toLiteral(arg, hasQuote));\n current = '';\n hasQuote = false;\n firstQuoteStart = -1;\n lastQuoteEnd = -1;\n };\n\n for (let i = 0; i < argsText.length; i++) {\n const char = argsText[i];\n\n if (inQuote) {\n if (char === inQuote) {\n inQuote = null;\n } else {\n if (firstQuoteStart === -1) {\n firstQuoteStart = current.length;\n }\n current += char;\n lastQuoteEnd = current.length;\n }\n } else if (char === '\"' || char === \"'\") {\n inQuote = char;\n hasQuote = true;\n } else if (char === ',') {\n flush();\n } else {\n current += char;\n }\n }\n\n if (inQuote !== null) {\n // 閉じていない引用符は受理しない(要件 B2)。以前は黙って閉じたことにしていた\n raiseError(`[wcs/binding-syntax] unterminated ${inQuote} quote in the filter arguments \"(${argsText})\". Close the quote.${LINT_HINT}`);\n }\n const last = finalizeArg(current, firstQuoteStart, lastQuoteEnd);\n if (last || hasQuote) {\n args.push(last);\n literals.push(toLiteral(last, hasQuote));\n }\n\n return { args, literals };\n}\n","import { clearFilterResolutionCache } from \"../core/filterRegistry\";\nimport { LINT_HINT } from \"../errorGuidance\";\nimport { FilterIOType } from \"../filters/types\";\nimport { raiseError } from \"../raiseError\";\nimport { IParsedFilter } from \"../types\";\nimport { parseFilterArgsWithLiterals } from \"./parseFilterArgs\";\n\n/** tooling 専用(parser.ts の clearParserCaches からのみ呼ぶ)。 */\nexport function clearFilterFnCacheForTooling(): void {\n clearFilterResolutionCache();\n}\n\n// format: filterName(arg1,arg2) or filterName\n\n/**\n * 文法の段(要件 D16): 名前と引数だけを読む。**実関数は引かない** — 束縛計画の段で\n * 登録簿から解決する(`core/filterRegistry.ts`・`bindings/getBindingInfos.ts`)。\n * 未知のフィルタもここでは落とさない: パーサだけを使う tooling は実装を持たないので、\n * 「知らない名前」を解析の段で判定できない。\n */\nexport function parseFilters(filterTextList: string[], _filterIOType: FilterIOType): IParsedFilter[] {\n return filterTextList.map((filterText) => {\n const openParenIndex = filterText.indexOf('(');\n const closeParenIndex = filterText.lastIndexOf(')');\n // check parentheses\n if (openParenIndex !== -1 && closeParenIndex === -1) {\n raiseError(`Invalid filter format: missing closing parenthesis in \"${filterText}\"`);\n }\n if (closeParenIndex !== -1 && openParenIndex === -1) {\n raiseError(`Invalid filter format: missing opening parenthesis in \"${filterText}\"`);\n }\n const filterName = (openParenIndex === -1 ? filterText : filterText.substring(0, openParenIndex)).trim();\n if (filterName.length === 0) {\n // 空のフィルタ(`x|`・`x||y`・`x|(1)`)は文法の誤り。解析の段で名指しで落とす — 未知の\n // フィルタとは別物で、実関数の解決(束縛計画の段)まで持ち越すと tooling の解析が素通りする\n raiseError(`[wcs/binding-syntax] an empty filter in \"${filterTextList.join(\"|\")}\" — remove the extra \"|\" or name the filter.${LINT_HINT}`);\n }\n if (openParenIndex === -1) {\n // no arguments\n return { filterName, args: [], literals: [] };\n }\n const argsText = filterText.substring(openParenIndex + 1, closeParenIndex);\n return { filterName, ...parseFilterArgsWithLiterals(argsText) };\n });\n}\n","export const trimFn = (s: string): string => s.trim();\n\nconst isQuote = (c: string): boolean => c === \"'\" || c === '\"';\n\n/**\n * `text` の中で、引用符(`'` / `\"`)の外にある最初の `char` の位置。無ければ -1(要件 B1)。\n * 閉じていない引用符はそのまま末尾まで続く扱い — 不正な引用符はフィルタ引数の段で名指しで落ちる。\n */\nexport function indexOfOutsideQuotes(text: string, char: string): number {\n let quote: string | null = null;\n for (let i = 0; i < text.length; i++) {\n const c = text[i];\n if (quote !== null) {\n if (c === quote) quote = null;\n } else if (isQuote(c)) {\n quote = c;\n } else if (c === char) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * `separator` で区切る。ただし引用符の中は区切らない(要件 B1): `join(';')` や `join('|')` の\n * 区切り文字は引数であって、バインディングやフィルタの区切りではない。\n */\nexport function splitOutsideQuotes(text: string, separator: string): string[] {\n const parts: string[] = [];\n let quote: string | null = null;\n let start = 0;\n for (let i = 0; i < text.length; i++) {\n const c = text[i];\n if (quote !== null) {\n if (c === quote) quote = null;\n } else if (isQuote(c)) {\n quote = c;\n } else if (c === separator) {\n parts.push(text.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(text.slice(start));\n return parts;\n}\n","import { DELIMITER, FILTER_SEPARATOR, MODIFIER_SEPARATOR } from \"../define\";\nimport { LINT_HINT } from \"../errorGuidance\";\nimport { raiseError } from \"../raiseError\";\nimport { IParsedBinding, IParsedFilter } from \"../types\";\nimport { parseFilters } from \"./parseFilters\";\nimport { indexOfOutsideQuotes, splitOutsideQuotes, trimFn } from \"./utils\";\n\n// 解析の段の形(フィルタは名前と引数だけ — 実関数は束縛計画の段で引く。要件 D16)\ntype PropPartParseResult = Pick<IParsedBinding, 'propName' | 'propSegments' | 'propModifiers' | 'inFilters'>;\n\nconst cacheFilterInfos = new Map<string, IParsedFilter[]>();\n\n/** tooling 専用(parser.ts の clearParserCaches からのみ呼ぶ)。 */\nexport function clearPropPartCacheForTooling(): void {\n cacheFilterInfos.clear();\n}\n\n// format: propName#moodifier1,modifier2\n// propName-format: path.to.property (e.g., textContent, style.color, not include :)\n// special path: \n// 'attr.attributeName' for attributes (e.g., attr.href, attr.data-id)\n// 'style.propertyName' for style properties (e.g., style.backgroundColor, style.fontSize)\n// 'class.className' for class names (e.g., class.active, class.hidden)\n// 'onclick', 'onchange' etc. for event listeners\n\nexport function parsePropPart(propPart: string): PropPartParseResult {\n const pos = indexOfOutsideQuotes(propPart, FILTER_SEPARATOR);\n let propText: string = '';\n let filterTexts: string[] = [];\n let filtersText = '';\n let filters: IParsedFilter[] = [];\n if (pos !== -1) {\n propText = propPart.slice(0, pos).trim();\n filtersText = propPart.slice(pos + 1).trim();\n if (cacheFilterInfos.has(filtersText)) {\n filters = cacheFilterInfos.get(filtersText)!;\n } else {\n filterTexts = splitOutsideQuotes(filtersText, FILTER_SEPARATOR).map(trimFn);\n filters = parseFilters(filterTexts, \"input\");\n cacheFilterInfos.set(filtersText, filters);\n }\n } else {\n propText = propPart.trim();\n }\n\n const modifierParts = propText.split(MODIFIER_SEPARATOR).map(trimFn);\n if (modifierParts.length > 2) {\n // 修飾子の並びは 1 つだけ(要件 B2)。`value#ro#wo` は以前 `ro` だけを残して黙って捨てていた\n raiseError(`[wcs/binding-syntax] \"${propText}\": a binding takes one modifier list after a single \"${MODIFIER_SEPARATOR}\" — write \"${modifierParts[0]}${MODIFIER_SEPARATOR}${modifierParts.slice(1).join(\",\")}\".${LINT_HINT}`);\n }\n const [propName, propModifiersText] = modifierParts;\n const propSegments = propName.split(DELIMITER).map(trimFn);\n const propModifiers = propModifiersText\n ? propModifiersText.split(',').map(trimFn)\n : [];\n return {\n propName,\n propSegments,\n propModifiers,\n inFilters: filters,\n };\n}","import { getPathInfo } from \"../address/PathInfo\";\nimport { raiseError } from \"../raiseError\";\nimport { FILTER_SEPARATOR } from \"../define\";\nimport { IParsedBinding, IParsedFilter } from \"../types\";\nimport { parseFilters } from \"./parseFilters\";\nimport { indexOfOutsideQuotes, splitOutsideQuotes, trimFn } from \"./utils\";\n\n// 解析の段の形(フィルタは名前と引数だけ — 実関数は束縛計画の段で引く。要件 D16)\ntype StatePartParseResult = Pick<IParsedBinding,\n 'statePathName' | 'statePathInfo' | 'outFilters'>;\n\nconst cacheFilterInfos = new Map<string, IParsedFilter[]>();\n\n/** tooling 専用(parser.ts の clearParserCaches からのみ呼ぶ)。 */\nexport function clearStatePartCacheForTooling(): void {\n cacheFilterInfos.clear();\n}\n\n// format: statePath|filter|filter\n// statePath-format: path.to.property (e.g., user.name.first, users.*.name, users.0.name, not include @)\n// filters-format: filterName or filterName(arg1,arg2)\nexport function parseStatePart(statePart: string): StatePartParseResult {\n // 引用符の中の `|` はフィルタの区切りではない(要件 B1 — `join('|')`)\n const pos = indexOfOutsideQuotes(statePart, FILTER_SEPARATOR);\n let stateAndPath: string = '';\n let filterTexts: string[] = [];\n let filtersText = '';\n let filters: IParsedFilter[] = [];\n if (pos !== -1) {\n stateAndPath = statePart.slice(0, pos).trim();\n filtersText = statePart.slice(pos + 1).trim();\n if (cacheFilterInfos.has(filtersText)) {\n filters = cacheFilterInfos.get(filtersText)!;\n } else {\n filterTexts = splitOutsideQuotes(filtersText, FILTER_SEPARATOR).map(trimFn);\n filters = parseFilters(filterTexts, \"output\");\n cacheFilterInfos.set(filtersText, filters);\n }\n } else {\n stateAndPath = statePart.trim();\n }\n if (stateAndPath.indexOf(\"@\") !== -1) {\n // 名前次元は v2 で撤去(docs/state-mount-design.md D16 / §9)。パスは 1 本のツリー。\n raiseError(\n `\"${stateAndPath}\": the \"@name\" selector was removed in v2 — there is a single state tree. ` +\n `Mount the named state onto the tree (<wcs-state mount=\"...\">) and read it by its path prefix instead.`,\n );\n }\n const statePathName = stateAndPath;\n const pathInfo = getPathInfo(statePathName);\n return {\n statePathName,\n statePathInfo: pathInfo,\n outFilters: filters,\n };\n}\n","import { getPathInfo } from \"../address/PathInfo.js\";\nimport {\n BINDING_SEPARATOR,\n ELSE_KEYWORD,\n EVENT_PROP_PREFIX,\n FILTER_SEPARATOR,\n MODIFIER_SEPARATOR,\n EVENT_TOKEN_NAMESPACE,\n PROP_VALUE_SEPARATOR,\n SPREAD_PROP,\n} from \"../define.js\";\nimport { LINT_HINT } from \"../errorGuidance.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { STRUCTURAL_BINDING_TYPE_SET } from \"../structural/define.js\";\nimport { parsePropPart } from \"./parsePropPart.js\";\nimport { parseStatePart } from \"./parseStatePart.js\";\nimport { ParseBindTextResult } from \"./types.js\";\nimport { splitOutsideQuotes, trimFn } from \"./utils.js\";\n\n// format: propPart:statePart; propPart:statePart; ...\n// special-propPart:\n// if: statePart (single binding for conditional rendering)\n// else: (single binding for conditional rendering, and statePart is ignored)\n// elseif: statePart only (single binding for conditional rendering)\n// for: statePart only (single binding for loop rendering)\n// onclick: statePart, onchange: statePart etc. (event listeners)\n// ...: statePart (spread — expand wcBindable properties+inputs of target object)\n\n/** 左辺に修飾子も入力フィルタも取らない束縛(構造ディレクティブと spread)— 付いていれば拒否する(要件 B4) */\nconst KEYWORDS_WITHOUT_MODIFIERS = new Set<string>([ELSE_KEYWORD, 'if', 'elseif', 'for', SPREAD_PROP]);\n\n/**\n * `data-wcs` の値をバインディングごとに区切る(前後の空白は残す — tooling が位置を数えられるように)。\n * 引用符の中の `;` は区切りではない(要件 B1 — `join(';')`)。ランタイムと tooling(`@wcstack/state/parser`)で共有する\n */\nexport function splitBindTexts(bindText: string): string[] {\n return splitOutsideQuotes(bindText, BINDING_SEPARATOR);\n}\n\nexport function parseBindTextsForElement(bindText: string): ParseBindTextResult[] {\n const [ ...bindTexts ] = splitBindTexts(bindText).map(trimFn).filter(s => s.length > 0);\n const results = bindTexts.map((bindText): ParseBindTextResult => {\n const separatorIndex = bindText.indexOf(PROP_VALUE_SEPARATOR);\n if (separatorIndex === -1) {\n raiseError(`Invalid bindText: \"${bindText}\". Missing ':' separator between propPart and statePart.`);\n }\n const propPart = bindText.slice(0, separatorIndex).trim();\n const statePart = bindText.slice(separatorIndex + 1).trim();\n // 種別は修飾子・入力フィルタより前の名前で決める(要件 B4)。以前は左辺全体との完全一致で\n // 判定していたので、`radio#ro:` が汎用プロパティに落ちていた\n const keyword = propPart.split(MODIFIER_SEPARATOR)[0].split(FILTER_SEPARATOR)[0].trim();\n if (keyword !== propPart && KEYWORDS_WITHOUT_MODIFIERS.has(keyword)) {\n raiseError(`[wcs/binding-syntax] \"${bindText}\": \"${keyword}\" takes no modifiers or filters on its left side — write \"${keyword}:\".${LINT_HINT}`);\n }\n if (propPart === ELSE_KEYWORD) {\n if (statePart.length > 0) {\n // else は値を取らない(要件 B2)。以前は右辺を黙って捨てていた\n raiseError(`[wcs/binding-syntax] \"${bindText}\": \"else\" takes no value — write \"else:\".${LINT_HINT}`);\n }\n const pathInfo = getPathInfo('#else');\n return {\n propName: ELSE_KEYWORD,\n propSegments: [ELSE_KEYWORD],\n propModifiers: [],\n statePathName: '#else',\n statePathInfo: pathInfo,\n inFilters: [],\n outFilters: [],\n bindingType: 'else',\n };\n } else if (propPart === SPREAD_PROP) {\n const stateResult = parseStatePart(statePart);\n if (stateResult.outFilters.length > 0) {\n raiseError(`Invalid spread binding \"${bindText}\": filters are not allowed on spread targets.`);\n }\n if (stateResult.statePathName.length === 0) {\n raiseError(`Invalid spread binding \"${bindText}\": spread target path is required.`);\n }\n return {\n propName: SPREAD_PROP,\n propSegments: [SPREAD_PROP],\n propModifiers: [],\n inFilters: [],\n ...stateResult,\n bindingType: 'spread',\n };\n } else if (propPart === 'if'\n || propPart === 'elseif'\n || propPart === 'for'\n ) {\n const stateResult = parseStatePart(statePart);\n return {\n propName: propPart,\n propSegments: [propPart],\n propModifiers: [],\n inFilters: [],\n ...stateResult,\n bindingType: propPart,\n };\n } else if (keyword === 'radio' || keyword === 'checkbox') {\n // 修飾子(`#ro`・`#onchange` …)と入力フィルタは radio / checkbox のハンドラが読む(要件 B4)\n const stateResult = parseStatePart(statePart);\n const propResult = parsePropPart(propPart);\n return {\n ...propResult,\n ...stateResult,\n bindingType: keyword,\n };\n } else {\n const stateResult = parseStatePart(statePart);\n const propResult = parsePropPart(propPart);\n // eventToken.<prop>: <name> は要素 dispatch を state へ流す pub/sub 配線。\n // 値適用ではないため bindingType 'event' として listener attach 経路に乗せる。\n if (propResult.propSegments[0] === EVENT_TOKEN_NAMESPACE) {\n return {\n ...propResult,\n ...stateResult,\n bindingType: 'event',\n };\n }\n if (propResult.propSegments[0].startsWith(EVENT_PROP_PREFIX)) {\n return {\n ...propResult,\n ...stateResult,\n bindingType: 'event',\n };\n } else {\n return {\n ...propResult,\n ...stateResult,\n bindingType: 'prop',\n };\n }\n }\n });\n // check for sigle binding for 'if', 'elseif', 'else', 'for'\n if (results.length > 1) {\n const isIncludeSingleBinding = results.some(r => STRUCTURAL_BINDING_TYPE_SET.has(r.bindingType));\n if (isIncludeSingleBinding) {\n // lint 側の単独バインディング検査(bindingValidator の structuralMustBeSingle)が\n // 同じケースを検出するため誘導を付ける(三面同語彙)。\n raiseError(`[wcs/template-syntax] Invalid bindText: \"${bindText}\". 'if', 'elseif', 'else', and 'for' bindings must be single binding. Put the structural binding alone in its own data-wcs (e.g. <template data-wcs=\"for: items\">).${LINT_HINT}`);\n }\n }\n return results;\n}\n\n","import { config } from \"../config\";\n\nconst bindTextByNode = new WeakMap<Node, string>();\n\n// format: <!--@@wcs-text:path-->\n// bind-stateはconfig.commentTextPrefixで変更可能\n// format: <!--@@wcs-for:UUID-->\n// bind-stateはconfig.commentForPrefixで変更可能\n// format: <!--@@wcs-if:UUID-->\n// bind-stateはconfig.commentIfPrefixで変更可能\n// format: <!--@@wcs-else:UUID-->\n// bind-stateはconfig.commentElsePrefixで変更可能\n// format: <!--@@wcs-elseif:UUID-->\n// bind-stateはconfig.commentElseIfPrefixで変更可能\nconst bindingTypeKeywordSet: Set<string> = new Set<string>([\n config.commentTextPrefix,\n config.commentForPrefix,\n config.commentIfPrefix,\n config.commentElseIfPrefix,\n config.commentElsePrefix,\n]);\n\n// format: <!--@@:path-->は<!--@@wcs-text:path-->と同義にする\nconst EMBEDDED_REGEX = /*#__PURE__*/ new RegExp(`^\\\\s*@@\\\\s*(.*?)\\\\s*:\\\\s*(.+?)\\\\s*$`);\n\nexport function parseCommentNode(node: Node): string | null {\n const savedText = bindTextByNode.get(node);\n if (typeof savedText === \"string\") {\n return savedText;\n }\n if (node.nodeType !== Node.COMMENT_NODE) {\n return null;\n }\n const commentNode = node as Comment;\n const text = commentNode.data.trim();\n const match = EMBEDDED_REGEX.exec(text);\n if (match === null) {\n return null;\n }\n // 空の場合は wcs-text として扱う\n const keyword = match[1] || config.commentTextPrefix;\n if (!bindingTypeKeywordSet.has(keyword)) {\n return null;\n }\n bindTextByNode.set(node, match[2]);\n return match[2];\n}\n\nexport function getCommentNodeBindText(node: Node): string | null {\n return bindTextByNode.get(node) || null;\n}","import { parseStatePart } from \"./parseStatePart.js\";\nimport { ParseBindTextResult } from \"./types.js\";\n\nexport function parseBindTextForEmbeddedNode(bindText: string): ParseBindTextResult {\n const stateResult = parseStatePart(bindText);\n return {\n propName: 'textContent',\n propSegments: ['textContent'],\n propModifiers: [],\n inFilters: [],\n ...stateResult,\n bindingType: 'text',\n }\n}","import { IInitializeBindingPromise } from \"./types\";\n\nconst bindingPromiseByNode = new WeakMap<Node, IInitializeBindingPromise>();\n// resolve 済みマーク。エントリ未生成のまま resolve されたノードは、後から\n// wait された時に「生成して即 resolve」で追いつく。\nconst resolvedNodes = new WeakSet<Node>();\n\nlet id = 0;\n\nexport function getInitializeBindingPromiseByNode(node: Node): IInitializeBindingPromise {\n let bindingPromise = bindingPromiseByNode.get(node) || null;\n if (bindingPromise !== null) {\n return bindingPromise;\n }\n let resolveFn = undefined;\n const promise = new Promise<void>((resolve) => {\n resolveFn = resolve;\n });\n bindingPromise = {\n id: ++id,\n promise,\n resolve: resolveFn!\n };\n bindingPromiseByNode.set(node, bindingPromise);\n if (resolvedNodes.has(node)) {\n bindingPromise.resolve();\n }\n return bindingPromise;\n}\n\nexport async function waitInitializeBinding(node: Node): Promise<void> {\n const bindingPromise = getInitializeBindingPromiseByNode(node);\n await bindingPromise.promise;\n}\n\nexport function resolveInitializedBinding(node: Node): void {\n // ホットパス: リスト行では全 subscriber ノードがここを通るが、await する消費者\n // (boundComponent / shadowRoot host)はほぼ居ない。既存エントリが無ければ\n // Promise+closure を生成せず resolve 済みマークだけ残す(15 万個級の割り当て削減)。\n const existing = bindingPromiseByNode.get(node);\n if (typeof existing !== \"undefined\") {\n existing.resolve();\n return;\n }\n resolvedNodes.add(node);\n}\n","\nconst cache = new WeakMap<Node, string | null>();\n\nexport function getCustomElement(node: Node): string | null {\n const cached = cache.get(node);\n if (cached !== undefined) {\n return cached;\n }\n let value: string | null = null;\n try {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return value;\n }\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n if (tagName.includes(\"-\")) {\n return value = tagName;\n }\n if (element.hasAttribute(\"is\")) {\n const is = element.getAttribute(\"is\")!;\n if (is.includes(\"-\")) {\n return value = is;\n }\n }\n return value;\n } finally {\n cache.set(node, value);\n }\n}\n","export interface ICustomElementRegistryAdapter {\n get(name: string): CustomElementConstructor | undefined;\n whenDefined(name: string): Promise<CustomElementConstructor>;\n upgrade?(root: Node): void;\n define?(name: string, constructor: CustomElementConstructor): void;\n}\n\nexport interface ICustomElementRegistryOwner {\n /**\n * Scoped registry hook, as exposed by `Element` / `Document` / `ShadowRoot`.\n * `undefined` on platforms without scoped custom element registries; `null`\n * when the node deliberately carries a null registry (a declarative shadow\n * root with `shadowrootcustomelementregistry`, or a document from\n * `createHTMLDocument()`) and has not been handed to `registry.initialize()`.\n */\n readonly customElementRegistry?: unknown;\n /** Legacy owner form: a `Window`-like object carrying a registry. */\n readonly customElements?: unknown;\n}\n\nfunction toAdapter(registry: unknown): ICustomElementRegistryAdapter | null {\n if (typeof registry !== \"object\" || registry === null) return null;\n\n const candidate = registry as Partial<ICustomElementRegistryAdapter>;\n if (typeof candidate.get !== \"function\" || typeof candidate.whenDefined !== \"function\") {\n return null;\n }\n return candidate as ICustomElementRegistryAdapter;\n}\n\n/**\n * Resolve the registry that governs `owner` at operation time, so importing the\n * runtime stays safe when browser globals are absent.\n *\n * Pass the node the operation is about (the bound element, its shadow root):\n * with scoped custom element registries the same tag name can resolve to a\n * different constructor per tree, so \"is this tag defined?\" is only meaningful\n * relative to a node. Nodes on platforms without scoped registries report\n * `undefined` and fall back to the global registry, which keeps every existing\n * caller on today's behaviour.\n */\nexport function getCustomElementRegistry(\n owner: ICustomElementRegistryOwner | Node | null = null,\n): ICustomElementRegistryAdapter | null {\n if (owner !== null && typeof owner !== \"undefined\") {\n const { customElementRegistry: scoped, customElements: owned } =\n owner as ICustomElementRegistryOwner;\n // A node in a null-registry subtree resolves to no registry at all. Falling\n // back to the global one would report globally-defined tags as usable and\n // let us write own properties onto elements that are still un-upgraded --\n // exactly the accessor shadowing the deferred-apply path exists to avoid.\n if (scoped === null) return null;\n if (typeof scoped !== \"undefined\") return toAdapter(scoped);\n if (typeof owned !== \"undefined\") return toAdapter(owned);\n }\n return toAdapter((globalThis as { readonly customElements?: unknown }).customElements);\n}\n\nexport function upgradeCustomElement(\n registry: ICustomElementRegistryAdapter,\n root: Node,\n): void {\n registry.upgrade?.(root);\n}\n","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/wc-bindable-reader.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\nimport type {\n IWcBindable,\n IWcBindableCommand,\n IWcBindableInput,\n IWcBindableProperty,\n} from \"./wcBindable.js\";\n\nexport const MIN_WC_BINDABLE_VERSION = 1;\n\nexport interface WcBindableElement {\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions,\n ): void;\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions,\n ): void;\n readonly constructor: {\n readonly wcBindable: IWcBindable;\n };\n}\n\nexport interface ReadBindableResult {\n readonly target: WcBindableElement;\n readonly liveDeclaration: IWcBindable;\n readonly knownProperties: ReadonlyMap<string, IWcBindableProperty>;\n readonly declaredInputs: ReadonlyMap<string, IWcBindableInput>;\n readonly declaredCommands: ReadonlyMap<string, IWcBindableCommand>;\n}\n\n/**\n * Repository-local conformance mirror of @wc-bindable/core's\n * getWcBindableDeclaration(). Discovery has one path only:\n * target.constructor.wcBindable.\n *\n * The declaration remains live. The maps are read-time indexes and are not a\n * clone, freeze, or normalized replacement for liveDeclaration.\n */\nexport function readBindableDeclaration(target: unknown): ReadBindableResult | null {\n try {\n if (target === null || (typeof target !== \"object\" && typeof target !== \"function\")) {\n return null;\n }\n\n const candidate = target as {\n readonly addEventListener?: unknown;\n readonly removeEventListener?: unknown;\n readonly constructor?: { readonly wcBindable?: IWcBindable };\n };\n const addEventListener = candidate.addEventListener;\n const removeEventListener = candidate.removeEventListener;\n const declaration = candidate.constructor?.wcBindable;\n\n if (typeof addEventListener !== \"function\" || typeof removeEventListener !== \"function\") {\n return null;\n }\n if (declaration?.protocol !== \"wc-bindable\") return null;\n if (!Number.isInteger(declaration.version) || declaration.version < MIN_WC_BINDABLE_VERSION) {\n return null;\n }\n\n const knownProperties = readNamedList(declaration.properties, isValidPropertyDescriptor);\n if (knownProperties === null) return null;\n\n const declaredInputs = declaration.inputs === undefined\n ? new Map<string, IWcBindableInput>()\n : readNamedList(declaration.inputs, isValidInputDescriptor);\n if (declaredInputs === null) return null;\n\n const declaredCommands = declaration.commands === undefined\n ? new Map<string, IWcBindableCommand>()\n : readNamedList(declaration.commands, isValidCommandDescriptor);\n if (declaredCommands === null) return null;\n\n return {\n target: target as WcBindableElement,\n liveDeclaration: declaration,\n knownProperties,\n declaredInputs,\n declaredCommands,\n };\n } catch {\n return null;\n }\n}\n\nfunction isValidPropertyDescriptor(value: unknown): value is IWcBindableProperty {\n if (typeof value !== \"object\" || value === null) return false;\n const descriptor = value as Partial<IWcBindableProperty>;\n if (typeof descriptor.name !== \"string\" || descriptor.name.length === 0) return false;\n if (typeof descriptor.event !== \"string\" || descriptor.event.length === 0) return false;\n return descriptor.getter === undefined || typeof descriptor.getter === \"function\";\n}\n\nfunction isValidInputDescriptor(value: unknown): value is IWcBindableInput {\n if (typeof value !== \"object\" || value === null) return false;\n const descriptor = value as Partial<IWcBindableInput>;\n if (typeof descriptor.name !== \"string\" || descriptor.name.length === 0) return false;\n return descriptor.attribute === undefined || typeof descriptor.attribute === \"string\";\n}\n\nfunction isValidCommandDescriptor(value: unknown): value is IWcBindableCommand {\n if (typeof value !== \"object\" || value === null) return false;\n const descriptor = value as Partial<IWcBindableCommand>;\n if (typeof descriptor.name !== \"string\" || descriptor.name.length === 0) return false;\n return descriptor.async === undefined || typeof descriptor.async === \"boolean\";\n}\n\nfunction readNamedList<T extends { readonly name: string }>(\n value: unknown,\n isValidEntry: (entry: unknown) => entry is T,\n): ReadonlyMap<string, T> | null {\n if (!Array.isArray(value)) return null;\n const entries = new Map<string, T>();\n for (const entry of value) {\n if (!isValidEntry(entry) || entries.has(entry.name)) return null;\n entries.set(entry.name, entry);\n }\n return entries;\n}\n","import { getPathInfo } from \"../address/PathInfo\";\nimport { config } from \"../config\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry, upgradeCustomElement } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration } from \"../protocol/wcBindableReader\";\nimport { raiseError } from \"../raiseError\";\nimport { ParseBindTextResult } from \"./types\";\n\nfunction makeExpandedEntry(\n name: string,\n base: string,\n): ParseBindTextResult {\n // Dot-relative spread keeps the loop item root (`.`) without producing `..foo`.\n const expandedPath = base === \".\" ? `.${name}` : `${base}.${name}`;\n return {\n propName: name,\n propSegments: [name],\n propModifiers: [],\n statePathName: expandedPath,\n statePathInfo: getPathInfo(expandedPath),\n inFilters: [],\n outFilters: [],\n bindingType: 'prop',\n };\n}\n\nfunction dedupKey(r: ParseBindTextResult): string | null {\n switch (r.bindingType) {\n case 'prop':\n case 'event':\n case 'radio':\n case 'checkbox':\n return `${r.bindingType}::${r.propName}`;\n case 'spread':\n return null;\n default:\n return null;\n }\n}\n\nexport interface IExpandSpreadOptions {\n /**\n * When false, raise an error if the custom element class is not yet defined.\n * When true (default), leave the spread entry in place so the caller can\n * defer expansion via customElements.whenDefined.\n */\n readonly allowDeferred?: boolean;\n}\n\n/**\n * Expand spread bind-text entries (`...: target`) into per-prop entries\n * by enumerating wcBindable.properties + inputs of the element's class.\n *\n * Behavior:\n * - With `allowDeferred: true` (default): if class is not yet defined, the\n * spread entry stays so the caller can wait via customElements.whenDefined.\n * - With `allowDeferred: false`: raises if class is not defined.\n * - Duplicate propName: last-wins (explicit binding overrides spread).\n * - When config.debug, console.debug logs each override.\n * - Mid-`*` in target path is allowed (e.g. `...: stores.*.fetch`).\n *\n * Composite Profile (COMPOSITE.md / SPEC-extensions § 4) support:\n * - A composite shell exposes its synthesized declaration via the standard\n * `target.constructor.wcBindable` surface (§ 1 Discovery), so this function\n * handles it without any composite-specific code path.\n * - Composed property names use the `<sourceId>.<sourceName>` pattern\n * (e.g. \"s3.progress\"); we keep the dotted name as a single segment so\n * element member access stays flat (element[\"s3.progress\"], not nested).\n * - The expanded state path becomes `targetBase.s3.progress`, which resolves\n * as nested state access — author state as `{ s3: { progress: 0 } }` to\n * mirror the composed structure.\n * - Tier claim (Symbol.for(\"wc-bindable.composite.tiers\")) is not read here;\n * spread covers observation (T1) and writable inputs (T2) transparently\n * through normal property assignment, and commands stay out of spread by\n * design regardless of tier.\n */\nexport function expandSpread(\n node: Node,\n results: ParseBindTextResult[],\n options: IExpandSpreadOptions = {},\n): ParseBindTextResult[] {\n const allowDeferred = options.allowDeferred ?? true;\n if (!results.some(r => r.bindingType === 'spread')) {\n return results;\n }\n const expanded: ParseBindTextResult[] = [];\n const spreadOrigin = new WeakSet<ParseBindTextResult>();\n for (const result of results) {\n if (result.bindingType !== 'spread') {\n expanded.push(result);\n continue;\n }\n if (node.nodeType !== Node.ELEMENT_NODE) {\n raiseError(`Spread binding requires an element node.`);\n }\n const element = node as Element;\n const tagName = getCustomElement(element);\n if (tagName === null) {\n raiseError(`Spread binding \"${result.statePathName}\" requires a custom element with wcBindable, but <${element.tagName.toLowerCase()}> is not a custom element.`);\n }\n const registry = getCustomElementRegistry(element);\n if (registry === null) {\n raiseError(`CustomElementRegistry is unavailable for <${tagName}>.`);\n }\n const customClass = registry.get(tagName);\n if (typeof customClass === \"undefined\") {\n if (!allowDeferred) {\n raiseError(`Spread binding \"${result.statePathName}\" requires <${tagName}> to be registered. Define the custom element before initializing this binding.`);\n }\n // Deferred: keep spread entry intact; caller retries via whenDefined.\n expanded.push(result);\n continue;\n }\n upgradeCustomElement(registry, element);\n const bindable = readBindableDeclaration(element);\n if (bindable === null) {\n raiseError(`Spread binding \"${result.statePathName}\" requires <${tagName}> to expose a valid wcBindable declaration.`);\n }\n const targetBase = result.statePathName;\n const seen = new Set<string>();\n for (const name of bindable.knownProperties.keys()) {\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = makeExpandedEntry(name, targetBase);\n spreadOrigin.add(entry);\n expanded.push(entry);\n }\n // properties win over inputs when the name overlaps because they carry the\n // full property contract (for example change events).\n for (const name of bindable.declaredInputs.keys()) {\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = makeExpandedEntry(name, targetBase);\n spreadOrigin.add(entry);\n expanded.push(entry);\n }\n }\n // Last-wins de-duplication\n const lastIndexByKey = new Map<string, number>();\n for (let i = 0; i < expanded.length; i++) {\n const key = dedupKey(expanded[i]);\n if (key !== null) {\n lastIndexByKey.set(key, i);\n }\n }\n const final: ParseBindTextResult[] = [];\n for (let i = 0; i < expanded.length; i++) {\n const key = dedupKey(expanded[i]);\n if (key === null) {\n final.push(expanded[i]);\n continue;\n }\n if (lastIndexByKey.get(key) === i) {\n final.push(expanded[i]);\n } else if (config.debug && spreadOrigin.has(expanded[i])) {\n const overrider = expanded[lastIndexByKey.get(key)!];\n const tagText = node.nodeType === Node.ELEMENT_NODE\n ? `<${(node as Element).tagName.toLowerCase()}>`\n : 'node';\n console.debug(`[@wcstack/state] spread: prop \"${expanded[i].propName}\" of ${tagText} overridden by explicit binding (statePath: \"${overrider.statePathName}\").`);\n }\n }\n return final;\n}\n\nexport function hasUnresolvedSpread(results: ParseBindTextResult[]): boolean {\n return results.some(r => r.bindingType === 'spread');\n}\n","export function resolveNodePath(root: Node, path: number[]): Node | null {\n let currentNode: Node | null = root;\n // childNodes[i] ではなく兄弟ポインタで辿る。複製したばかりの行では、childNodes に触れた\n // ノードごとに NodeList(と NodeRareData)が作られ、行の寿命のあいだ残る。行テンプレートの\n // 子は数個なので、辿る歩数は添字の分だけで済む(設計 R5)。\n for (let i = 0; i < path.length; i++) {\n let remaining = path[i];\n currentNode = currentNode.firstChild;\n while (currentNode !== null && remaining > 0) {\n currentNode = currentNode.nextSibling;\n remaining--;\n }\n if (currentNode === null) break;\n }\n return currentNode;\n}\n","import { IBindingInfo, IFilterInfo, IParsedFilter } from \"../types\";\nimport { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { resolveFilterFn } from \"../core/filterRegistry\";\nimport { FilterIOType } from \"../filters/types\";\n\n/**\n * 束縛計画の段でフィルタの実関数を引く(要件 D16)。解析の段は名前と引数しか持たないので、\n * 未知のフィルタが名指しで落ちるのはここ — ページの構築時であって、最初の更新の最中ではない。\n * 解決済みの答えは登録簿が名前・引数・入出力ごとに 1 つ持つ(`core/filterRegistry.ts`)。\n */\nfunction planFilters(filters: IParsedFilter[], filterIOType: FilterIOType): IFilterInfo[] {\n if (filters.length === 0) {\n return filters as IFilterInfo[];\n }\n const planned: IFilterInfo[] = [];\n for (let i = 0; i < filters.length; i++) {\n const filter = filters[i];\n planned.push({\n filterName: filter.filterName,\n args: filter.args,\n filterFn: resolveFilterFn(filter.filterName, filter.args, filterIOType, filter.literals ?? filter.args),\n });\n }\n return planned;\n}\n\nexport function getBindingInfos(node: Node, parseBindingTextResults: ParseBindTextResult[]): IBindingInfo[] {\n const bindingInfos: IBindingInfo[] = [];\n for (const parseBindingTextResult of parseBindingTextResults) {\n const inFilters = planFilters(parseBindingTextResult.inFilters, \"input\");\n const outFilters = planFilters(parseBindingTextResult.outFilters, \"output\");\n if (parseBindingTextResult.bindingType !== 'text') {\n bindingInfos.push({\n ...parseBindingTextResult,\n inFilters,\n outFilters,\n node: node,\n replaceNode: node,\n });\n } else {\n // フラグメント登録時に事前正規化済みの Text ノードはそのまま replaceNode に\n // 使う(node === replaceNode なら replaceToReplaceNode は no-op)。\n // 実 DOM 上の wcs-text コメント(非フラグメント経路)は従来どおり\n // 空 Text を生成して実行時に差し替える。\n const replaceNode = node.nodeType === Node.TEXT_NODE\n ? node\n : document.createTextNode('');\n bindingInfos.push({\n ...parseBindingTextResult,\n inFilters,\n outFilters,\n node: node,\n replaceNode: replaceNode,\n });\n }\n }\n return bindingInfos;\n}\n","import { IBindingInfo } from \"../binding/types\";\n\nconst bindingsByNode = new WeakMap<Node, IBindingInfo[]>();\n\nexport function getBindingsByNode(node: Node): IBindingInfo[] | null {\n return bindingsByNode.get(node) || null;\n}\n\nexport function setBindingsByNode(node: Node, bindings: IBindingInfo[]): void {\n bindingsByNode.set(node, bindings);\n}\n\nexport function addBindingByNode(node: Node, binding: IBindingInfo): void {\n const bindings = getBindingsByNode(node);\n if (bindings === null) {\n setBindingsByNode(node, [binding]);\n } else {\n bindings.push(binding);\n }\n}","/**\n * bindings/lightDomComponentScope.ts — Light DOM の mapped `bind-component` を\n * 「ホストとは別のバインディングスコープ」として扱うための判定\n * (docs/architecture-hardening/15-state-component-mechanism-consistency.md §1.13)。\n *\n * Shadow DOM 形では、コンポーネントの `<wcs-state>` が**別 rootNode** にいることで\n * 2 つのことが同時に成立している。\n *\n * 1. ホスト root の `waitForStateInitialize` の走査集合に入らない\n * 2. 子スコープのバインディングがホストとは別の `buildBindings` パスで処理される\n *\n * Light DOM では両方が失われる。1 が失われると、\n * 「ホストの `waitForStateInitialize` が子 state を待つ →\n * 子 state は自分を束ねるホスト binding を待つ →\n * その binding を作る `initializeBindings` は `waitForStateInitialize` の後」\n * という循環になり、初期化が永久に解決しない。2 が失われると、子スコープの\n * `@name` 参照がホストと同じパスで解決されてしまい、子 state の名前登録より\n * 先に評価される。\n *\n * このモジュールはその 2 つを明示的に復元するための判定だけを持つ。\n *\n * **plain(ホストからバインドしない state 注入)の Light DOM は v2 で廃止**\n *(State._initializeBindWebComponent が raise する — 共有 rootNode に独立ツリーを\n * 置けないため。shadow を付ければ plain Shadow 形として従来どおり動く)。\n * ここの判定が「ホストからバインドされているか」を見るのはその名残ではなく、\n * マウント(配線あり)だけをスコープとして切り出すため。\n */\n\nimport { config } from \"../config\";\n\n/** `<wcs-state bind-component>` が Light DOM の mapped 形(=別スコープ扱い)か。 */\nexport function isLightDomMappedStateElement(stateElement: Element): boolean {\n if (!stateElement.hasAttribute(\"bind-component\")) {\n return false;\n }\n const parentNode = stateElement.parentNode;\n // Shadow DOM 形では parentNode が ShadowRoot になる(かつホスト root の\n // querySelectorAll にはそもそも出てこない)\n if (!(parentNode instanceof Element)) {\n return false;\n }\n // ホストからバインドされていなければ plain。従来どおりの扱いに任せる\n return parentNode.hasAttribute(config.bindAttributeName);\n}\n\n/**\n * `root` の内側にある Light DOM mapped コンポーネント要素を集める。\n *\n * `root` 自身は**含めない**。子スコープが自分のパスとして\n * `initializeBindings(componentElement)` を呼ぶとき、その要素自身まで prune すると\n * 何も初期化されなくなるため。\n */\nexport function findNestedLightDomComponents(root: Document | Element | DocumentFragment): Element[] {\n const components: Element[] = [];\n const stateElements = root.querySelectorAll(`${config.tagNames.state}[bind-component]`);\n for (const stateElement of stateElements) {\n if (!isLightDomMappedStateElement(stateElement)) {\n continue;\n }\n const component = stateElement.parentNode as Element;\n if (component === (root as unknown as Element)) {\n continue;\n }\n components.push(component);\n }\n return components;\n}\n\n/** `node` が、いずれかのコンポーネント要素の**真の**子孫か。 */\nexport function isInsideAnyComponent(node: Node, components: Element[]): boolean {\n for (let i = 0; i < components.length; i++) {\n const component = components[i];\n if (component !== node && component.contains(node)) {\n return true;\n }\n }\n return false;\n}\n","import { config } from \"../config\";\nimport { findNestedLightDomComponents, isInsideAnyComponent } from \"./lightDomComponentScope\";\nimport { parseCommentNode } from \"./parseCommentNode\";\n\n/**\n * data-wcs 属性または埋め込みノード<!--{{}}-->を持つノードをすべて取得する\n *\n * Light DOM の mapped コンポーネントの**内側**は除外する(§1.13)。そのサブツリーの\n * `@name` 参照は、コンポーネント側の state が名前登録を済ませてからでないと解決できず、\n * ホストと同じパスで拾うと登録前に評価されてしまう。除外したぶんは、その state が\n * 初期化を終えた時点で自分のスコープとして `initializeBindings(componentElement)` を\n * 呼び直す(Shadow DOM 形で rootNode ごとにパスが分かれるのと同じ形にする)。\n *\n * コンポーネント要素**自身**は除外しない。ホスト側の `data-wcs`(`state.msg: user.name`)\n * はホストのスコープに属し、それが張られることで子側の待ちが解ける。\n *\n * @param root\n * @returns\n */\n\nexport function getSubscriberNodes(root: Document | Element | DocumentFragment): Node[] {\n const subscriberNodes: Node[] = [];\n const nestedComponents = findNestedLightDomComponents(root);\n const walker = document.createTreeWalker(\n root, \n NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, \n {\n acceptNode(node: Node) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n const hasBinding = element.hasAttribute(config.bindAttributeName);\n return hasBinding\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP;\n } else {\n // Comment node\n return parseCommentNode(node) !== null\n ? NodeFilter.FILTER_ACCEPT \n : NodeFilter.FILTER_SKIP;\n }\n }\n }\n );\n \n while (walker.nextNode()) {\n const node = walker.currentNode;\n // TreeWalker の acceptNode は「自分は拾うが子孫は辿らない」を表現できないため、\n // コンポーネント要素自身を拾ったうえで、その子孫をここで落とす。\n // nestedComponents が空(=圧倒的多数)のときは contains 走査ごと発生しない。\n if (nestedComponents.length > 0 && isInsideAnyComponent(node, nestedComponents)) {\n continue;\n }\n subscriberNodes.push(node);\n }\n return subscriberNodes;\n}","import { expandSpread, hasUnresolvedSpread } from \"../bindTextParser/expandSpread\";\nimport { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { raiseError } from \"../raiseError\";\nimport { resolveNodePath } from \"../structural/resolveNodePath\";\nimport { IFragmentNodeInfo } from \"../structural/types\";\nimport { IBindingInfo } from \"../types\";\nimport { getBindingInfos } from \"./getBindingInfos\";\nimport { setBindingsByNode } from \"./getBindingsByNode\";\nimport { getParseBindTextResults } from \"./getParseBindTextResults\";\nimport { getSubscriberNodes } from \"./getSubscriberNodes\";\nimport { resolveInitializedBinding } from \"./initializeBindingPromiseByNode\";\n\nconst registeredNodeSet = new WeakSet<Node>();\n\n/**\n * パース結果の変換フック(Phase 2 のマウント — impl-plan §3-0 の 1)。\n * マウントされたスコープの収集は、これで各パース結果を親ツリーの絶対パスへ書き換える。\n * `uuid` を持つエントリ(構造フラグメントの参照)には掛けない — フラグメント側の\n * パース結果は登録時(collectStructuralFragments)に変換済みで、二重に掛けると\n * 接頭辞が二重になる。\n */\nexport type ParseResultTransform = (parsed: ParseBindTextResult, forPath?: string) => ParseBindTextResult;\n\nfunction applyTransform(\n parseResults: ParseBindTextResult[],\n transform: ParseResultTransform | undefined,\n): ParseBindTextResult[] {\n if (typeof transform === \"undefined\") {\n return parseResults;\n }\n return parseResults.map((parsed) => (parsed.uuid != null ? parsed : transform(parsed)));\n}\n\nexport interface IDeferredSpreadEntry {\n readonly node: Node;\n readonly tagName: string;\n readonly parseResults: ParseBindTextResult[];\n readonly transform?: ParseResultTransform;\n}\n\nfunction processParseResultsForNode(\n node: Node,\n parseResults: ParseBindTextResult[],\n options: { allowDeferred: boolean },\n transform?: ParseResultTransform,\n): { bindings: IBindingInfo[], deferred: IDeferredSpreadEntry | null } {\n const expanded = expandSpread(node, parseResults, { allowDeferred: options.allowDeferred });\n if (hasUnresolvedSpread(expanded)) {\n const tagName = node.nodeType === Node.ELEMENT_NODE\n ? getCustomElement(node as Element)\n : null;\n if (tagName === null) {\n raiseError(`Spread binding deferred but element is not a custom element.`);\n }\n return { bindings: [], deferred: { node, tagName, parseResults, transform } };\n }\n registeredNodeSet.add(node);\n // 変換は spread 展開の**後**(展開されたプロパティごとのパスに掛かる)\n const bindings = getBindingInfos(node, applyTransform(expanded, transform));\n setBindingsByNode(node, bindings);\n resolveInitializedBinding(node);\n return { bindings, deferred: null };\n}\n\nexport function collectNodesAndBindingInfos(\n root: Document | Element | DocumentFragment,\n transform?: ParseResultTransform,\n): [ Node[], IBindingInfo[], IDeferredSpreadEntry[] ] {\n const subscriberNodes = getSubscriberNodes(root);\n const allBindings: IBindingInfo[] = [];\n const deferredSpreads: IDeferredSpreadEntry[] = [];\n for(const node of subscriberNodes) {\n if (registeredNodeSet.has(node)) continue;\n const parseResults = getParseBindTextResults(node);\n const result = processParseResultsForNode(node, parseResults, { allowDeferred: true }, transform);\n if (result.deferred !== null) {\n deferredSpreads.push(result.deferred);\n continue;\n }\n allBindings.push(...result.bindings);\n }\n return [subscriberNodes, allBindings, deferredSpreads];\n}\n\nexport function collectNodesAndBindingInfosByFragment(\n root: DocumentFragment,\n nodeInfos: IFragmentNodeInfo[],\n): [ Node[], IBindingInfo[] ] {\n const nodes: Node[] = [];\n const allBindings: IBindingInfo[] = [];\n for(const nodeInfo of nodeInfos) {\n const node = resolveNodePath(root, nodeInfo.nodePath);\n if (node === null) {\n raiseError(`Node not found by path [${nodeInfo.nodePath.join(', ')}] in fragment.`);\n }\n if (registeredNodeSet.has(node)) continue;\n const result = processParseResultsForNode(node, nodeInfo.parseBindTextResults, { allowDeferred: false });\n // deferred is impossible when allowDeferred=false (expandSpread raises instead)\n allBindings.push(...result.bindings);\n nodes.push(node);\n }\n return [nodes, allBindings];\n}\n\nexport function unregisterNode(node: Node): void {\n registeredNodeSet.delete(node);\n}\n\n/**\n * RowPlan 経路(createContent のプラン実体化)用。パース・spread 展開を経ずに\n * binding を組み立てた subscriber ノードを二重処理防止台帳へ載せる\n * (後続の collectNodesAndBindingInfos による再スキャンから保護)。\n */\nexport function markNodeRegistered(node: Node): void {\n registeredNodeSet.add(node);\n}\n\n/**\n * Re-process a deferred spread entry once the custom element class is\n * registered. Expands the captured parseResults, installs bindings, and\n * returns them so the caller can attach handlers and apply state values.\n */\nexport function processDeferredNode(entry: IDeferredSpreadEntry): IBindingInfo[] {\n const { node, parseResults, transform } = entry;\n unregisterNode(node);\n const result = processParseResultsForNode(node, parseResults, { allowDeferred: false }, transform);\n return result.bindings;\n}\n","import { ILoopContext } from \"./types\";\n\nconst loopContextByNode = new WeakMap<Node, ILoopContext>();\n\n// 親を持たない ShadowRoot で探索を続けるか。マウントされたスコープ根はホストへ抜ける\n// (webComponent/mount.ts が記録の登録時に注入する)。未注入なら従来どおり境界で止まる —\n// 走るのは探索が ShadowRoot に達した 1 回だけなので、大域の受け口でも hot path には載らない\nlet mountedScopeHost: ((root: ShadowRoot) => Node | null) | null = null;\n\nexport function setMountedScopeHost(resolver: (root: ShadowRoot) => Node | null): void {\n mountedScopeHost = resolver;\n}\n\nexport function getLoopContextByNode(node: Node): ILoopContext | null {\n let paramNode: Node | null = node;\n while (paramNode) {\n const loopContext = loopContextByNode.get(paramNode);\n if (loopContext) {\n return loopContext;\n }\n let next: Node | null = paramNode.parentNode;\n if (next === null && mountedScopeHost !== null && paramNode instanceof ShadowRoot) {\n // マウントされた ShadowRoot はホストのループ文脈を継承する(impl-plan §3-0 の 3)。\n // ホスト行の listIndex [i] が子スコープの `for` の親になり、内側の行は [i, j] を\n // 作る — 絶対パスのワイルドカード数 = listIndex 段数(設計書 §4-4)がこれで成立し、\n // v1 の crossBoundaryAddress / baseListIndex(Δ の帳簿)は要らなくなる。\n // マウントされていない ShadowRoot(plain コンポーネント・通常の Shadow ツリー)は\n // 従来どおり境界で止まる(resolver が null を返す)。\n next = mountedScopeHost(paramNode);\n }\n paramNode = next;\n }\n return null;\n}\n\nexport function setLoopContextByNode(node: Node, loopContext: ILoopContext | null): void {\n if (loopContext === null) {\n loopContextByNode.delete(node);\n return;\n }\n loopContextByNode.set(node, loopContext);\n}\n","import { IAbsoluteStateAddress } from \"../address/types\";\n\nconst lastListValueByAbsoluteStateAddress: WeakMap<IAbsoluteStateAddress, readonly unknown[]> = new WeakMap();\n\nexport function getLastListValueByAbsoluteStateAddress(address: IAbsoluteStateAddress): readonly unknown[] {\n return lastListValueByAbsoluteStateAddress.get(address) ?? [];\n}\n\nexport function setLastListValueByAbsoluteStateAddress(address: IAbsoluteStateAddress, value: readonly unknown[]): void {\n lastListValueByAbsoluteStateAddress.set(address, value);\n}\n\nexport function clearLastListValueByAbsoluteStateAddress(address: IAbsoluteStateAddress): void {\n lastListValueByAbsoluteStateAddress.delete(address);\n}\n\nexport function hasLastListValueByAbsoluteStateAddress(address: IAbsoluteStateAddress): boolean {\n return lastListValueByAbsoluteStateAddress.has(address);\n}\n","/**\n * list/stateListBaseline.ts\n *\n * state 側のリスト差分基準 — 「最後に **state 側が観測した** リスト値」。\n *\n * 描画側の基準([lastListValueByAbsoluteStateAddress](./lastListValueByAbsoluteStateAddress.ts))\n * とは別の問いに答える台帳である。あちらは「最後に**描画した**値」で、`applyChangeToFor` が\n * 「画面に対して何を足し引きするか」を決めるために使う。こちらは読み(`$getAll`)と\n * 依存ウォーク(`walkDependency`)が「**前回見た形からどう変わったか**」を決めるために使う。\n *\n * 統合してはならない。ウォークが描画側の基準を進めると、その後の `applyChangeToFor` が\n * 空の差分を見て描画を落とす。逆に描画側の基準だけに頼ると、`for` バインドの無いリストでは\n * 基準が永久に空のままになり、`createListDiff` の「旧リストが空」分岐が新しい配列に\n * **新しい ListIndex を鋳造**する。子リストの台帳は旧親 ListIndex を指したまま残るので\n * 親子の連鎖が切れ、集計が恒久的に stale になるか `ListIndexes not found` で恒久的に\n * throw する(docs/state-recursive-path-impl-plan.md §3-2 の E1)。\n *\n * 書き手は 4 系統ある。いずれも「観測した」という同じ意味を持つ。\n * - 読み: `collectWildcardIndexes`(`commitDiffBaseline: true` のときだけ。固定 arity の\n * `$setAll` は走査を借りるだけで動かさない — docs/state-set-all-design.md §6-2)\n * - 再帰の走査: `recursion/walk.ts`(合併形の `$getAll` と**再帰の `$setAll` の両方**が確定する。\n * cold な書き込みが ListIndex 世代を鋳造したまま基準を残すと、次の構造変更で深い子台帳が\n * 孤児になるため — docs/state-recursive-path-impl-plan.md §6)\n * - 描画: `applyChangeFromBindings` / `hydrateBindings`(描画側の基準と同時に書く)\n * - 依存ウォーク: `walkDependency`(ウォーク完了後にまとめて確定する)\n *\n * キーは **絶対アドレス**。`IStateAddress` は listIndex が null のとき pathInfo だけで\n * intern されるため、同じパス形状のルートリストを持つ 2 つの state 要素がエントリを\n * 共有してしまう(`createStateAddress` の `_cacheNullListIndex`)。\n */\nimport { IAbsoluteStateAddress } from \"../address/types\";\n\nconst stateListBaselineByAbsoluteStateAddress: WeakMap<IAbsoluteStateAddress, readonly unknown[]> = new WeakMap();\n/**\n * 更新バッチ中の観測は**即座に確定しない**。バッチ内で同じリストへ 2 回構造書き込みすると、\n * 2 回目のウォークが「一度も描画されず直後に上書きされる中間値」を基準に diff を取り、\n * 中間値が落とした行の ListIndex が鋳造し直されて子リストの台帳が恒久的に切れるため。\n *\n * バッチが開いている間の観測はここに溜め、バッチ末尾(updater の drain 終了)でまとめて\n * 確定する。こうするとバッチ内のどのウォークも「バッチ開始時の値」と diff を取り、\n * これは描画側(applyChangeToFor が描画基準で取る diff)と一致する。\n *\n * 深さで数えるのは、drain の最中に $updatedCallback などが書いて新しいバッチが\n * 始まる形があるため。0 に戻ったバッチだけが確定する。\n */\nlet pendingBaselines: Map<IAbsoluteStateAddress, readonly unknown[]> | null = null;\nlet batchDepth = 0;\n\nexport function getStateListBaseline(address: IAbsoluteStateAddress): readonly unknown[] {\n // pending は意図的に見ない。バッチ中の読み手には「バッチ開始時の値」を返す。\n return stateListBaselineByAbsoluteStateAddress.get(address) ?? [];\n}\n\nexport function setStateListBaseline(address: IAbsoluteStateAddress, value: readonly unknown[]): void {\n if (pendingBaselines !== null) {\n pendingBaselines.set(address, value);\n return;\n }\n stateListBaselineByAbsoluteStateAddress.set(address, value);\n}\n\n/** 更新バッチの開始(updater が最初の enqueue で呼ぶ)。 */\nexport function beginStateListBaselineBatch(): void {\n batchDepth++;\n if (pendingBaselines === null) {\n pendingBaselines = new Map<IAbsoluteStateAddress, readonly unknown[]>();\n }\n}\n\n/** 更新バッチの終了(updater が drain の finally で呼ぶ)。入れ子が全部閉じたら確定する。 */\nexport function endStateListBaselineBatch(): void {\n if (batchDepth === 0) {\n // enqueue を経ない直接 drain(testApplyChange)。開いていないバッチは閉じない。\n return;\n }\n batchDepth--;\n if (batchDepth > 0 || pendingBaselines === null) {\n return;\n }\n for (const [address, value] of pendingBaselines) {\n stateListBaselineByAbsoluteStateAddress.set(address, value);\n }\n pendingBaselines = null;\n}\n\n/** 台帳から 1 件落とす(描画側の clearLastListValueByAbsoluteStateAddress と対にしておく)。 */\nexport function clearStateListBaseline(address: IAbsoluteStateAddress): void {\n pendingBaselines?.delete(address);\n stateListBaselineByAbsoluteStateAddress.delete(address);\n}\n\nexport function hasStateListBaseline(address: IAbsoluteStateAddress): boolean {\n return (pendingBaselines?.has(address) ?? false)\n || stateListBaselineByAbsoluteStateAddress.has(address);\n}\n","\nexport const setLoopContextSymbol: unique symbol = Symbol(\"$$setLoopContext\");\nexport const getByAddressSymbol: unique symbol = Symbol(\"$$getByAddress\");\nexport const hasByAddressSymbol: unique symbol = Symbol(\"$$hasByAddress\");\nexport const setByAddressSymbol: unique symbol = Symbol(\"$$setByAddress\");\nexport const connectedCallbackSymbol: unique symbol = Symbol(\"$$connectedCallback\");\nexport const disconnectedCallbackSymbol: unique symbol = Symbol(\"$$disconnectedCallback\");\nexport const updatedCallbackSymbol: unique symbol = Symbol(\"$$updatedCallback\");\nexport const errorCallbackSymbol: unique symbol = Symbol(\"$$errorCallback\");\n","import { IListIndex } from \"../list/types\";\nimport { ITreePath, IAbsoluteStateAddress } from \"./types\";\n\nconst _cache: WeakMap<IListIndex, WeakMap<ITreePath, IAbsoluteStateAddress>> = new WeakMap();\nconst _cacheNullListIndex: WeakMap<ITreePath, IAbsoluteStateAddress> = new WeakMap();\n\nclass AbsoluteStateAddress implements IAbsoluteStateAddress {\n readonly absolutePathInfo: ITreePath;\n readonly listIndex: IListIndex | null;\n\n constructor(absolutePathInfo: ITreePath, listIndex: IListIndex | null) {\n this.absolutePathInfo = absolutePathInfo;\n this.listIndex = listIndex;\n }\n}\n\nexport function createAbsoluteStateAddress(absolutePathInfo: ITreePath, listIndex: IListIndex | null): IAbsoluteStateAddress {\n if (listIndex === null) {\n let cached = _cacheNullListIndex.get(absolutePathInfo);\n if (typeof cached !== \"undefined\") {\n return cached;\n }\n cached = new AbsoluteStateAddress(absolutePathInfo, null);\n _cacheNullListIndex.set(absolutePathInfo, cached);\n return cached;\n } else {\n let cacheByAbsolutePathInfo = _cache.get(listIndex);\n if (typeof cacheByAbsolutePathInfo === \"undefined\") {\n cacheByAbsolutePathInfo = new WeakMap<ITreePath, IAbsoluteStateAddress>();\n _cache.set(listIndex, cacheByAbsolutePathInfo);\n }\n let cached = cacheByAbsolutePathInfo.get(absolutePathInfo);\n if (typeof cached !== \"undefined\") {\n return cached;\n }\n cached = new AbsoluteStateAddress(absolutePathInfo, listIndex);\n cacheByAbsolutePathInfo.set(absolutePathInfo, cached);\n return cached;\n }\n}\n","import { IStateElement } from \"../components/types\";\nimport { ITreePath, IPathInfo } from \"./types\";\n\n/**\n * ツリー(`<wcs-state>` 要素)に固定したパス。絶対アドレスの intern の中間ノードであり、\n * 行バインディングのパターン台帳のキーでもある(docs/state-row-instantiation-redesign.md §3-3)。\n *\n * 表は「要素を弱キーにした WeakMap → PathInfo をキーにした Map」の 2 段。PathInfo はページの\n * 寿命だけ生きる(強参照の Map に載っている)ので内側は WeakMap である必要が無く、Map のほうが\n * 引きが速い。各段は get 1 回と undefined 比較で引く — has してから get する形は同じ表を\n * 2 回引いていた。読みのベンチ(e2e/bench/plain-read.mjs)では、キャッシュを引く読みが\n * getter で約 1ns、行の getter で 3〜5ns 速くなり、この関数を通らない素のパスの読みは変わらない\n * (docs/spikes/state-address-intern-placement/README.md の main-tp)。\n *\n * ノードへの強参照経路は要素の WeakMap エントリ(ephemeron)だけなので、要素が DOM から外れれば\n * ノードごと回収される(e2e/tests/state-address-gc.spec.ts)。\n */\nconst treePathsByElement: WeakMap<IStateElement, Map<IPathInfo, ITreePath>> = new WeakMap();\n\nexport function getTreePath(stateElement: IStateElement, pathInfo: IPathInfo): ITreePath {\n let table = treePathsByElement.get(stateElement);\n if (table === undefined) {\n table = new Map();\n treePathsByElement.set(stateElement, table);\n }\n let treePath = table.get(pathInfo);\n if (treePath === undefined) {\n treePath = Object.freeze(new TreePath(stateElement, pathInfo));\n table.set(pathInfo, treePath);\n }\n return treePath;\n}\n\nclass TreePath implements ITreePath {\n readonly pathInfo: IPathInfo;\n readonly stateElement: IStateElement;\n constructor(stateElement: IStateElement, pathInfo: IPathInfo) {\n this.pathInfo = pathInfo;\n this.stateElement = stateElement;\n }\n}\n","import { IStateElement } from \"../components/types\";\nimport { IListIndex } from \"../list/types\";\nimport { createAbsoluteStateAddress } from \"./AbsoluteStateAddress\";\nimport { getTreePath } from \"./TreePath\";\nimport { IAbsoluteStateAddress, IPathInfo, IStateAddress } from \"./types\";\n\n/**\n * ツリー非依存のアドレスを、`stateElement`(どのツリーか)まで確定した絶対アドレスへ持ち上げる。\n *\n * 恒久台帳(cache / bindings / baseline / updater の queue)はモジュール単一でツリーをまたぐので、\n * キーは必ずこちらを使う — `IStateAddress` をそのままキーにすると、同じパス形状や同じ配列を持つ\n * 2 つの `<wcs-state>` が混線する(__tests__/addressLedgerKeyGuard.test.ts が番人)。\n *\n * 持ち上げは選択の余地が無い決定的な変換で、以前は各呼び出し元が 2 行で手書きしていた。\n * ここに集めて、intern の関数(getTreePath / createAbsoluteStateAddress)を src/address/ の外から\n * 直接呼ばせない(__tests__/addressImportBoundary.test.ts が番人)。2 本の型を 1 本に畳む統合\n * (docs/state-address-unification-design.md)は、素のパスの読みを退行させることが実測で分かり、\n * 閉じた(同 §12)— この持ち上げは残る。\n */\nexport function liftAddress(stateElement: IStateElement, address: IStateAddress): IAbsoluteStateAddress {\n return createAbsoluteStateAddress(getTreePath(stateElement, address.pathInfo), address.listIndex);\n}\n\n/** `IStateAddress` を経ずに、構成要素から直接絶対アドレスを作る。 */\nexport function absoluteAddressOf(\n stateElement: IStateElement,\n pathInfo: IPathInfo,\n listIndex: IListIndex | null,\n): IAbsoluteStateAddress {\n return createAbsoluteStateAddress(getTreePath(stateElement, pathInfo), listIndex);\n}\n","\nconst rootNodeByFragment: WeakMap<DocumentFragment, Node> = new WeakMap();\n\nexport function setRootNodeByFragment(fragment: DocumentFragment, rootNode: Node | null): void {\n if (rootNode === null) {\n rootNodeByFragment.delete(fragment);\n } else {\n rootNodeByFragment.set(fragment, rootNode);\n }\n}\n\nexport function getRootNodeByFragment(fragment: DocumentFragment): Node | null {\n return rootNodeByFragment.get(fragment) || null;\n}\n","import { IPathInfo } from \"./types.js\";\n\nconst cacheCalcWildcardLen: Map<string, number> = new Map(); \n\nexport function calcWildcardLen(pathInfo: IPathInfo, targetPathInfo: IPathInfo): number {\n let path1: IPathInfo;\n let path2: IPathInfo;\n if (pathInfo.wildcardCount === 0 || targetPathInfo.wildcardCount === 0) {\n return 0;\n }\n if (pathInfo.wildcardCount === 1 \n && targetPathInfo.wildcardCount > 0 \n && targetPathInfo.wildcardPathSet.has(pathInfo.path)) {\n return 1;\n }\n if (pathInfo.id < targetPathInfo.id) {\n path1 = pathInfo;\n path2 = targetPathInfo;\n } else {\n path1 = targetPathInfo;\n path2 = pathInfo;\n }\n const key = `${path1.path}\\t${path2.path}`;\n let len = cacheCalcWildcardLen.get(key);\n if (typeof len !== \"undefined\") {\n return len;\n }\n const matchPath = path1.wildcardPathSet.intersection(path2.wildcardPathSet);\n len = matchPath.size;\n cacheCalcWildcardLen.set(key, len);\n return len;\n}\n\n","/**\n * list/wildcardLevel.ts\n *\n * 「パス上のワイルドカード位置」→「listIndex チェーン上の段」の変換を 1 箇所に集める。\n *\n * チェーンの長さは常に `Δ + W`(W = そのパスの wildcardCount、Δ = そのスコープの\n * base 深さ)である。通常の state スコープは Δ=0 なので「位置 i = 段 i」で済んでいたが、\n * `bind-component` の子スコープがホストの `for` の内側にいる場合は Δ>0 になる\n * (docs/state-bind-component-nested-for-design.md)。\n *\n * そこで**先頭ではなく末尾を基準に数える**。`IListIndex.at()` は負値を受けるので:\n *\n * at(i) → at(i - W) // listIndexes[(Δ+W) + (i-W)] = listIndexes[Δ+i]\n *\n * Δ=0 のときは両者が同じ要素を指すため、この書き換えは既存スコープに対して\n * 意味論を変えない。Δ の値を呼び出し側へ配管する必要も無い。\n */\n\nimport { IListIndex } from \"./types\";\n\n/**\n * ワイルドカード位置 `wildcardPos`(先頭から 0 始まり)に対応する listIndex を返す。\n * `wildcardCount` は `wildcardPos` が属するパスのワイルドカード総数。\n *\n * 範囲外(`wildcardPos >= wildcardCount`)は null。Δ=0 では `at(pos)` が\n * チェーン長を超えて null を返していたのと同じ結果になる。**このガードは必須**で、\n * 落とすと「1 段ループの中で `$2` を読む」が黙って `$1` を返す\n * (末尾起点では `at(1-1)=at(0)` に化けるため)。\n */\nexport function listIndexAtWildcard(\n listIndex: IListIndex,\n wildcardPos: number,\n wildcardCount: number,\n): IListIndex | null {\n if (wildcardPos < 0 || wildcardPos >= wildcardCount) {\n return null;\n }\n return listIndex.at(wildcardPos - wildcardCount);\n}\n\n/**\n * ユーザーランドへ渡すインデックス列。チェーンの先頭 Δ 段(base)を落とし、\n * **そのスコープ自身のループ分だけ**にする。\n *\n * コンポーネントの作者は、自分がリストの中に置かれるかどうかを知らずに書く。\n * `$1` や `onClick(event, index)` の意味が設置場所で変わってはいけないので、\n * Δ は境界の内側に閉じ込める。`$resolve(path, indexes)` は台帳の配列位置で\n * 引くため、ここで返した列がそのまま往復で使える。\n */\nexport function getScopedIndexes(listIndex: IListIndex, wildcardCount: number): number[] {\n // indexes は型上は必須だが、防御的フォールバックを既存挙動として持っている\n const indexes = listIndex.indexes ?? [];\n if (indexes.length === wildcardCount) {\n return indexes;\n }\n return indexes.slice(indexes.length - wildcardCount);\n}\n","import { calcWildcardLen } from \"../address/calcWildcardLen\";\nimport { IBindingInfo } from \"../types\";\nimport { getLoopContextByNode } from \"./loopContextByNode\";\nimport { IListIndex, ILoopContext } from \"./types\";\nimport { listIndexAtWildcard } from \"./wildcardLevel\";\n\nconst listIndexByBindingInfoByLoopContext: WeakMap<ILoopContext, WeakMap<IBindingInfo, IListIndex | null>> = new WeakMap();\n\nexport function getListIndexByBindingInfo(bindingInfo: IBindingInfo): IListIndex | null {\n const loopContext = getLoopContextByNode(bindingInfo.node);\n if (loopContext === null) {\n return null;\n }\n let listIndexByBindingInfo = listIndexByBindingInfoByLoopContext.get(loopContext);\n if (typeof listIndexByBindingInfo === \"undefined\") {\n listIndexByBindingInfo = new WeakMap<IBindingInfo, IListIndex | null>();\n listIndexByBindingInfoByLoopContext.set(loopContext, listIndexByBindingInfo);\n } else {\n const listIndex = listIndexByBindingInfo.get(bindingInfo);\n if (typeof listIndex !== \"undefined\") {\n return listIndex;\n }\n }\n\n let listIndex: IListIndex | null = null;\n try {\n const wildcardLen = calcWildcardLen(loopContext.pathInfo, bindingInfo.statePathInfo);\n if (wildcardLen > 0) {\n listIndex = listIndexAtWildcard(loopContext.listIndex, wildcardLen - 1, loopContext.pathInfo.wildcardCount);\n }\n return listIndex;\n } finally {\n listIndexByBindingInfo.set(bindingInfo, listIndex);\n }\n\n}\n","import { absoluteAddressOf } from \"../address/liftAddress\";\nimport { IAbsoluteStateAddress } from \"../address/types\";\nimport { getRootNodeByFragment } from \"../apply/rootNodeByFragment\";\nimport { getListIndexByBindingInfo } from \"../list/getListIndexByBindingInfo\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo } from \"./types\";\n\nconst absoluteStateAddressByBinding: WeakMap<IBindingInfo, IAbsoluteStateAddress> = new WeakMap();\n\n/**\n * binding の解決済み root を返す。knownRootNode があれば getRootNode() と\n * fragment フォールバックを省略する(リスト行活性化のホットパス)。\n */\nexport function resolveBindingRootNode(binding: IBindingInfo, knownRootNode?: Node | null): Node {\n if (knownRootNode != null) {\n return knownRootNode;\n }\n let rootNode: Node = binding.replaceNode.getRootNode() as Node;\n // binding.replaceNodeはisConnected=trueになっていることが前提、切断されている場合はraiseErrorを返す\n if (binding.replaceNode.isConnected === false) {\n // DocumentFragmentでバッファリングされている場合は、ルートノードをDocumentFragmentから実際のルートノードに切り替える\n const rootNodeByFragment = getRootNodeByFragment(rootNode as DocumentFragment);\n if (rootNodeByFragment === null) {\n raiseError(`Cannot get absolute state address for disconnected binding: ${binding.bindingType} ${binding.statePathName} on ${binding.node.nodeName}`);\n } else {\n rootNode = rootNodeByFragment;\n }\n }\n return rootNode;\n}\n\nexport function getAbsoluteStateAddressByBinding(binding: IBindingInfo, knownRootNode?: Node | null): IAbsoluteStateAddress {\n // 切断されていても、キャッシュされていれば絶対状態アドレスを返す。\n let absoluteStateAddress: IAbsoluteStateAddress | null = null;\n absoluteStateAddress = absoluteStateAddressByBinding.get(binding) || null;\n if (absoluteStateAddress !== null) {\n return absoluteStateAddress;\n }\n\n const rootNode: Node = resolveBindingRootNode(binding, knownRootNode);\n\n const listIndex = getListIndexByBindingInfo(binding);\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n absoluteStateAddress = absoluteAddressOf(stateElement, binding.statePathInfo, listIndex);\n absoluteStateAddressByBinding.set(binding, absoluteStateAddress);\n return absoluteStateAddress;\n}\n\nexport function clearAbsoluteStateAddressByBinding(binding: IBindingInfo) {\n absoluteStateAddressByBinding.delete(binding);\n}","import { createAbsoluteStateAddress } from \"../address/AbsoluteStateAddress\";\nimport { ITreePath, IAbsoluteStateAddress } from \"../address/types\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { IListIndex } from \"../list/types\";\nimport { IBindingInfo } from \"./types\";\n\n/**\n * 絶対アドレス → 登録 binding の台帳。\n *\n * リスト行の絶対アドレスは (absolutePathInfo, listIndex) の組ごとに一意で、\n * 登録される binding は通常 1 本しかない。アドレスごとに Set を確保すると\n * 行×binding の数だけ Set アロケーションが積み上がるため、単一値で持ち\n * 2 本目から Set に昇格する(interestedSessionsByNode と同じ前例)。\n */\nconst bindingsByAbsoluteStateAddress: WeakMap<IAbsoluteStateAddress, IBindingInfo | Set<IBindingInfo>> = new WeakMap();\n\n/**\n * 参照専用の取得。未登録アドレスにエントリを生成・キャッシュしない\n * (リスト置換の drain は大量のバインディング無しアドレスを照会するため、\n * 生成すると空エントリが溜まり続ける)。\n * 戻り値は単一 binding(登録 1 本)か Set(2 本以上)のどちらか。\n * 呼び出し側は Set を変異してはならない(instanceof で分岐できるよう\n * ReadonlySet でなく Set 型で返す)。\n */\nexport function peekBindingsByAbsoluteStateAddress(\n absoluteStateAddress: IAbsoluteStateAddress,\n): IBindingInfo | Set<IBindingInfo> | undefined {\n return bindingsByAbsoluteStateAddress.get(absoluteStateAddress);\n}\n\nexport function addBindingByAbsoluteStateAddress(absoluteStateAddress: IAbsoluteStateAddress, binding: IBindingInfo): void {\n const current = bindingsByAbsoluteStateAddress.get(absoluteStateAddress);\n if (typeof current === \"undefined\") {\n bindingsByAbsoluteStateAddress.set(absoluteStateAddress, binding);\n } else if (current instanceof Set) {\n current.add(binding);\n } else if (current !== binding) {\n bindingsByAbsoluteStateAddress.set(absoluteStateAddress, new Set([current, binding]));\n }\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:binding-added\", absoluteAddress: absoluteStateAddress, binding });\n }\n}\n\nexport function clearBindingSetByAbsoluteStateAddress(absoluteStateAddress: IAbsoluteStateAddress): void {\n bindingsByAbsoluteStateAddress.delete(absoluteStateAddress);\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:binding-cleared\", absoluteAddress: absoluteStateAddress });\n }\n}\n\nexport function removeBindingByAbsoluteStateAddress(absoluteStateAddress: IAbsoluteStateAddress, binding: IBindingInfo): void {\n const current = bindingsByAbsoluteStateAddress.get(absoluteStateAddress);\n if (typeof current === \"undefined\") {\n return;\n }\n if (current instanceof Set) {\n current.delete(binding);\n } else if (current === binding) {\n bindingsByAbsoluteStateAddress.delete(absoluteStateAddress);\n }\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:binding-removed\", absoluteAddress: absoluteStateAddress, binding });\n }\n}\n\n/**\n * パターン索引台帳(リスト行バインディング専用・docs/state-row-instantiation-redesign.md §3-3)。\n *\n * 行バインディングは (absolutePathInfo, listIndex) の 2 段キーで登録し、登録側では\n * AbsoluteStateAddress の intern(アドレスオブジェクト割当 + listIndex ごとの\n * intern 用 WeakMap)を一切行わない。書き込み側(setByAddress → enqueue)は従来\n * どおり intern 済みアドレスを使うため、drain はアドレスの構成要素\n * (absolutePathInfo / listIndex — どちらもオブジェクト同一性が保証済み)で\n * このパターン台帳を引ける。リオーダーは listIndex 同一性キーの帰結として\n * 従来同様ゼロタッチ。wholesale destroy は従来同様削除ゼロ(listIndex ごと GC 崩壊)。\n *\n * devtools 計装(state:binding-added/removed)はプロトコル契約なので、sink 接続時に\n * 限りアドレスを intern してイベントを流す(フック未接続時のコストは分岐 1 個の規範を維持)。\n */\nconst patternLedger: WeakMap<ITreePath, WeakMap<IListIndex, IBindingInfo | Set<IBindingInfo>>> = new WeakMap();\n\nexport function addBindingByPattern(absolutePathInfo: ITreePath, listIndex: IListIndex, binding: IBindingInfo): void {\n let rowMap = patternLedger.get(absolutePathInfo);\n if (typeof rowMap === \"undefined\") {\n rowMap = new WeakMap();\n patternLedger.set(absolutePathInfo, rowMap);\n }\n const current = rowMap.get(listIndex);\n if (typeof current === \"undefined\") {\n rowMap.set(listIndex, binding);\n } else if (current instanceof Set) {\n current.add(binding);\n } else if (current !== binding) {\n rowMap.set(listIndex, new Set([current, binding]));\n }\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:binding-added\", absoluteAddress: createAbsoluteStateAddress(absolutePathInfo, listIndex), binding });\n }\n}\n\nexport function removeBindingByPattern(absolutePathInfo: ITreePath, listIndex: IListIndex, binding: IBindingInfo): void {\n const rowMap = patternLedger.get(absolutePathInfo);\n if (typeof rowMap === \"undefined\") {\n return;\n }\n const current = rowMap.get(listIndex);\n if (typeof current === \"undefined\") {\n return;\n }\n if (current instanceof Set) {\n current.delete(binding);\n } else if (current === binding) {\n rowMap.delete(listIndex);\n }\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:binding-removed\", absoluteAddress: createAbsoluteStateAddress(absolutePathInfo, listIndex), binding });\n }\n}\n\n/**\n * drain(updater)用の統合参照。従来台帳 → パターン台帳の順に引く。\n * 従来台帳を先に引くのは、listIndex 付きでも旧経路(SSR ハイドレーション等)で\n * アドレス台帳に登録される可能性を許容するため(取りこぼし防止)。\n */\nexport function peekBindingsForAddress(\n absoluteStateAddress: IAbsoluteStateAddress,\n): IBindingInfo | Set<IBindingInfo> | undefined {\n const entry = bindingsByAbsoluteStateAddress.get(absoluteStateAddress);\n if (typeof entry !== \"undefined\") {\n return entry;\n }\n if (absoluteStateAddress.listIndex === null) {\n return undefined;\n }\n return patternLedger.get(absoluteStateAddress.absolutePathInfo)?.get(absoluteStateAddress.listIndex);\n}\n","import { WILDCARD } from \"../define\";\nimport { IListIndex } from \"../list/types\";\nimport { IPathInfo, IStateAddress } from \"./types\";\n\nconst _cache: WeakMap<IListIndex, WeakMap<IPathInfo, IStateAddress>> = new WeakMap();\nconst _cacheNullListIndex: WeakMap<IPathInfo, IStateAddress> = new WeakMap();\n\nclass StateAddress implements IStateAddress {\n readonly pathInfo: IPathInfo;\n readonly listIndex: IListIndex | null;\n private _parentAddress: IStateAddress | null | undefined;\n\n constructor(pathInfo: IPathInfo, listIndex: IListIndex | null) {\n this.pathInfo = pathInfo;\n this.listIndex = listIndex;\n }\n\n get parentAddress(): IStateAddress | null {\n if (typeof this._parentAddress !== 'undefined') {\n return this._parentAddress;\n }\n const parentPathInfo = this.pathInfo.parentPathInfo;\n if (parentPathInfo === null) {\n return null;\n }\n const lastSegment = this.pathInfo.segments[this.pathInfo.segments.length - 1];\n let parentListIndex: IListIndex | null = null;\n if (lastSegment === WILDCARD) {\n parentListIndex = this.listIndex?.parentListIndex ?? null;\n } else {\n parentListIndex = this.listIndex;\n }\n return this._parentAddress = createStateAddress(parentPathInfo, parentListIndex);\n }\n}\n\nexport function createStateAddress(pathInfo: IPathInfo, listIndex: IListIndex | null): IStateAddress {\n if (listIndex === null) {\n let cached = _cacheNullListIndex.get(pathInfo);\n if (typeof cached !== \"undefined\") {\n return cached;\n }\n cached = new StateAddress(pathInfo, null);\n _cacheNullListIndex.set(pathInfo, cached);\n return cached;\n } else {\n let cacheByPathInfo = _cache.get(listIndex);\n if (typeof cacheByPathInfo === \"undefined\") {\n cacheByPathInfo = new WeakMap<IPathInfo, IStateAddress>();\n _cache.set(listIndex, cacheByPathInfo);\n }\n let cached = cacheByPathInfo.get(pathInfo);\n if (typeof cached !== \"undefined\") {\n return cached;\n }\n cached = new StateAddress(pathInfo, listIndex);\n cacheByPathInfo.set(pathInfo, cached);\n return cached;\n }\n}","import { createStateAddress } from \"../address/StateAddress\";\nimport { IStateAddress } from \"../address/types\";\nimport { getListIndexByBindingInfo } from \"../list/getListIndexByBindingInfo\";\nimport { raiseError } from \"../raiseError\";\nimport { IBindingInfo } from \"../types\";\n\nconst stateAddressByBindingInfo: WeakMap<IBindingInfo, IStateAddress> = new WeakMap();\n\nexport function getStateAddressByBindingInfo(bindingInfo: IBindingInfo) {\n let stateAddress: IStateAddress | null = null;\n stateAddress = stateAddressByBindingInfo.get(bindingInfo) || null;\n if (stateAddress !== null) {\n return stateAddress;\n }\n if (bindingInfo.statePathInfo.wildcardCount > 0) {\n const listIndex = getListIndexByBindingInfo(bindingInfo);\n if (listIndex === null) {\n raiseError(`Cannot resolve state address for binding with wildcard statePathName \"${bindingInfo.statePathName}\" because list index is null.`);\n }\n stateAddress = createStateAddress(bindingInfo.statePathInfo, listIndex);\n } else {\n stateAddress = createStateAddress(bindingInfo.statePathInfo, null);\n }\n stateAddressByBindingInfo.set(bindingInfo, stateAddress);\n return stateAddress;\n}\n\n// call for change loopContext\nexport function clearStateAddressByBindingInfo(bindingInfo: IBindingInfo) {\n stateAddressByBindingInfo.delete(bindingInfo);\n}","import { IBindingInfo } from \"../types\";\n\n/**\n * イベントハンドラ登録の台帳。\n *\n * 旧実装は Map<string, Set<IBindingInfo>>(文字列キーの強参照 Map)で binding を\n * 保持していたため、binding.node → 行 DOM サブツリー全体が解放不能だった\n * (detach 系はほぼ呼ばれないため、リスト削除後も全イベントバインディングが\n * 永久保持されるリーク。clear-10k 後に 10k 行分の detached DOM が残留していた)。\n *\n * WeakSet(帰属判定・冪等性)と件数カウンタ(「最後の 1 件が外れたらハンドラを\n * 掃除する」判定)に分離し、binding を強参照しない。GC で binding が消えた場合\n * カウンタは減らないが、残るのはキー文字列と数値のみで実害はない。\n */\nexport interface IHandlerBindingRegistry {\n /** binding を key に登録する。新規登録なら true を返す(既登録は冪等に false) */\n add(key: string, binding: IBindingInfo): boolean;\n /** binding を key から外す。key の登録件数が 0 になったら true を返す */\n remove(key: string, binding: IBindingInfo): boolean;\n has(key: string, binding: IBindingInfo): boolean;\n countOf(key: string): number;\n readonly keyCount: number;\n clear(): void;\n}\n\nexport function createHandlerBindingRegistry(): IHandlerBindingRegistry {\n const attachedByKey = new Map<string, WeakSet<IBindingInfo>>();\n const countByKey = new Map<string, number>();\n return {\n add(key: string, binding: IBindingInfo): boolean {\n let attached = attachedByKey.get(key);\n if (typeof attached === \"undefined\") {\n attached = new WeakSet<IBindingInfo>();\n attachedByKey.set(key, attached);\n }\n if (attached.has(binding)) {\n return false;\n }\n attached.add(binding);\n countByKey.set(key, (countByKey.get(key) ?? 0) + 1);\n return true;\n },\n remove(key: string, binding: IBindingInfo): boolean {\n const attached = attachedByKey.get(key);\n if (typeof attached === \"undefined\" || !attached.has(binding)) {\n return false;\n }\n attached.delete(binding);\n const next = (countByKey.get(key) ?? 1) - 1;\n if (next <= 0) {\n attachedByKey.delete(key);\n countByKey.delete(key);\n return true;\n }\n countByKey.set(key, next);\n return false;\n },\n has(key: string, binding: IBindingInfo): boolean {\n return attachedByKey.get(key)?.has(binding) ?? false;\n },\n countOf(key: string): number {\n return countByKey.get(key) ?? 0;\n },\n get keyCount(): number {\n return countByKey.size;\n },\n clear(): void {\n attachedByKey.clear();\n countByKey.clear();\n },\n };\n}\n","import { EVENT_PROP_PREFIX, MODIFIER_READONLY } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo, IFilterInfo } from \"../types\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { createHandlerBindingRegistry } from \"./handlerBindingRegistry\";\n\nconst handlerByHandlerKey: Map<string, (event: Event) => any> = new Map();\n// binding を強参照しない台帳(handlerBindingRegistry.ts のリーク解説を参照)\nconst bindingRegistry = /*#__PURE__*/ createHandlerBindingRegistry();\n\nfunction getHandlerKey(binding: IBindingInfo, eventName: string): string {\n const filterKey = binding.inFilters.map(f => f.filterName + '(' + f.args.join(',') + ')').join('|');\n return `${binding.statePathName}::${eventName}::${filterKey}`;\n}\n\nfunction getEventName(binding: IBindingInfo): string {\n let eventName = 'input';\n for(const modifier of binding.propModifiers) {\n if (modifier.startsWith(EVENT_PROP_PREFIX)) {\n eventName = modifier.slice(EVENT_PROP_PREFIX.length);\n }\n }\n return eventName;\n}\n\nconst checkboxEventHandlerFunction = (\n statePathName: string,\n inFilters: IFilterInfo[],\n) => (event: Event): any => {\n const node = event.target as HTMLInputElement;\n if (node === null) {\n console.warn(`[@wcstack/state] event.target is null.`);\n return;\n }\n if (node.type !== 'checkbox') {\n console.warn(`[@wcstack/state] event.target is not a checkbox input element.`);\n return;\n }\n const checked = node.checked;\n const newValue = node.value;\n let filteredNewValue: unknown = newValue;\n for(const filter of inFilters) {\n filteredNewValue = filter.filterFn(filteredNewValue);\n }\n\n const rootNode = node.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for two-way binding.`);\n }\n\n const loopContext = getLoopContextByNode(node);\n stateElement.createState(\"writable\", (state) => {\n state[setLoopContextSymbol](loopContext, () => {\n let currentValue = state[statePathName];\n if (Array.isArray(currentValue)) {\n if (checked) {\n if (currentValue.indexOf(filteredNewValue) === -1) {\n state[statePathName] = currentValue.concat(filteredNewValue);\n }\n } else {\n const index = currentValue.indexOf(filteredNewValue);\n if (index !== -1) {\n state[statePathName] = currentValue.toSpliced(index, 1);\n }\n }\n } else {\n if (checked) {\n state[statePathName] = [filteredNewValue];\n } else {\n state[statePathName] = [];\n }\n }\n });\n });\n}\n\nexport function attachCheckboxEventHandler(binding: IBindingInfo): boolean {\n if (binding.bindingType === \"checkbox\" && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const key = getHandlerKey(binding, eventName);\n let checkboxEventHandler = handlerByHandlerKey.get(key);\n if (typeof checkboxEventHandler === \"undefined\") {\n checkboxEventHandler = checkboxEventHandlerFunction(\n binding.statePathName,\n binding.inFilters\n );\n handlerByHandlerKey.set(key, checkboxEventHandler);\n }\n (binding.node as Element).addEventListener(eventName, checkboxEventHandler);\n bindingRegistry.add(key, binding);\n return true;\n }\n return false;\n}\n\nexport function detachCheckboxEventHandler(binding: IBindingInfo): boolean {\n if (binding.bindingType === \"checkbox\" && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const key = getHandlerKey(binding, eventName);\n const checkboxEventHandler = handlerByHandlerKey.get(key);\n if (typeof checkboxEventHandler === \"undefined\") {\n return false;\n }\n (binding.node as Element).removeEventListener(eventName, checkboxEventHandler);\n\n if (bindingRegistry.countOf(key) === 0) {\n return false;\n }\n if (bindingRegistry.remove(key, binding)) {\n handlerByHandlerKey.delete(key);\n }\n return true;\n }\n return false;\n}\n\nexport const __private__ = {\n handlerByHandlerKey,\n bindingRegistry,\n getHandlerKey,\n getEventName,\n checkboxEventHandlerFunction,\n};\n","/**\n * captureHandlerRejection.ts\n *\n * state 側ハンドラ(`$on` の event-token subscriber、`onXxx:` の state メソッド、\n * DOM イベント起点の command-token emit)の戻り値を受け取り、Promise が混ざって\n * いれば reject を捕捉して報告する。\n *\n * なぜ必要か:\n * 発火経路はハンドラの完了を待たない。戻り値は `Token.emit` の結果配列にしか現れず、\n * 呼び出し側(eventTokenHandler / handler)はそれを捨てている。そのため **async\n * ハンドラが reject すると unhandled rejection になり**、しかも「どのハンドラで\n * 落ちたか」の手掛かりがスタックにしか残らない(特性化:\n * `__tests__/poc.asyncOnLoopContext.test.ts`)。\n *\n * 握り潰しではない:\n * 可視性は `console.error` で保たれ、state 名・ハンドラ名が付く分むしろ特定は容易に\n * なる。非同期の失敗を「例外の伝播」ではなく「診断可能な報告」に落とすのは\n * never-throw(async-io-node-guidelines.md §3.6)と同じ方針であり、I/O ノードが\n * `error` プロパティへ流すのと同じ位置づけの、state 側ハンドラ版にあたる。\n *\n * 同期 throw はここを通らない(従来どおり呼び出し元へ伝播する)。プログラマエラーを\n * loud に落とす `raiseError` の挙動は一切変えない。\n */\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" || typeof value === \"function\") &&\n value !== null &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * @param result ハンドラ呼び出しの戻り値。`Token.emit` の結果配列(subscriber ごとの\n * 戻り値)と、単一ハンドラの戻り値の両方を受ける。\n * @param describe 報告に載せるハンドラの識別名(例: `$on.\"rowFailed\" of state \"default\"`)。\n */\nexport function captureHandlerRejection(result: unknown, describe: string): void {\n // emit は subscriber ごとの戻り値配列。単一ハンドラの戻り値はそのまま届く。\n const values = Array.isArray(result) ? result : [result];\n for (const value of values) {\n if (!isThenable(value)) {\n continue;\n }\n // Promise.resolve は native Promise をそのまま返すため、catch の登録によって\n // 元の Promise が handled になる(thenable は同値の Promise に包まれる)。\n Promise.resolve(value).catch((error: unknown) => {\n console.error(`[wcstack/state] ${describe} rejected.`, error);\n });\n }\n}\n","// command-token / event-token が共有する pub/sub プリミティブ。\n// _subscribers は Set のため挿入順を保持する。\n// emit() は subscribe() された順に呼び出され、戻り値配列も同じ順序で返る。\n//\n// 「誰が subscribe し誰が emit するか」だけが command / event の違い:\n// - command-token: element が subscribe / state が emit\n// - event-token: state(`$on`) が subscribe / element(listener) が emit\n\nexport type TokenSubscriber = (...args: unknown[]) => unknown;\n\nexport interface IToken {\n readonly name: string;\n readonly size: number;\n subscribe(fn: TokenSubscriber): () => void;\n unsubscribe(fn: TokenSubscriber): boolean;\n emit(...args: unknown[]): unknown[];\n}\n\nexport class Token implements IToken {\n private _name: string;\n private _subscribers: Set<TokenSubscriber> = new Set();\n\n constructor(name: string) {\n this._name = name;\n }\n\n get name(): string {\n return this._name;\n }\n\n get size(): number {\n return this._subscribers.size;\n }\n\n subscribe(fn: TokenSubscriber): () => void {\n this._subscribers.add(fn);\n return () => {\n this._subscribers.delete(fn);\n };\n }\n\n unsubscribe(fn: TokenSubscriber): boolean {\n return this._subscribers.delete(fn);\n }\n\n emit(...args: unknown[]): unknown[] {\n const results: unknown[] = [];\n for (const fn of this._subscribers) {\n results.push(fn(...args));\n }\n return results;\n }\n}\n","import type { IStateElement } from \"../components/types\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { Token } from \"../token/Token\";\n\n// EventToken は共有 pub/sub プリミティブ Token の薄い特化(element→state 方向)。\n// instanceof による型判別を成立させるため独立クラスとして維持する。\nexport class EventToken extends Token {\n /**\n * 属する state 要素(devtools のツリー識別 — protocol v2 追補)。\n * registry(getOrCreateEventToken)経由の生成でのみ渡る optional 参照。\n * 寿命は registry 側の WeakMap が管理する(CommandToken と同じ位置づけ)。\n */\n private _stateElement: IStateElement | undefined;\n\n constructor(name: string, stateElement?: IStateElement) {\n super(name);\n this._stateElement = stateElement;\n }\n\n emit(...args: unknown[]): unknown[] {\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"state:token-emit\",\n kind: \"event\",\n tokenName: this.name,\n args,\n subscriberCount: this.size,\n stateElement: this._stateElement,\n });\n }\n return super.emit(...args);\n }\n}\n\nexport function isEventToken(value: unknown): value is EventToken {\n return value instanceof EventToken;\n}\n","import { IStateElement } from \"../components/types\";\nimport { EventToken } from \"./EventToken\";\n\nconst registryByStateElement: WeakMap<IStateElement, Map<string, EventToken>> = new WeakMap();\n\nexport function getOrCreateEventToken(stateElement: IStateElement, name: string): EventToken {\n let registry = registryByStateElement.get(stateElement);\n if (typeof registry === \"undefined\") {\n registry = new Map<string, EventToken>();\n registryByStateElement.set(stateElement, registry);\n }\n let token = registry.get(name);\n if (typeof token === \"undefined\") {\n // stateElement を渡すのは devtools のツリー識別(protocol v2 追補)のため\n token = new EventToken(name, stateElement);\n registry.set(name, token);\n }\n return token;\n}\n\nexport function clearEventTokenRegistry(stateElement: IStateElement): void {\n registryByStateElement.delete(stateElement);\n}\n\nexport const __private__ = {\n registryByStateElement,\n};\n","/**\n * eventToken.<propertyName>: <eventTokenName> バインディングの attach ハンドラ。\n *\n * command-token の双対(element→state)。要素が dispatch する CustomEvent を受けて\n * event-token を emit し、state 側の `$on` ハンドラ群へ pub/sub で配送する。\n *\n * 設計(MVP スコープ: wc-bindable カスタム要素のみ):\n * - キーは生イベント名ではなく **wcBindable property 名**。実 DOM イベント名は\n * wcBindable.properties[].event から解決する(command-token が wcBindable.commands で\n * 検証するのと対称。コロンを含む namespaced event 名と binding 構文の `:` 衝突も回避)。\n * - <prop> が wcBindable.properties に宣言されていることは attach 時に検証する\n * (要素クラス参照のみで DOM 接続に非依存。fail-fast / typo 耐性)。\n * - <eventTokenName> が $eventTokens に宣言されていることは **発火時** に検証する\n * (state 解決が必要なため。詳細は下記の fire-time 解決の注記を参照)。\n * - subscriber 引数規約は `(state, event, ...listIndexes)`。\n * - modifier `#prevent` / `#stop` は既存イベント binding と同等にサポート。\n *\n * token はイベント発火ごとに registry から解決する(getOrCreateEventToken)。これにより\n * state の再 set で registry が作り直されても最新の subscriber 群へ配送できる。\n *\n * state element の解決と `$eventTokens` 検証は **発火時** に行う(attach 時ではない)。\n * 構造ブロック(for/if)や SSR hydration では、binding 初期化時にノードが detached な\n * DocumentFragment / wrapper 上にあり、その時点では element.getRootNode() から state を\n * 解決できないため。onclick / two-way ハンドラと同じく fire-time 解決に揃えている。\n */\n\nimport { EVENT_TOKEN_NAMESPACE, MODIFIER_PREVENT, MODIFIER_STOP } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { getScopedIndexes } from \"../list/wildcardLevel\";\nimport { didYouMean, LINT_HINT } from \"../errorGuidance\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration, ReadBindableResult } from \"../protocol/wcBindableReader\";\nimport { IBindingInfo } from \"../types\";\nimport { captureHandlerRejection } from \"./captureHandlerRejection\";\nimport { getOrCreateEventToken } from \"./eventTokenRegistry\";\n\ninterface IEventTokenListener {\n readonly eventName: string;\n readonly handler: (event: Event) => void;\n}\n\nconst listenerByBinding: WeakMap<IBindingInfo, IEventTokenListener> = new WeakMap();\n\nfunction getWcBindable(element: Element): ReadBindableResult | null {\n const customTagName = getCustomElement(element);\n if (customTagName === null) {\n return null;\n }\n // attach 側で未定義要素は whenDefined 後に再試行するため、ここに来る時点で customClass は定義済み。\n return readBindableDeclaration(element);\n}\n\nexport function attachEventTokenHandler(binding: IBindingInfo): boolean {\n if (binding.propSegments[0] !== EVENT_TOKEN_NAMESPACE) {\n return false;\n }\n const element = binding.node as Element;\n\n // カスタム要素が未定義なら定義後に再試行(wcBindable が必要なため)。\n const customTagName = getCustomElement(element);\n const registry = getCustomElementRegistry(element);\n if (customTagName !== null && registry?.get(customTagName) === undefined) {\n if (registry === null) {\n raiseError(`CustomElementRegistry is unavailable for <${customTagName}>.`);\n }\n return true;\n }\n\n // 再評価で二重 attach しない。\n if (listenerByBinding.has(binding)) {\n return true;\n }\n\n const propertyName = binding.propSegments[1];\n if (typeof propertyName !== \"string\" || propertyName.length === 0) {\n raiseError(`eventToken binding requires a property name (e.g., \"eventToken.error\").`);\n }\n\n const bindable = getWcBindable(element);\n if (bindable === null) {\n raiseError(`eventToken binding requires a wc-bindable custom element. <${element.tagName.toLowerCase()}> is not wc-bindable.`);\n }\n const propDesc = bindable.knownProperties.get(propertyName);\n if (typeof propDesc === \"undefined\") {\n raiseError(`Property \"${propertyName}\" is not declared in wcBindable.properties of <${element.tagName.toLowerCase()}>.${didYouMean(propertyName, bindable.knownProperties.keys())}`);\n }\n const eventName = propDesc.event;\n\n const tokenName = binding.statePathName;\n const modifiers = binding.propModifiers;\n const handler = (event: Event): void => {\n if (modifiers.includes(MODIFIER_PREVENT)) event.preventDefault();\n if (modifiers.includes(MODIFIER_STOP)) event.stopPropagation();\n\n // state は発火時の live root から解決する(attach 時は detached の可能性があるため)。\n const rootNode = element.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for eventToken handler.`);\n }\n if (!stateElement.eventTokenNames.has(tokenName)) {\n // lint も同じケースを wcs/token-undeclared で検出する(三面同語彙)。\n raiseError(`[wcs/token-undeclared] eventToken \"${tokenName}\" is not declared in $eventTokens.${didYouMean(tokenName, stateElement.eventTokenNames)}${LINT_HINT}`);\n }\n const loopContext = getLoopContextByNode(element);\n stateElement.createStateAsync(\"writable\", async (state) => {\n const results = state[setLoopContextSymbol](loopContext, () => {\n const indexes = loopContext !== null\n ? getScopedIndexes(loopContext.listIndex, loopContext.pathInfo.wildcardCount) : [];\n const token = getOrCreateEventToken(stateElement, tokenName);\n return token.emit(state, event, ...indexes);\n });\n // この経路はハンドラの完了を待たない(emit の戻り値はここでしか見えない)。\n // async な $on ハンドラの reject を unhandled にせず報告へ落とす。\n captureHandlerRejection(results, `$on.\"${tokenName}\"`);\n });\n };\n\n element.addEventListener(eventName, handler);\n listenerByBinding.set(binding, { eventName, handler });\n return true;\n}\n\nexport function detachEventTokenHandler(binding: IBindingInfo): boolean {\n if (binding.propSegments[0] !== EVENT_TOKEN_NAMESPACE) {\n return false;\n }\n const listener = listenerByBinding.get(binding);\n if (typeof listener === \"undefined\") {\n return false;\n }\n (binding.node as Element).removeEventListener(listener.eventName, listener.handler);\n listenerByBinding.delete(binding);\n return true;\n}\n\nexport const __private__ = {\n listenerByBinding,\n};\n","import type { IStateElement } from \"../components/types\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { Token } from \"../token/Token\";\nimport { ICommandToken } from \"./types\";\n\n// CommandToken は共有 pub/sub プリミティブ Token の薄い特化。\n// instanceof による型判別を成立させるため独立クラスとして維持する。\n//\nexport class CommandToken extends Token implements ICommandToken {\n /**\n * 属する state 要素(devtools のツリー識別 — protocol v2 追補)。\n * registry(getOrCreateCommandToken)経由の生成でのみ渡る optional 参照で、\n * token の寿命は registry 側の WeakMap が state 要素に紐づけている(ここが\n * 寿命を延ばす新しい経路にはならない)。emit の payload にだけ載せる。\n */\n private _stateElement: IStateElement | undefined;\n\n constructor(name: string, stateElement?: IStateElement) {\n super(name);\n this._stateElement = stateElement;\n }\n\n emit(...args: unknown[]): unknown[] {\n if (devtoolsSink !== null) {\n // subscriberCount 0 の emit(空撃ち)もそのまま流す — whenDefined 前の\n // command 空撃ちレース類をタイムラインで可視化するため\n devtoolsSink({\n type: \"state:token-emit\",\n kind: \"command\",\n tokenName: this.name,\n args,\n subscriberCount: this.size,\n stateElement: this._stateElement,\n });\n }\n return super.emit(...args);\n }\n}\n\nexport function isCommandToken(value: unknown): value is ICommandToken {\n return value instanceof CommandToken;\n}\n","import { createStateAddress } from \"../address/StateAddress\";\nimport { IPathInfo } from \"../address/types\";\nimport { isCommandToken } from \"../command/CommandToken\";\nimport { ICommandToken } from \"../command/types\";\nimport { EVENT_PROP_PREFIX, MODIFIER_PREVENT, MODIFIER_STOP, STATE_COMMAND_NAMESPACE_NAME } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { getByAddressSymbol, setLoopContextSymbol } from \"../proxy/symbols\";\nimport { getScopedIndexes } from \"../list/wildcardLevel\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo } from \"../types\";\nimport { captureHandlerRejection } from \"./captureHandlerRejection\";\nimport { createHandlerBindingRegistry } from \"./handlerBindingRegistry\";\n\n// onclick: $command.<name> のように、DOM イベントから command token を直接 emit する形式かを判定する。\n// 右辺が $command 名前空間配下のパス($command.<token>)のときに true。\nfunction isCommandTokenPath(statePathName: string): boolean {\n return statePathName.startsWith(STATE_COMMAND_NAMESPACE_NAME + \".\");\n}\n\nconst handlerByHandlerKey: Map<string, (event: Event) => any> = new Map();\n// binding を強参照しない台帳(handlerBindingRegistry.ts のリーク解説を参照)\n// 純粋な割り当て(Map 2 個)。バンドラが未使用時に落とせるよう明示する(ヘルパーだけの import に残さない)\nconst bindingRegistry = /*#__PURE__*/ createHandlerBindingRegistry();\n\nfunction getHandlerKey(binding: IBindingInfo): string {\n const modifierKey = binding.propModifiers.filter(m => m === MODIFIER_PREVENT || m === MODIFIER_STOP).sort().join(',');\n return `${binding.statePathName}::${modifierKey}`;\n}\n\nconst stateEventHandlerFunction = (\n handlerName: string,\n modifiers: string[],\n statePathInfo: IPathInfo\n) => (event: Event): any => {\n if (modifiers.includes(MODIFIER_PREVENT)) event.preventDefault();\n if (modifiers.includes(MODIFIER_STOP)) event.stopPropagation();\n\n const node = event.target as Element;\n const rootNode = node.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for event handler.`);\n }\n\n const loopContext = getLoopContextByNode(node);\n const isCommand = isCommandTokenPath(handlerName);\n stateElement.createStateAsync(\"writable\", async (state) => {\n const results = state[setLoopContextSymbol](loopContext, () => {\n // マウントされたスコープ(v2): 作者のハンドラが受ける添字は自スコープの\n // ループ分だけ(§4-4 / P2-9)。翻訳で増えたワイルドカード数を落とす。\n // 翻訳された for の台帳に無いループ文脈は外側スコープのもの(境界ホップで\n // 借りた行)なので、作者から見える添字は 0 本。\n // 記録の解決はノードから(findMountRecordForNode)— Shadow 形は rootNode\n // (shadowRoot)で直に引け、Light DOM 形はスコープ根がコンポーネント要素\n // 自身なので祖先走査が要る(rootNode だけ見ると Light DOM で外側の添字が漏れる)\n let scopedWildcardCount = loopContext !== null ? loopContext.pathInfo.wildcardCount : 0;\n if (loopContext !== null) {\n // 添字の段数はスコープ機能の handlerScope hook(webComponent/addressHooks.ts)が決める。\n // hook の無い state は判定 1 個で抜ける\n const hooks = stateElement.addressHooks;\n if (hooks) {\n const scopes = hooks.handlerScope;\n for (let i = 0; i < scopes.length; i++) {\n scopedWildcardCount = scopes[i](stateElement, node, rootNode, loopContext, scopedWildcardCount);\n }\n }\n }\n const indexes = loopContext !== null\n ? getScopedIndexes(loopContext.listIndex, scopedWildcardCount) : [];\n if (isCommand) {\n // command token を解決して emit。引数はハンドラ呼び出しと同じく (event, ...listIndexes) を透過する。\n const token = state[getByAddressSymbol](createStateAddress(statePathInfo, null));\n if (!isCommandToken(token)) {\n raiseError(`Event binding \"${handlerName}\" did not resolve to a CommandToken. Declare the name in $commandTokens and reference it as $command.<name>.`);\n }\n return (token as ICommandToken).emit(event, ...indexes);\n }\n const handler = state[handlerName];\n if (typeof handler !== \"function\") {\n raiseError(`Handler \"${handlerName}\" is not a function on the state tree.`);\n }\n return Reflect.apply(handler, state, [event, ...indexes]);\n });\n // eventTokenHandler と同じく、この経路もハンドラの完了を待たない。async な\n // state メソッド / command subscriber の reject を unhandled にせず報告へ落とす。\n captureHandlerRejection(results, `\"${handlerName}\"`);\n });\n}\n\nexport function attachEventHandler(binding: IBindingInfo): boolean {\n if (!binding.propName.startsWith(EVENT_PROP_PREFIX)) {\n return false;\n }\n const key = getHandlerKey(binding);\n let stateEventHandler = handlerByHandlerKey.get(key);\n if (typeof stateEventHandler === \"undefined\") {\n stateEventHandler = stateEventHandlerFunction(binding.statePathName, binding.propModifiers, binding.statePathInfo);\n handlerByHandlerKey.set(key, stateEventHandler);\n }\n\n const eventName = binding.propName.slice(2);\n (binding.node as Element).addEventListener(eventName, stateEventHandler);\n\n bindingRegistry.add(key, binding);\n return true;\n}\n\nexport function detachEventHandler(binding: IBindingInfo): boolean {\n if (!binding.propName.startsWith(EVENT_PROP_PREFIX)) {\n return false;\n }\n const key = getHandlerKey(binding);\n const stateEventHandler = handlerByHandlerKey.get(key);\n if (typeof stateEventHandler === \"undefined\") {\n return false;\n }\n const eventName = binding.propName.slice(2);\n (binding.node as Element).removeEventListener(eventName, stateEventHandler);\n\n if (bindingRegistry.countOf(key) === 0) {\n return false;\n }\n if (bindingRegistry.remove(key, binding)) {\n handlerByHandlerKey.delete(key);\n }\n return true;\n}\n\nexport const __private__ = {\n handlerByHandlerKey,\n bindingRegistry,\n getHandlerKey,\n};\n\n","import { EVENT_PROP_PREFIX, MODIFIER_READONLY } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo, IFilterInfo } from \"../types\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { createHandlerBindingRegistry } from \"./handlerBindingRegistry\";\n\nconst handlerByHandlerKey: Map<string, (event: Event) => any> = new Map();\n// binding を強参照しない台帳(handlerBindingRegistry.ts のリーク解説を参照)\nconst bindingRegistry = /*#__PURE__*/ createHandlerBindingRegistry();\n\nfunction getHandlerKey(binding: IBindingInfo, eventName: string): string {\n const filterKey = binding.inFilters.map(f => f.filterName + '(' + f.args.join(',') + ')').join('|');\n return `${binding.statePathName}::${eventName}::${filterKey}`;\n}\n\nfunction getEventName(binding: IBindingInfo): string {\n let eventName = 'input';\n for(const modifier of binding.propModifiers) {\n if (modifier.startsWith(EVENT_PROP_PREFIX)) {\n eventName = modifier.slice(EVENT_PROP_PREFIX.length);\n }\n }\n return eventName;\n}\n\nconst radioEventHandlerFunction = (\n statePathName: string,\n inFilters: IFilterInfo[],\n) => (event: Event): any => {\n const node = event.target as HTMLInputElement;\n if (node === null) {\n console.warn(`[@wcstack/state] event.target is null.`);\n return;\n }\n if (node.type !== 'radio') {\n console.warn(`[@wcstack/state] event.target is not a radio input element.`);\n return;\n }\n if (node.checked === false) {\n return;\n }\n const newValue = node.value;\n let filteredNewValue: unknown = newValue;\n for(const filter of inFilters) {\n filteredNewValue = filter.filterFn(filteredNewValue);\n }\n\n const rootNode = node.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for two-way binding.`);\n }\n\n const loopContext = getLoopContextByNode(node);\n stateElement.createState(\"writable\", (state) => {\n state[setLoopContextSymbol](loopContext, () => {\n state[statePathName] = filteredNewValue;\n });\n });\n}\n\nexport function attachRadioEventHandler(binding: IBindingInfo): boolean {\n if (binding.bindingType === \"radio\" && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const key = getHandlerKey(binding, eventName);\n let radioEventHandler = handlerByHandlerKey.get(key);\n if (typeof radioEventHandler === \"undefined\") {\n radioEventHandler = radioEventHandlerFunction(\n binding.statePathName,\n binding.inFilters\n );\n handlerByHandlerKey.set(key, radioEventHandler);\n }\n (binding.node as Element).addEventListener(eventName, radioEventHandler);\n bindingRegistry.add(key, binding);\n return true;\n }\n return false;\n}\n\nexport function detachRadioEventHandler(binding: IBindingInfo): boolean {\n if (binding.bindingType === \"radio\" && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const key = getHandlerKey(binding, eventName);\n const radioEventHandler = handlerByHandlerKey.get(key);\n if (typeof radioEventHandler === \"undefined\") {\n return false;\n }\n (binding.node as Element).removeEventListener(eventName, radioEventHandler);\n\n if (bindingRegistry.countOf(key) === 0) {\n return false;\n }\n if (bindingRegistry.remove(key, binding)) {\n handlerByHandlerKey.delete(key);\n }\n return true;\n }\n return false;\n}\n\nexport const __private__ = {\n handlerByHandlerKey,\n bindingRegistry,\n getHandlerKey,\n getEventName,\n radioEventHandlerFunction,\n};\n","import { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration } from \"../protocol/wcBindableReader\";\nimport { raiseError } from \"../raiseError\";\n\nconst CHECK_TYPES = new Set([ 'radio', 'checkbox' ]);\nconst DEFAULT_VALUE_PROP_NAMES = new Set([ 'value', 'valueAsNumber', 'valueAsDate' ]);\n\nexport function isPossibleTwoWay(node: Node, propName: string): boolean {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return false;\n }\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n if (tagName === 'input') {\n const inputType = (element.getAttribute('type') || 'text').toLowerCase();\n if (inputType === 'button') {\n return false;\n }\n if (CHECK_TYPES.has(inputType) && propName === 'checked') {\n return true;\n }\n if (DEFAULT_VALUE_PROP_NAMES.has(propName)) {\n return true;\n }\n }\n if (tagName === 'select' && propName === 'value') {\n return true;\n }\n if (tagName === 'textarea' && propName === 'value') {\n return true;\n }\n const customTagName = getCustomElement(element);\n if (customTagName !== null) {\n const customClass = getCustomElementRegistry(element)?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n raiseError(`Custom element <${customTagName}> is not defined. Cannot determine if property \"${propName}\" is suitable for two-way binding.`);\n }\n const bindable = readBindableDeclaration(element);\n if (bindable?.knownProperties.has(propName)) {\n return true;\n }\n }\n return false;\n}\n","/**\n * propagation/propagation.ts\n *\n * Phase 3 の因果伝播コア(feature flag `enablePropagationContext` 下)。\n * 依存は types のみの葉モジュールとし、twowayHandler / applyChangeToProperty /\n * setByAddress / updater の計装点から循環 import なしで参照できるようにする。\n *\n * wire 識別は (node × member × statePathName) で行う。設計書の\n * WriteReceipt は bindingId + generation を持つが、twoway handler は共有\n * handler(handlerByHandlerKey)で binding インスタンスに到達できないため、\n * runtime の edge / receipt 照合キーは wire 単位とする。BindingSession\n * generation との統合(再 attach 後の edge ID 非再利用)は session 側の\n * 計装が揃う段階で bindingGeneration に反映する。\n */\n\nimport { IPropagationContext, IWriteReceipt } from \"./types\";\n\nexport type PropagationEdgeDirection = \"to-element\" | \"to-state\";\n\nlet nextWireId = 1;\nlet nextTransactionId = 1;\nlet nextSynchronousScopeId = 1;\n\n// node を強参照しない wire 台帳。inner key = `${statePathName}::${member}`\nconst wireIdsByNode = new WeakMap<Node, Map<string, number>>();\n\nfunction wireKey(member: string, statePathName: string): string {\n return `${statePathName}::${member}`;\n}\n\n/**\n * wire(配線)の安定 ID を返す。edge ID の基底と receipt の bindingId に使う。\n */\nexport function getWireId(\n node: Node,\n member: string,\n statePathName: string,\n): number {\n let byKey = wireIdsByNode.get(node);\n if (typeof byKey === \"undefined\") {\n byKey = new Map();\n wireIdsByNode.set(node, byKey);\n }\n const key = wireKey(member, statePathName);\n let wireId = byKey.get(key);\n if (typeof wireId === \"undefined\") {\n wireId = nextWireId++;\n byKey.set(key, wireId);\n }\n return wireId;\n}\n\n/** wire × 方向 → edge ID。方向を含めるため再利用されない */\nexport function getEdgeId(wireId: number, direction: PropagationEdgeDirection): number {\n return direction === \"to-element\" ? wireId * 2 : wireId * 2 + 1;\n}\n\nconst EMPTY_EDGES: ReadonlySet<number> = new Set<number>();\n\n/** 外部 event / API update ごとの transaction 開始。current context は変更しない */\nexport function beginPropagationTransaction(originBindingId: number): IPropagationContext {\n return {\n transactionId: nextTransactionId++,\n originBindingId,\n visitedEdges: EMPTY_EDGES,\n hop: 0,\n };\n}\n\n/** edge を 1 つ通過した新しい context を返す(visitedEdges 追加・hop+1) */\nexport function extendPropagationContext(\n context: IPropagationContext,\n edgeId: number,\n): IPropagationContext {\n const visitedEdges = new Set(context.visitedEdges);\n visitedEdges.add(edgeId);\n return {\n transactionId: context.transactionId,\n originBindingId: context.originBindingId,\n visitedEdges,\n hop: context.hop + 1,\n };\n}\n\n// 同期 dynamic scope の current context(updater drain / element 書き込み中に設定)\nlet currentContext: IPropagationContext | null = null;\n\nexport function getCurrentPropagationContext(): IPropagationContext | null {\n return currentContext;\n}\n\nexport function runWithPropagationContext<T>(\n context: IPropagationContext | null,\n callback: () => T,\n): T {\n const previous = currentContext;\n currentContext = context;\n try {\n return callback();\n } finally {\n currentContext = previous;\n }\n}\n\n// WriteReceipt: 同期 scope 限定のスタック。scope 終了時に必ず破棄される\ninterface IActiveWriteReceipt {\n readonly receipt: IWriteReceipt;\n readonly node: Node;\n}\n\nconst receiptStack: IActiveWriteReceipt[] = [];\n\n/**\n * state → element 書き込みを receipt scope で包んで実行する。\n * setter が同期 dispatch する event は matchWriteReceipt でこの receipt を観測できる。\n */\nexport function runWithWriteReceipt<T>(\n node: Node,\n member: string,\n writtenValue: unknown,\n bindingId: number,\n transactionId: number,\n callback: () => T,\n): T {\n const receipt: IWriteReceipt = {\n bindingId,\n bindingGeneration: 0,\n member,\n transactionId,\n synchronousScopeId: nextSynchronousScopeId++,\n writtenValue,\n };\n receiptStack.push({ receipt, node });\n try {\n return callback();\n } finally {\n receiptStack.pop();\n }\n}\n\n/**\n * (node, member) に対する最も内側の active receipt を返す。\n * confirmation / normalization の判定(writtenValue との Object.is 比較)は\n * 呼び出し側が行う。scope 外(非同期に届いた event)では null。\n */\nexport function matchWriteReceipt(node: Node, member: string): IWriteReceipt | null {\n for (let i = receiptStack.length - 1; i >= 0; i--) {\n const active = receiptStack[i];\n if (active.node === node && active.receipt.member === member) {\n return active.receipt;\n }\n }\n return null;\n}\n\n// テスト用\nexport const __private__ = {\n receiptStack,\n};\n","/**\n * occurrenceWrite.ts\n *\n * wc-bindable の `semantics: \"event\"` を宣言した property から届いた値を state へ書き込む\n * 間だけ、same-value guard(`config.sameValueGuard`・既定 ON)を 1 回分だけ無効化する\n * one-shot トークン。\n *\n * 背景:\n * same-value guard は primitive が `Object.is` 同値なら set / enqueue / 依存伝播 / DOM 適用 /\n * `$updatedCallback` をまるごとスキップする。current value(state)にとっては正しい最適化だが、\n * occurrence(同じ payload でも「もう一度起きた」ことに意味がある)へ適用すると発生を取りこぼす。\n * どちらであるかは producer の declaration が `semantics` で宣言する\n * (docs/architecture-hardening/12-wc-bindable-observable-inventory.md)。\n *\n * one-shot にしている理由:\n * フラグを書き込みの呼び出しスタック全体へ張ると、その内側で走る `$updatedCallback` や\n * 依存伝播が行う無関係な書き込みまでガードを失う。`setByAddress` が最初のガード評価で\n * トークンを消費するため、影響は目的の 1 write に閉じる。\n */\n\nlet pending = false;\n\n/** 直後の 1 write を occurrence として扱う。必ず `endOccurrenceWrite` と対で使う。 */\nexport function beginOccurrenceWrite(): void {\n pending = true;\n}\n\n/** 未消費のトークンを破棄する(write が setByAddress へ到達しなかった場合の後始末)。 */\nexport function endOccurrenceWrite(): void {\n pending = false;\n}\n\n/**\n * ガード評価側が呼ぶ。`true` を返したら、その 1 回だけ same-value guard を飛ばす。\n * トークンは呼んだ時点で消費される。\n */\nexport function consumeOccurrenceWrite(): boolean {\n if (!pending) return false;\n pending = false;\n return true;\n}\n","import { isPossibleTwoWay } from \"./isPossibleTwoWay\";\nimport { EVENT_PROP_PREFIX, MODIFIER_READONLY } from \"../define\";\nimport { config } from \"../config\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { beginPropagationTransaction, extendPropagationContext, getCurrentPropagationContext, getEdgeId, getWireId, matchWriteReceipt, runWithPropagationContext } from \"../propagation/propagation\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo, IFilterInfo } from \"../types\";\nimport { setLoopContextSymbol } from \"../proxy/symbols\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration } from \"../protocol/wcBindableReader\";\nimport { createHandlerBindingRegistry } from \"./handlerBindingRegistry\";\nimport { beginOccurrenceWrite, endOccurrenceWrite } from \"../proxy/occurrenceWrite\";\n\nconst handlerByHandlerKey: Map<string, (event: Event) => any> = new Map();\n// binding を強参照しない台帳(handlerBindingRegistry.ts のリーク解説を参照)\nconst bindingRegistry = /*#__PURE__*/ createHandlerBindingRegistry();\nconst producerValueObserversByNode = new WeakMap<Node, Map<string, Set<(value: unknown) => void>>>();\n\nconst DEFAULT_GETTER = (e: Event) => (e as CustomEvent).detail;\n\n/**\n * 既定 getter(`(e) => e.detail`)が要素の宣言と噛み合っていない典型 2 形を、\n * 要素 × プロパティごとに 1 回だけ警告する(README「What the element writes back」)。\n *\n * (a) detail が undefined なのに `element[propName]` には値がある —\n * CustomEvent でない Event を dispatch している / `detail` を付け忘れている\n * (b) detail が `{ <propName>: … }` の形のラッパーで、`element[propName]` はオブジェクトでない —\n * `getter: (e) => e.detail.<propName>` が要る\n *\n * どちらも state には黙って undefined / ラッパーが書かれ、例外も lint 診断も出ない\n * (payload の形は静的に見えない)。挙動は変えない — 書き込みはそのまま行う。\n * occurrence(`semantics: \"event\"`)は payload が任意なので対象外(呼び出し側で除外)。\n */\nconst warnedDefaultGetter = new WeakMap<Element, Set<string>>();\nfunction warnDefaultGetterMismatch(node: Element, propName: string, detail: unknown): void {\n const propValue = (node as any)[propName];\n let reason: string | null = null;\n if (typeof detail === \"undefined\") {\n if (typeof propValue !== \"undefined\") {\n reason = `the event carried no detail (undefined) while element.${propName} is ${typeof propValue}`;\n }\n } else if (\n detail !== null && typeof detail === \"object\" && Object.prototype.hasOwnProperty.call(detail, propName)\n && (propValue === null || typeof propValue !== \"object\")\n ) {\n reason = `the event's detail is an object with a \"${propName}\" key while element.${propName} is ${typeof propValue}`;\n }\n if (reason === null) return;\n let props = warnedDefaultGetter.get(node);\n if (typeof props === \"undefined\") {\n props = new Set();\n warnedDefaultGetter.set(node, props);\n }\n if (props.has(propName)) return;\n props.add(propName);\n console.warn(\n `[@wcstack/state] [wcs/default-getter-mismatch] <${node.tagName.toLowerCase()}> \"${propName}\": ${reason}. ` +\n `With no getter, state receives e.detail as-is. Dispatch the value itself as detail, or declare ` +\n `getter (e.g. (e) => e.detail.${propName}, or (e) => e.target.${propName}) on that wcBindable property.`\n );\n}\n\nfunction getHandlerKey(binding: IBindingInfo, eventName: string, hasGetter: boolean, isOccurrence: boolean): string {\n const filterKey = binding.inFilters.map(f => f.filterName + '(' + f.args.join(',') + ')').join('|');\n return `${binding.propName}::${binding.statePathName}::${eventName}::${filterKey}::${hasGetter ? 'g' : 'n'}::${isOccurrence ? 'o' : 's'}`;\n}\n\nfunction getEventName(binding: IBindingInfo): string {\n const tagName = (binding.node as Element).tagName.toLowerCase();\n // 1.default event name\n let eventName = (tagName === 'select') ? 'change' : 'input';\n // 2.wcBindable protocol\n const customTagName = getCustomElement(binding.node as Element);\n if (customTagName !== null) {\n const customClass = getCustomElementRegistry(binding.node)?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n raiseError(`Custom element <${customTagName}> is not defined. Cannot determine event name for two-way binding.`);\n }\n const propDesc = readBindableDeclaration(binding.node)?.knownProperties.get(binding.propName);\n if (propDesc) {\n eventName = propDesc.event;\n }\n }\n // 3.modifier(`#onchange` 等 — `on` + イベント名の修飾子形。README「Modifiers」参照)\n for(const modifier of binding.propModifiers) {\n if (modifier.startsWith(EVENT_PROP_PREFIX)) {\n eventName = modifier.slice(EVENT_PROP_PREFIX.length);\n }\n }\n return eventName;\n}\n\nfunction getValueGetter(binding: IBindingInfo): ((event: Event) => any) | null {\n const customTagName = getCustomElement(binding.node as Element);\n if (customTagName !== null) {\n const propDesc = readBindableDeclaration(binding.node)?.knownProperties.get(binding.propName);\n if (propDesc) {\n return propDesc.getter ?? DEFAULT_GETTER;\n }\n }\n return null;\n}\n\n/**\n * producer が `semantics: \"event\"` を宣言した property か。occurrence は同じ payload でも\n * 「もう一度起きた」ことに意味があるため、state への書き込みで same-value guard を通さない\n * (docs/async-io-node-guidelines.md §3.3.1 の `event`)。宣言が無い property は従来どおり\n * — 未指定は「未指定」であって state ではないので、挙動は変えない。\n */\nfunction isOccurrenceProperty(binding: IBindingInfo): boolean {\n const customTagName = getCustomElement(binding.node as Element);\n if (customTagName === null) return false;\n const propDesc = readBindableDeclaration(binding.node)?.knownProperties.get(binding.propName);\n return propDesc?.semantics === \"event\";\n}\n\nconst twowayEventHandlerFunction = (\n propName: string,\n statePathName: string,\n inFilters: IFilterInfo[],\n valueGetter: ((event: Event) => any) | null,\n isOccurrence: boolean,\n) => (event: Event): any => {\n const node = event.target as Element;\n if (node === null) {\n console.warn(`[@wcstack/state] event.target is null.`);\n return;\n }\n let newValue: any;\n if (valueGetter !== null) {\n newValue = valueGetter(event);\n if (valueGetter === DEFAULT_GETTER && !isOccurrence) {\n warnDefaultGetterMismatch(node, propName, newValue);\n }\n } else {\n if (!(propName in node)) {\n console.warn(`[@wcstack/state] Property \"${propName}\" does not exist on target element.`);\n return;\n }\n newValue = (node as any)[propName];\n }\n let filteredNewValue = newValue;\n for(const filter of inFilters) {\n filteredNewValue = filter.filterFn(filteredNewValue);\n }\n const producerObservers = producerValueObserversByNode.get(node)?.get(propName);\n if (typeof producerObservers !== \"undefined\") {\n for (const observer of producerObservers) observer(filteredNewValue);\n }\n\n let propagationContext: ReturnType<typeof getCurrentPropagationContext> = null;\n if (config.enablePropagationContext) {\n // Phase 3: element → state edge の因果判定(設計書 §4)。\n const wireId = getWireId(node, propName, statePathName);\n const receipt = matchWriteReceipt(node, propName);\n if (receipt !== null && Object.is(receipt.writtenValue, newValue)) {\n // 規則 4: 同じ setter call stack 内で同じ member から Object.is 同値の\n // 通知が戻った場合だけ confirmation として再伝播を抑止する。\n // shadow diagnostic(§8): primitive なら same-value guard も同じ結論に\n // なるため、provenance だけが守っている非 primitive の echo を可視化する。\n if (config.debug) {\n console.debug(`[@wcstack/state] propagation: write confirmation suppressed echo.`, {\n node,\n propName,\n statePathName,\n transactionId: receipt.transactionId,\n coveredBySameValueGuard: config.sameValueGuard\n && (filteredNewValue === null || typeof filteredNewValue !== \"object\"),\n });\n }\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"propagation:suppressed\",\n reason: \"confirmation\",\n transactionId: receipt.transactionId,\n edgeId: getEdgeId(wireId, \"to-state\"),\n node,\n member: propName,\n });\n }\n return;\n }\n // receipt があるが値が異なる場合は正規化差分: element の確定値として受理し、\n // 新しい edge を通る変更として継続する(規則 5・decision gate)。\n const toStateEdgeId = getEdgeId(wireId, \"to-state\");\n const baseContext = getCurrentPropagationContext();\n if (baseContext !== null && baseContext.visitedEdges.has(toStateEdgeId)) {\n // 規則 2: 同じ transaction が同じ edge を再度通ろうとした場合だけ抑止\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"propagation:suppressed\",\n reason: \"visited-edge\",\n transactionId: baseContext.transactionId,\n edgeId: toStateEdgeId,\n node,\n member: propName,\n });\n }\n return;\n }\n // 規則 1: 外部 event(受け皿の context が無い)なら新しい transaction を開始\n propagationContext = extendPropagationContext(\n baseContext ?? beginPropagationTransaction(wireId),\n toStateEdgeId,\n );\n }\n\n const rootNode = node.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for two-way binding.`);\n }\n\n const loopContext = getLoopContextByNode(node);\n const commitToState = (): void => {\n // occurrence は同値でも取りこぼしてはならない(§3.3.1 `event`)。トークンは\n // setByAddress の最初のガード評価で消費されるため、この write 1 回だけに効く。\n if (isOccurrence) beginOccurrenceWrite();\n try {\n stateElement.createState(\"writable\", (state) => {\n state[setLoopContextSymbol](loopContext, () => {\n state[statePathName] = filteredNewValue;\n });\n });\n } finally {\n if (isOccurrence) endOccurrenceWrite();\n }\n };\n if (propagationContext !== null) {\n runWithPropagationContext(propagationContext, commitToState);\n } else {\n commitToState();\n }\n}\n\nexport function addTwowayValueObserver(\n node: Node,\n propName: string,\n observer: (value: unknown) => void,\n): () => void {\n let byProperty = producerValueObserversByNode.get(node);\n if (typeof byProperty === \"undefined\") {\n byProperty = new Map();\n producerValueObserversByNode.set(node, byProperty);\n }\n let observers = byProperty.get(propName);\n if (typeof observers === \"undefined\") {\n observers = new Set();\n byProperty.set(propName, observers);\n }\n observers.add(observer);\n return () => {\n observers?.delete(observer);\n if (observers?.size === 0) byProperty?.delete(propName);\n if (byProperty?.size === 0) producerValueObserversByNode.delete(node);\n };\n}\n\nexport function attachTwowayEventHandler(binding: IBindingInfo): void {\n const customTagName = getCustomElement(binding.node as Element);\n if (customTagName !== null) {\n const registry = getCustomElementRegistry(binding.node);\n const customClass = registry?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n if (registry === null) {\n raiseError(`CustomElementRegistry is unavailable for <${customTagName}>.`);\n }\n return;\n }\n }\n\n if (isPossibleTwoWay(binding.node, binding.propName) && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const valueGetter = getValueGetter(binding);\n const isOccurrence = isOccurrenceProperty(binding);\n const key = getHandlerKey(binding, eventName, valueGetter !== null, isOccurrence);\n let twowayEventHandler = handlerByHandlerKey.get(key);\n if (typeof twowayEventHandler === \"undefined\") {\n twowayEventHandler = twowayEventHandlerFunction(\n binding.propName,\n binding.statePathName,\n binding.inFilters,\n valueGetter,\n isOccurrence\n );\n handlerByHandlerKey.set(key, twowayEventHandler);\n }\n (binding.node as Element).addEventListener(eventName, twowayEventHandler);\n bindingRegistry.add(key, binding);\n }\n}\n\nexport function detachTwowayEventHandler(binding: IBindingInfo): void {\n const customTagName = getCustomElement(binding.node as Element);\n if (customTagName !== null) {\n const registry = getCustomElementRegistry(binding.node);\n const customClass = registry?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n if (registry === null) {\n return;\n }\n return;\n }\n }\n\n if (isPossibleTwoWay(binding.node, binding.propName) && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1) {\n const eventName = getEventName(binding);\n const valueGetter = getValueGetter(binding);\n const key = getHandlerKey(binding, eventName, valueGetter !== null, isOccurrenceProperty(binding));\n const twowayEventHandler = handlerByHandlerKey.get(key);\n if (typeof twowayEventHandler === \"undefined\") {\n return;\n }\n (binding.node as Element).removeEventListener(eventName, twowayEventHandler);\n\n if (bindingRegistry.remove(key, binding)) {\n handlerByHandlerKey.delete(key);\n }\n }\n}\n\nexport const __private__ = {\n handlerByHandlerKey,\n bindingRegistry,\n producerValueObserversByNode,\n getHandlerKey,\n getEventName,\n getValueGetter,\n twowayEventHandlerFunction,\n DEFAULT_GETTER,\n};\n","// framework 自身が detach し明示的に解体(deactivate/unmount)したノード。\n// BindingOwner の MutationObserver は削除サブツリー走査でこれらをスキップする。\n//\n// 根拠: 削除時の handleRemovedNode は binding を dispose するだけ(DOM 構造変更も\n// connect-snapshot 依存も無い)で、framework が unmount 経路で既に dispose 済みの\n// content に対しては純粋な冗長走査(forEachInclusive で削除サブツリー全体を歩く)に\n// なる。create(追加)経路は two-way の connect-time snapshot を observer に依存する\n// ため対象外だが、削除は依存が無いため安全に飛ばせる。\n//\n// マークは observer が削除を配送した時点で消費(削除)する。マーク〜配送の間隔は\n// 単一 microtask であり、その間に外部 DOM 変異は割り込めない(framework の drain は\n// 同期)ため、マークは framework 由来の削除にしか一致しない。\nconst observerSkipNodes = new WeakSet<Node>();\n\nexport function markObserverSkipOnRemove(node: Node): void {\n observerSkipNodes.add(node);\n}\n\n// マーク済みなら true を返しつつマークを消費する。未マークなら false。\nexport function consumeObserverSkipOnRemove(node: Node): boolean {\n if (!observerSkipNodes.has(node)) {\n return false;\n }\n observerSkipNodes.delete(node);\n return true;\n}\n\n// framework 自身がマウント(Content.appendTo / mountAfter)したノード。\n// 追加サブツリー走査の実質の仕事は connect-snapshot 待ち(observationPending)の\n// record への配送だけで、record 自体は同期マウント(activateContent → start)で\n// observer flush より先に active 済み。よって待ちがグローバルに 1 つも無ければ\n// 追加側走査も冗長であり丸ごとスキップできる(削除側スキップの対称形)。\n// マーク〜配送が単一 microtask で外部変異が割り込めない前提も削除側と同じ。\n// framework の削除を親ごとの件数で数える(1 つの mutation record がその件数の子をまとめて消したとき、\n// 削除ノードごとの WeakSet 印の代わりに 1 回の判定で飛ばせる)\nconst skipRemovedChildrenByParent = new WeakMap<Node, number>();\n\nexport function markObserverSkipRemovedChildren(parent: Node, count: number): void {\n skipRemovedChildrenByParent.set(parent, (skipRemovedChildrenByParent.get(parent) ?? 0) + count);\n}\n\n/** Consumes `count` framework removals of `parent`; false (and nothing consumed) when the count does not cover them. */\nexport function consumeObserverSkipRemovedChildren(parent: Node, count: number): boolean {\n const pending = skipRemovedChildrenByParent.get(parent);\n if (typeof pending === \"undefined\" || pending < count) {\n return false;\n }\n if (pending === count) {\n skipRemovedChildrenByParent.delete(parent);\n } else {\n skipRemovedChildrenByParent.set(parent, pending - count);\n }\n return true;\n}\n\nconst observerSkipAddedNodes = new WeakSet<Node>();\n\nexport function markObserverSkipOnAdd(node: Node): void {\n observerSkipAddedNodes.add(node);\n}\n\n// マーク済みなら true を返しつつマークを消費する(削除側と同じ one-shot 契約)。\nexport function consumeObserverSkipOnAdd(node: Node): boolean {\n if (!observerSkipAddedNodes.has(node)) {\n return false;\n }\n observerSkipAddedNodes.delete(node);\n return true;\n}\n\n// connect-snapshot 待ち(two-way sync=connect で未接続のまま activate された record)の\n// グローバル件数。> 0 の間は追加側スキップを無効化して従来走査に戻す。\n// increment は settleInitialRecord、decrement は readProducerSnapshot(消化時)と\n// runTeardowns(未消化のまま終端した record のリーク防止)が担う。\nlet pendingObservationCount = 0;\n\nexport function incrementPendingObservation(): void {\n pendingObservationCount++;\n}\n\nexport function decrementPendingObservation(): void {\n pendingObservationCount--;\n}\n\nexport function hasPendingObservation(): boolean {\n return pendingObservationCount > 0;\n}\n","import { ICustomElementRegistryAdapter } from \"../platform/customElementRegistry\";\n\ninterface IDefinitionWaiter {\n active: boolean;\n readonly resolve: () => void;\n readonly reject: (error: unknown) => void;\n}\n\ninterface IDefinitionEntry {\n readonly waiters: Set<IDefinitionWaiter>;\n}\n\n/**\n * Shares one CustomElementRegistry.whenDefined() continuation per registry/tag.\n * Waiters can be removed independently, so a never-defined tag does not retain\n * binding records or their DOM nodes after teardown.\n */\nexport class DefinitionCoordinator {\n private readonly entries = new Map<string, IDefinitionEntry>();\n\n constructor(private readonly registry: ICustomElementRegistryAdapter) {}\n\n wait(\n tagName: string,\n resolve: () => void,\n reject: (error: unknown) => void = () => undefined,\n ): () => void {\n const normalizedTagName = tagName.toLowerCase();\n let entry = this.entries.get(normalizedTagName);\n if (typeof entry === \"undefined\") {\n entry = { waiters: new Set() };\n this.entries.set(normalizedTagName, entry);\n this.registry.whenDefined(normalizedTagName).then(\n () => this.settle(normalizedTagName, null),\n (error: unknown) => this.settle(normalizedTagName, error),\n );\n }\n\n const waiter: IDefinitionWaiter = { active: true, resolve, reject };\n entry.waiters.add(waiter);\n return () => {\n if (!waiter.active) return;\n waiter.active = false;\n entry?.waiters.delete(waiter);\n };\n }\n\n pendingCount(tagName: string): number {\n return this.entries.get(tagName.toLowerCase())?.waiters.size ?? 0;\n }\n\n private settle(tagName: string, error: unknown): void {\n const entry = this.entries.get(tagName);\n if (typeof entry === \"undefined\") return;\n this.entries.delete(tagName);\n const waiters = Array.from(entry.waiters);\n entry.waiters.clear();\n for (const waiter of waiters) {\n if (!waiter.active) continue;\n waiter.active = false;\n if (error === null) waiter.resolve();\n else waiter.reject(error);\n }\n }\n}\n\nconst coordinatorByRegistry = new WeakMap<ICustomElementRegistryAdapter, DefinitionCoordinator>();\n\nexport function getDefinitionCoordinator(\n registry: ICustomElementRegistryAdapter,\n): DefinitionCoordinator {\n let coordinator = coordinatorByRegistry.get(registry);\n if (typeof coordinator === \"undefined\") {\n coordinator = new DefinitionCoordinator(registry);\n coordinatorByRegistry.set(registry, coordinator);\n }\n return coordinator;\n}\n","import { getStateAddressByBindingInfo } from \"../binding/getStateAddressByBindingInfo\";\nimport { config } from \"../config\";\nimport { COMMAND_NAMESPACE, MODIFIER_KEY_INIT, MODIFIER_KEY_SYNC } from \"../define\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { hasByAddressSymbol, setLoopContextSymbol } from \"../proxy/symbols\";\nimport { readBindableDeclaration } from \"../protocol/wcBindableReader\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo } from \"../types\";\n\nexport type InitialAuthority = \"state\" | \"element\" | \"auto\" | \"none\";\nexport type ResolvedInitialAuthority = Exclude<InitialAuthority, \"auto\">;\nexport type InitialSyncOn = \"call\" | \"connect\";\n\nexport interface IInitialSyncPolicy {\n readonly authority: InitialAuthority;\n readonly syncOn: InitialSyncOn;\n readonly observable: boolean;\n /**\n * wcBindable 宣言が properties のみ(output-only member)であること。\n * authority は初期同期のみを支配する(docs/architecture-hardening/09 §3.6)が、\n * output-only member への state→element 書き込みは初期に限らず契約として\n * 恒久ブロックする。その判定を authority と分離してここに持つ。\n */\n readonly outputOnly: boolean;\n}\n\nfunction readOption(\n binding: IBindingInfo,\n key: \"init\" | \"sync\",\n): string | null {\n let result: string | null = null;\n for (const modifier of binding.propModifiers) {\n const separator = modifier.indexOf(\"=\");\n if (separator < 0) continue;\n const modifierKey = modifier.slice(0, separator).trim();\n const value = modifier.slice(separator + 1).trim();\n if (modifierKey !== MODIFIER_KEY_INIT && modifierKey !== MODIFIER_KEY_SYNC) {\n raiseError(`Unknown binding modifier \"${modifierKey}\" in \"${modifier}\".`);\n }\n if (modifierKey !== key) continue;\n if (result !== null) {\n raiseError(`Binding modifier \"${key}\" may only be specified once.`);\n }\n result = value;\n }\n return result;\n}\n\nfunction parseAuthority(value: string | null): InitialAuthority | null {\n if (value === null) return null;\n if (value === \"state\" || value === \"element\" || value === \"auto\" || value === \"none\") {\n return value;\n }\n return raiseError(`Invalid init modifier value \"${value}\".`);\n}\n\nfunction parseSyncOn(value: string | null): InitialSyncOn {\n if (value === null || value === \"call\") return \"call\";\n if (value === \"connect\") return \"connect\";\n return raiseError(`Invalid sync modifier value \"${value}\".`);\n}\n\nexport function hasInitialSyncModifier(binding: IBindingInfo): boolean {\n return binding.propModifiers.some((modifier) => modifier.includes(\"=\"));\n}\n\n// 頻出ポリシー(修飾子なしの通常バインディング)の凍結シングルトン。リスト行では\n// binding ごとに resolveInitialSyncPolicy が走るため、毎回のオブジェクト割り当てを\n// 避ける(record.initialPolicy は読み取り専用でしか使われない)。\nconst STATE_CALL_POLICY: IInitialSyncPolicy = Object.freeze({ authority: \"state\", syncOn: \"call\", observable: false, outputOnly: false });\nconst NONE_CALL_POLICY: IInitialSyncPolicy = Object.freeze({ authority: \"none\", syncOn: \"call\", observable: false, outputOnly: false });\n\nfunction statePolicy(authority: InitialAuthority, syncOn: IInitialSyncPolicy[\"syncOn\"]): IInitialSyncPolicy {\n if (authority === \"state\" && syncOn === \"call\") return STATE_CALL_POLICY;\n return { authority, syncOn, observable: false, outputOnly: false };\n}\n\nexport function resolveInitialSyncPolicy(binding: IBindingInfo): IInitialSyncPolicy {\n if (!config.enableDirectionalInitialSync) {\n if (hasInitialSyncModifier(binding)) {\n raiseError(\"init=/sync= modifiers require enableDirectionalInitialSync.\");\n }\n return STATE_CALL_POLICY;\n }\n\n const explicitAuthority = parseAuthority(readOption(binding, MODIFIER_KEY_INIT));\n const syncOn = parseSyncOn(readOption(binding, MODIFIER_KEY_SYNC));\n if (binding.bindingType === \"event\") {\n if (explicitAuthority !== null && explicitAuthority !== \"none\") {\n raiseError(\"Event bindings only allow init=none.\");\n }\n return syncOn === \"call\" ? NONE_CALL_POLICY : { authority: \"none\", syncOn, observable: false, outputOnly: false };\n }\n // command.<name>: $command.<method> は命令的な command-token 配線。bindingType は\n // \"prop\" だが propName (\"command.<name>\") は wcBindable property ではないため、下の\n // property authority 検証(未宣言なら raiseError)に掛けてはならない。値の初期同期を\n // 持たない配線なので、現行互換の \"state\" authority を返す(command token は従来通り\n // 初期 apply で配線される)。\n if (binding.propSegments[0] === COMMAND_NAMESPACE) {\n return statePolicy(\"state\", syncOn);\n }\n if (binding.bindingType !== \"prop\") {\n if (explicitAuthority !== null && explicitAuthority !== \"state\" && explicitAuthority !== \"none\") {\n raiseError(`Binding type \"${binding.bindingType}\" does not support init=${explicitAuthority}.`);\n }\n return statePolicy(explicitAuthority ?? \"state\", syncOn);\n }\n\n const declaration = readBindableDeclaration(binding.node);\n if (declaration === null) {\n return statePolicy(explicitAuthority ?? \"state\", syncOn);\n }\n const hasOutput = declaration.knownProperties.has(binding.propName);\n const hasInput = declaration.declaredInputs.has(binding.propName);\n if (!hasOutput && !hasInput) {\n raiseError(`Property \"${binding.propName}\" is not declared by wcBindable.`);\n }\n\n const allowed = hasOutput && hasInput\n ? new Set<InitialAuthority>([\"state\", \"element\", \"auto\", \"none\"])\n : hasOutput\n ? new Set<InitialAuthority>([\"element\", \"none\"])\n : new Set<InitialAuthority>([\"state\", \"none\"]);\n const defaultAuthority: InitialAuthority = hasOutput && !hasInput ? \"element\" : \"state\";\n const authority = explicitAuthority ?? defaultAuthority;\n if (!allowed.has(authority)) {\n raiseError(`init=${authority} is incompatible with wcBindable member \"${binding.propName}\".`);\n }\n if (syncOn === \"connect\" && !hasOutput) {\n raiseError(`sync=connect requires observable property \"${binding.propName}\".`);\n }\n return { authority, syncOn, observable: hasOutput, outputOnly: hasOutput && !hasInput };\n}\n\nexport function isBindingStateInitialized(binding: IBindingInfo): boolean {\n const rootNode = binding.replaceNode.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n const address = getStateAddressByBindingInfo(binding);\n let initialized = false;\n stateElement.createState(\"readonly\", (state) => {\n initialized = state[hasByAddressSymbol](address);\n });\n return initialized;\n}\n\nexport function resolveInitialAuthority(\n binding: IBindingInfo,\n authority: InitialAuthority,\n): ResolvedInitialAuthority {\n if (authority !== \"auto\") return authority;\n return isBindingStateInitialized(binding) ? \"state\" : \"element\";\n}\n\nexport function commitProducerValue(binding: IBindingInfo, value: unknown): void {\n let filteredValue = value;\n for (const filter of binding.inFilters) {\n filteredValue = filter.filterFn(filteredValue);\n }\n const rootNode = binding.node.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for initial binding sync.`);\n }\n const loopContext = getLoopContextByNode(binding.node);\n stateElement.createState(\"writable\", (state) => {\n state[setLoopContextSymbol](loopContext, () => {\n state[binding.statePathName] = filteredValue;\n });\n });\n}\n","import { applyChangeFromBindings } from \"../apply/applyChangeFromBindings\";\nimport { EVENT_TOKEN_NAMESPACE, MODIFIER_READONLY } from \"../define\";\nimport { IAbsoluteStateAddress } from \"../address/types\";\nimport { getTreePath } from \"../address/TreePath\";\nimport { ITreePath } from \"../address/types\";\nimport { clearAbsoluteStateAddressByBinding, getAbsoluteStateAddressByBinding, resolveBindingRootNode } from \"../binding/getAbsoluteStateAddressByBinding\";\nimport { addBindingByAbsoluteStateAddress, addBindingByPattern, removeBindingByAbsoluteStateAddress, removeBindingByPattern } from \"../binding/getBindingSetByAbsoluteStateAddress\";\nimport { getListIndexByBindingInfo } from \"../list/getListIndexByBindingInfo\";\nimport { getLastListValueByAbsoluteStateAddress, hasLastListValueByAbsoluteStateAddress, setLastListValueByAbsoluteStateAddress } from \"../list/lastListValueByAbsoluteStateAddress\";\nimport { getStateListBaseline, hasStateListBaseline, setStateListBaseline } from \"../list/stateListBaseline\";\nimport { IListIndex } from \"../list/types\";\nimport { clearStateAddressByBindingInfo } from \"../binding/getStateAddressByBindingInfo\";\nimport { config } from \"../config\";\nimport { detachCheckboxEventHandler, attachCheckboxEventHandler } from \"../event/checkboxHandler\";\nimport { detachEventTokenHandler, attachEventTokenHandler } from \"../event/eventTokenHandler\";\nimport { detachEventHandler, attachEventHandler } from \"../event/handler\";\nimport { detachRadioEventHandler, attachRadioEventHandler } from \"../event/radioHandler\";\nimport { detachTwowayEventHandler, attachTwowayEventHandler, addTwowayValueObserver } from \"../event/twowayHandler\";\nimport { isPossibleTwoWay } from \"../event/isPossibleTwoWay\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry, upgradeCustomElement } from \"../platform/customElementRegistry\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IBindingInfo } from \"../types\";\nimport { consumeObserverSkipOnAdd, consumeObserverSkipOnRemove, consumeObserverSkipRemovedChildren, decrementPendingObservation, hasPendingObservation, incrementPendingObservation } from \"./observerSkip\";\nimport { DefinitionCoordinator, getDefinitionCoordinator } from \"./DefinitionCoordinator\";\nimport { commitProducerValue, hasInitialSyncModifier, IInitialSyncPolicy, ResolvedInitialAuthority, resolveInitialAuthority, resolveInitialSyncPolicy } from \"./initialSync\";\nimport { replaceToReplaceNode } from \"./replaceToReplaceNode\";\nimport type { IRowPlan } from \"../structural/types\";\n\nexport type BindingPhase =\n | \"discovered\"\n | \"waiting-definition\"\n | \"ready-to-attach\"\n | \"attaching\"\n | \"synchronizing\"\n | \"active\"\n | \"failed\"\n | \"disposed\";\n\nexport interface IBindingRecord {\n readonly id: number;\n readonly info: IBindingInfo;\n readonly generation: number;\n phase: BindingPhase;\n /**\n * 追加の後始末クロージャ(radio/checkbox/observer/定義キャンセル等の希少ケース)。\n * 頻出の後始末(イベント detach・双方向 detach・アドレス台帳解除)はクロージャで\n * なく record のフラグ/フィールドから runTeardowns がデータ駆動で実行するため、\n * 大多数の record では null のまま(行あたり Set×5 + クロージャ×10 の割当を排除)。\n */\n teardowns: Set<() => void> | null;\n}\n\ninterface IBindingOptions {\n registerAddress: boolean;\n registerPathInfo: boolean;\n applyOnReconnect: boolean;\n}\n\ninterface IInternalBindingRecord extends IBindingRecord {\n /**\n * generation はプラン行のプール再利用(record オブジェクト再利用)で更新するため\n * 内部表現では書き込み可能にする(IBindingRecord 公開面は readonly のまま)\n */\n generation: number;\n readonly session: BindingSession;\n readonly anchor: Node;\n readonly options: IBindingOptions;\n address: IAbsoluteStateAddress | null;\n /**\n * パターン索引台帳((absolutePathInfo, listIndex) 2 段キー)への登録。リスト行の\n * binding は address を intern せずこちらに登録する。address とは排他。\n */\n patternPathInfo: ITreePath | null;\n patternListIndex: IListIndex | null;\n pendingDefinitions: number;\n initialPolicy: IInitialSyncPolicy | null;\n resolvedAuthority: ResolvedInitialAuthority | null;\n initialSettled: boolean;\n /**\n * 最初の shouldApplyState 相談(= 初期 state sweep / 初回 render の選別)を\n * 消費済みか。authority は初期同期のみを支配する(09 §3.6)ため、初回相談は\n * authority で答え、以降の定常 apply は output-only 契約と connect-snapshot\n * 未解決だけをブロックする。\n */\n initialApplyDone: boolean;\n /** initialPolicy.outputOnly のミラー(settle 時確定・定常ゲートの分岐を総域にする) */\n outputOnlyMember: boolean;\n observationPending: boolean;\n eventSequence: number;\n hasProducerValue: boolean;\n producerValue: unknown;\n /** attachEventHandler 済み(dispose 時に detachEventHandler をデータ駆動実行) */\n eventAttached: boolean;\n /** attachTwowayEventHandler 済み(dispose 時に detachTwowayEventHandler をデータ駆動実行) */\n twowayAttached: boolean;\n}\n\ninterface IDeferredDefinition {\n readonly node: Node;\n active: boolean;\n cancel: (() => void) | null;\n}\n\ninterface IObservableRoot extends Node {\n contains(other: Node | null): boolean;\n}\n\nlet nextRecordId = 0;\nlet nextGeneration = 0;\n\n// プラン行の帳簿は束縛ごとの record ではなく行に 1 つの record(slot 配列)で持つ\n// (行ランタイム設計 R3)。phase は slot ごとの SLOT_*、フラグは FLAG_* のビット。\nconst SLOT_ACTIVE = 0;\nconst SLOT_DISPOSED = 1;\nconst SLOT_FAILED = 2;\nconst FLAG_INITIAL_APPLY_DONE = 1;\nconst FLAG_EVENT_ATTACHED = 2;\nconst SLOT_PHASE_NAMES: readonly BindingPhase[] = [\"active\", \"disposed\", \"failed\"];\ninterface IRowRecord {\n readonly id: number;\n /** この行を持つ共有 session(行 → session の逆引き。設計 R3) */\n readonly session: BindingSession;\n generation: number;\n readonly plan: IRowPlan;\n readonly bindings: readonly IBindingInfo[];\n /** activate が address 登録を昇格したか(従来の record.options.registerAddress に相当、行で共有) */\n registered: boolean;\n /** SLOT_* per slot */\n readonly phases: number[];\n /** FLAG_* bits per slot */\n readonly flags: number[];\n readonly addresses: (IAbsoluteStateAddress | null)[];\n readonly patternPathInfos: (ITreePath | null)[];\n readonly patternListIndexes: (IListIndex | null)[];\n}\n// 束縛 → その行の record(record が共有 session を知っている。設計 R3)\nconst rowByBinding = new WeakMap<IBindingInfo, IRowRecord>();\n\nconst recordByBinding = new WeakMap<IBindingInfo, IInternalBindingRecord>();\nconst sessionByRoot = new WeakMap<Node, BindingSession>();\n\n// binding の構造キーは不変フィールドのみから決まる。リスト行の初期化では同一 binding に\n// 対し remember() が2回呼ばれる(createContent 内 initializeBindingsByFragment と\n// activateContent の registerAddress 目的の initialize)ため、2度目の文字列生成を避けるべく\n// binding 単位でメモ化する。プロファイル上 bindingKey は create-10k の JS 自己時間で上位。\nconst bindingKeyByBinding = new WeakMap<IBindingInfo, string>();\n\n// node → その node に関心を持つ session(anchor として binding を覚えている、\n// または定義待ちタスクを抱えている)。BindingOwner は mutation で増減した\n// サブツリーを1回だけ走査し、ここに登録された session だけへ per-node 配送する。\n// 全 session ブロードキャストだと、リスト行の逐次 append などで\n// 「session 数 × 変異ノード数」の O(n²) ファンアウトになるため、その正本台帳。\n// 大多数の node は関心 session が1つなので単一値で持ち、2つ目から Set に昇格する。\nconst interestedSessionsByNode = new WeakMap<Node, BindingSession | Set<BindingSession>>();\n\nfunction addInterestedSession(node: Node, session: BindingSession): void {\n const current = interestedSessionsByNode.get(node);\n if (typeof current === \"undefined\") {\n interestedSessionsByNode.set(node, session);\n return;\n }\n if (current === session) return;\n if (current instanceof Set) {\n current.add(session);\n return;\n }\n interestedSessionsByNode.set(node, new Set([current, session]));\n}\n\n/**\n * このノードに既にバインドが張られているか。\n *\n * binder プロトコル(`bind()`)の冪等判定に使う。`remember` が binding ごとに\n * `addInterestedSession(binding.replaceNode, …)` を呼ぶので、バインド済みノードは\n * 必ずこの台帳に載っている。新しい台帳を足さずに済むぶん、二重管理の齟齬が無い。\n */\nexport function hasInterestedSession(node: Node): boolean {\n return interestedSessionsByNode.has(node);\n}\n\nfunction forEachInterestedSession(node: Node, callback: (session: BindingSession) => void): void {\n const current = interestedSessionsByNode.get(node);\n if (typeof current === \"undefined\") return;\n if (current instanceof Set) {\n for (const session of Array.from(current)) callback(session);\n return;\n }\n callback(current);\n}\n\nfunction forEachInclusive(root: Node, callback: (node: Node) => void): void {\n callback(root);\n // 葉ノード(fragment 一括挿入時のテキスト・空セル等が大多数)では\n // Array.from(childNodes) の空配列アロケーションを避ける。callback が子を\n // 追加しうるため firstChild は callback 後に判定する(従来と同一意味論)。\n if (root.firstChild === null) return;\n for (const child of Array.from(root.childNodes)) {\n forEachInclusive(child, callback);\n }\n}\n\nfunction isObservableRoot(value: unknown): value is IObservableRoot {\n if (typeof value !== \"object\" || value === null) return false;\n const node = value as Node;\n return node.nodeType === 9 || (node.nodeType === 11 && \"host\" in (node as object));\n}\n\nfunction observableRootFor(node: Node): IObservableRoot | null {\n const root = node.getRootNode();\n return isObservableRoot(root) ? root : null;\n}\n\nclass BindingOwner {\n private readonly observer: MutationObserver | null;\n\n constructor(readonly root: IObservableRoot) {\n const Observer = (globalThis as { MutationObserver?: typeof MutationObserver }).MutationObserver;\n this.observer = typeof Observer === \"function\"\n ? new Observer((mutations) => this.handleMutations(mutations))\n : null;\n this.observer?.observe(root, { childList: true, subtree: true });\n }\n\n private handleMutations(mutations: MutationRecord[]): void {\n const removed: Node[] = [];\n const added: Node[] = [];\n for (let m = 0; m < mutations.length; m++) {\n const mutation = mutations[m];\n const removedNodes = mutation.removedNodes;\n // 削除された子がすべて framework の削除(消去が親に件数で印を付けた)なら record ごと飛ばし、\n // ノードごとの印には触れない\n if (removedNodes.length === 0 || !consumeObserverSkipRemovedChildren(mutation.target, removedNodes.length)) {\n for (let i = 0; i < removedNodes.length; i++) removed.push(removedNodes[i]);\n }\n const addedNodes = mutation.addedNodes;\n for (let i = 0; i < addedNodes.length; i++) added.push(addedNodes[i]);\n }\n // 走査は owner が1回だけ行い、関心 session が居る node だけを配送・contains\n // 検査へ進める。contains は O(木の深さ) なので、関心の無い node で呼ばない。\n const reconnected: IBindingInfo[] = [];\n for (const subtree of removed) {\n // framework が unmount した削除サブツリーは binding を明示 dispose 済みなので\n // observer 側の冗長走査(forEachInclusive で全 node を歩き handleRemovedNode を\n // 呼ぶ)を丸ごとスキップする。clear/大量 delete のホットスポット短縮。\n if (consumeObserverSkipOnRemove(subtree)) continue;\n forEachInclusive(subtree, (node) => {\n forEachInterestedSession(node, (session) => {\n if (this.root.contains(node)) return;\n session.handleRemovedNode(node);\n });\n });\n }\n for (const subtree of added) {\n // framework がマウントしたサブツリーは record が同期 activate 済みで、追加側\n // 走査の実質の仕事は connect-snapshot 待ちへの配送だけ。待ちがグローバルに\n // 無ければ丸ごとスキップする(待ちがあればマークだけ消費して従来走査に戻す)。\n if (consumeObserverSkipOnAdd(subtree) && !hasPendingObservation()) continue;\n forEachInclusive(subtree, (node) => {\n forEachInterestedSession(node, (session) => {\n if (!this.root.contains(node)) return;\n session.handleAddedNode(node, reconnected);\n });\n });\n }\n if (reconnected.length > 0) applyChangeFromBindings(reconnected);\n }\n}\n\nconst ownerByRoot = new WeakMap<IObservableRoot, BindingOwner>();\n\nfunction getBindingOwner(root: IObservableRoot): BindingOwner {\n let owner = ownerByRoot.get(root);\n if (typeof owner === \"undefined\") {\n owner = new BindingOwner(root);\n ownerByRoot.set(root, owner);\n }\n return owner;\n}\n\nfunction bindingKey(binding: IBindingInfo): string {\n const inFilters = binding.inFilters.map((filter) => `${filter.filterName}(${filter.args.join(\",\")})`).join(\"|\");\n const outFilters = binding.outFilters.map((filter) => `${filter.filterName}(${filter.args.join(\",\")})`).join(\"|\");\n return [\n binding.bindingType,\n binding.propName,\n binding.propModifiers.join(\",\"),\n binding.statePathName,\n inFilters,\n outFilters,\n binding.uuid ?? \"\",\n ].join(\"\\u0000\");\n}\n\n/*\n * 束縛が状態の台帳へ出入りする経路(行ランタイム設計 R4)。行 slot(registerRowSlot /\n * unregisterRowSlot)と record(registerAddress / runTeardowns / rebindAddresses)が同じ登録・\n * 解除をそれぞれ書き写していたのを 1 箇所にした。登録した形(アドレスか、パターンの\n * pathInfo + listIndex か)は呼び出し側の器(行の slot 配列 / record のフィールド)へ書く —\n * ここで値の組を返すと行ごとに割り当てが増えるため、器は呼び出し側に残す。\n */\n\n/** リスト行: (absolutePathInfo, listIndex) のパターン台帳へ入れる(AbsoluteStateAddress の intern を省く) */\nfunction registerPattern(binding: IBindingInfo, listIndex: IListIndex, knownRoot?: Node | null): ITreePath {\n const stateElement = getStateElement(resolveBindingRootNode(binding, knownRoot));\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n const absolutePathInfo = getTreePath(stateElement, binding.statePathInfo);\n addBindingByPattern(absolutePathInfo, listIndex, binding);\n return absolutePathInfo;\n}\n\n/** リスト行でない束縛: 絶対アドレスの台帳へ入れる */\nfunction registerAbsoluteAddress(binding: IBindingInfo, knownRoot?: Node | null): IAbsoluteStateAddress {\n const address = getAbsoluteStateAddressByBinding(binding, knownRoot);\n addBindingByAbsoluteStateAddress(address, binding);\n return address;\n}\n\n/**\n * 台帳から外す。`address` が null ならパターン登録(`pathInfo` + `listIndex`)。相対アドレス\n * (getValue)と絶対アドレス(applyChangeToFor / updatedCallback 経由の遅延 intern)のメモは\n * パターン登録でも作られうるので、どちらでも対称にクリアする。\n */\nfunction unregisterFromLedger(\n binding: IBindingInfo,\n address: IAbsoluteStateAddress | null,\n pathInfo: ITreePath | null,\n listIndex: IListIndex | null,\n): void {\n if (address !== null) {\n removeBindingByAbsoluteStateAddress(address, binding);\n } else {\n removeBindingByPattern(pathInfo!, listIndex!, binding);\n }\n clearStateAddressByBindingInfo(binding);\n clearAbsoluteStateAddressByBinding(binding);\n}\n\nfunction addRecordTeardown(record: IInternalBindingRecord, teardown: () => void): void {\n if (record.teardowns === null) {\n record.teardowns = new Set();\n }\n record.teardowns.add(teardown);\n}\n\nexport class BindingSession {\n private readonly records = new Set<IInternalBindingRecord>();\n /**\n * initializeRow で設定される行プラン。非 null のとき activate は\n * スロット整列の高速経路(activatePlanRows)を使う。\n */\n private rowPlan: IRowPlan | null = null;\n /** この session が持つ生きている行(`for` 束縛 1 つにつき session 1 つ、行は複数。設計 R3) */\n private readonly rows = new Set<IRowRecord>();\n // anchor ノードが持つ binding は大多数が 1 本なので単一値で持ち、2 本目から\n // Map(remember 経路のキー照合用)に昇格する(台帳・興味 session と同じ前例)\n private readonly knownBindingsByNode = new WeakMap<Node, IBindingInfo | Map<string, IBindingInfo>>();\n private readonly optionsByBinding = new WeakMap<IBindingInfo, IBindingOptions>();\n private readonly deferredByNode = new WeakMap<Node, Set<IDeferredDefinition>>();\n private readonly deferred = new Set<IDeferredDefinition>();\n\n constructor(root: Node | null = null) {\n if (root !== null) this.observe(root);\n }\n\n /**\n * knownRoot: 呼び出し側が root を確定済みのときの per-binding observe 省略。\n * - undefined: 従来どおり binding ごとに anchor から root を導出して observe\n * - null: detached fragment 上(createContent)の初期化。observableRootFor が\n * 必ず null を返す状況なので observe(= getRootNode)を丸ごと省略する\n * - Node: 呼び出し側で owner 保証済み(activate 経由のみ。initialize へは未使用)\n */\n initialize(\n bindings: readonly IBindingInfo[],\n options: Partial<IBindingOptions> = {},\n knownRoot?: Node | null,\n ): IBindingInfo[] {\n const registerAddress = options.registerAddress ?? true;\n const resolvedOptions: IBindingOptions = {\n registerAddress,\n registerPathInfo: options.registerPathInfo ?? registerAddress,\n applyOnReconnect: options.applyOnReconnect ?? true,\n };\n const initialized: IBindingInfo[] = [];\n for (const candidate of bindings) {\n const binding = this.remember(candidate, resolvedOptions);\n const rowRecord = this.rowOf(binding);\n const rowSlot = rowRecord === null ? -1 : rowRecord.bindings.indexOf(binding);\n if (rowRecord !== null && rowRecord.phases[rowSlot] === SLOT_ACTIVE) {\n const row = rowRecord;\n this.observe(binding.replaceNode);\n if (resolvedOptions.registerAddress && row.addresses[rowSlot] === null && row.patternPathInfos[rowSlot] === null) {\n row.registered = true;\n this.registerRowSlot(row, rowSlot);\n }\n continue;\n }\n const existing = recordByBinding.get(binding);\n if (typeof existing !== \"undefined\" && existing.phase !== \"disposed\" && existing.phase !== \"failed\") {\n this.observe(existing.anchor);\n if (resolvedOptions.registerAddress && existing.address === null && existing.patternListIndex === null) {\n existing.options.registerAddress = true;\n this.registerAddress(existing);\n }\n if (existing.phase === \"active\") this.settleInitialRecord(existing);\n this.settleConnectedSnapshot(existing);\n continue;\n }\n this.start(binding, resolvedOptions, knownRoot);\n initialized.push(binding);\n }\n return initialized.filter((binding) => this.shouldApplyState(binding));\n }\n\n /**\n * activateContent 専用の再活性化パス。createContent 側の initialize で\n * remember 済みの binding 配列(bindingsByContent がそのまま保持する同一オブジェクト)\n * にだけ使える前提で、remember の再実行(キー照合・options マージ・興味登録)を省き、\n * 必要な仕事だけ行う: 初回活性化はアドレス登録+初期同期、pool 再利用(disposed)は\n * start による再構築、未知の binding は防御的に従来 initialize へ倒す。\n *\n * knownRoot は呼び出し側(applyChangeToFor / applyChangeToIf の apply context)が\n * 確定済みの root。owner(root ごとの MutationObserver)の保証を呼び出しあたり\n * 1 回に集約し、binding ごとの observe(= getRootNode)とアドレス解決の\n * getRootNode を丸ごと省略する。\n */\n activate(bindings: readonly IBindingInfo[], knownRoot: Node): void {\n if (isObservableRoot(knownRoot)) getBindingOwner(knownRoot);\n if (this.rowPlan !== null) {\n this.activatePlanRows(this.rowPlan, bindings, knownRoot);\n return;\n }\n for (const binding of bindings) {\n const record = recordByBinding.get(binding);\n if (typeof record !== \"undefined\" && record.session === this\n && record.phase !== \"disposed\" && record.phase !== \"failed\") {\n if (record.address === null && record.patternListIndex === null) {\n // 初回活性化(owner は冒頭で保証済み)\n record.options.registerAddress = true;\n this.registerAddress(record, knownRoot);\n }\n if (record.phase === \"active\") this.settleInitialRecord(record);\n this.settleConnectedSnapshot(record);\n continue;\n }\n const options = this.optionsByBinding.get(binding);\n if (typeof options === \"undefined\") {\n // この session で remember されていない binding(防御): 従来経路\n this.initialize([binding], { registerAddress: true, registerPathInfo: false, applyOnReconnect: false });\n continue;\n }\n // pool 再利用: record は disposed。活性化要件(アドレス登録)を昇格して再構築\n options.registerAddress = true;\n this.start(binding, options, knownRoot);\n }\n }\n\n shouldApplyState(binding: IBindingInfo): boolean {\n if (!config.enableDirectionalInitialSync) {\n if (hasInitialSyncModifier(binding)) resolveInitialSyncPolicy(binding);\n return true;\n }\n const row = this.rowOf(binding);\n if (row !== null) {\n const slot = row.bindings.indexOf(binding);\n if (slot >= 0) {\n if (!row.registered) return true;\n if (row.phases[slot] === SLOT_FAILED) return false;\n const planSlot = row.plan.slots[slot];\n if ((row.flags[slot] & FLAG_INITIAL_APPLY_DONE) === 0) {\n row.flags[slot] |= FLAG_INITIAL_APPLY_DONE;\n return planSlot.authority === \"state\";\n }\n if (planSlot.authority === \"state\") return true;\n return !planSlot.policy.outputOnly;\n }\n }\n const record = recordByBinding.get(binding);\n if (typeof record === \"undefined\" || record.session !== this) return true;\n if (!record.options.registerAddress || record.phase === \"waiting-definition\") return true;\n if (record.phase === \"failed\") return false;\n if (record.phase === \"active\") this.settleInitialRecord(record);\n // authority は初期同期のみを支配する(09 §3.6: init=element は「snapshot を\n // state へ入れる」、init=none は「次の変更から扱う」)。settle 後の最初の相談\n // = 初期 state sweep / 初回 render / deferred initial apply の選別なので\n // authority で答え、ここで初期適用を消費する。\n if (!record.initialApplyDone) {\n record.initialApplyDone = true;\n return record.resolvedAuthority === \"state\";\n }\n if (record.resolvedAuthority === \"state\") return true;\n // 定常: two-way / input member は authority と無関係に state→element を流す。\n // 恒久ブロックは (1) output-only member の契約(書き込み無意味・DCC/router の\n // conformance が依存)と (2) sync=connect の接続 snapshot が未解決の間\n //(初期競合が未決着のうちは state push が element 初期値を潰しうる)だけ。\n return !record.outputOnlyMember && !record.observationPending;\n }\n\n getRecord(binding: IBindingInfo): IBindingRecord | null {\n const row = this.rowOf(binding);\n const slot = row === null ? -1 : row.bindings.indexOf(binding);\n if (row !== null && slot >= 0) {\n return { id: row.id * 64 + slot, info: binding, generation: row.generation, phase: SLOT_PHASE_NAMES[row.phases[slot]], teardowns: null };\n }\n const record = recordByBinding.get(binding);\n return record?.session === this ? record : null;\n }\n\n /**\n * teardown を足せるのは record を持つ束縛だけ(設計 R3)。唯一の呼び出し元は\n * `scheduleDeferredApply`(未定義カスタム要素への遅延適用)で、プラン行はカスタム要素を\n * 含み得ないため行 slot には来ない。\n */\n addTeardown(binding: IBindingInfo, teardown: () => void): boolean {\n const record = recordByBinding.get(binding);\n if (typeof record === \"undefined\" || !this.isAlive(record, record.generation)) {\n return false;\n }\n addRecordTeardown(record, teardown);\n return true;\n }\n\n deferUntilDefined(\n node: Node,\n tagName: string,\n callback: () => void,\n reject: (error: unknown) => void = () => undefined,\n ): () => void {\n const registry = getCustomElementRegistry(node);\n if (registry === null) {\n raiseError(`CustomElementRegistry is unavailable for <${tagName}>.`);\n }\n this.observe(node);\n addInterestedSession(node, this);\n const task: IDeferredDefinition = { node, active: true, cancel: null };\n let tasks = this.deferredByNode.get(node);\n if (typeof tasks === \"undefined\") {\n tasks = new Set();\n this.deferredByNode.set(node, tasks);\n }\n tasks.add(task);\n this.deferred.add(task);\n const finish = (): boolean => {\n if (!task.active) return false;\n task.active = false;\n tasks?.delete(task);\n this.deferred.delete(task);\n return true;\n };\n task.cancel = getDefinitionCoordinator(registry).wait(\n tagName,\n () => {\n if (!finish()) return;\n try {\n upgradeCustomElement(registry, node);\n callback();\n } catch (error) {\n reject(error);\n }\n },\n (error) => {\n if (!finish()) return;\n reject(error);\n },\n );\n return () => {\n if (!finish()) return;\n task.cancel?.();\n };\n }\n\n disposeBinding(binding: IBindingInfo): void {\n const row = this.rowOf(binding);\n if (row !== null) {\n const slot = row.bindings.indexOf(binding);\n if (slot >= 0) {\n this.disposeRowSlot(row, slot);\n return;\n }\n }\n const record = recordByBinding.get(binding);\n if (typeof record === \"undefined\" || record.session !== this) return;\n this.disposeRecord(record);\n }\n\n /** 行の session か(`for` 束縛ごとに 1 つを全行で共有する形。設計 R3) */\n get isRowSession(): boolean {\n return this.rowPlan !== null;\n }\n\n get currentRowPlan(): IRowPlan | null {\n return this.rowPlan;\n }\n\n /**\n * 共有 session の行単位の解体(設計 R3)。この content の行だけを解体する。\n *\n * 生きている行が 1 つも無くなったら、行ごと session だった頃の `dispose()` と同じく\n * 残っている定義待ち(`deferUntilDefined`)を取り消す。プラン行そのものは未定義要素を\n * 持てない(`compileRowPlan` がカスタム要素のテンプレートを不適格にする)が、\n * この session に注入された待ちが残ると閉包が強参照で残り続ける。\n */\n disposeBindings(bindings: readonly IBindingInfo[]): void {\n for (let i = 0; i < bindings.length; i++) {\n this.disposeBinding(bindings[i]);\n }\n if (this.rows.size > 0) {\n return;\n }\n for (const task of Array.from(this.deferred)) {\n task.active = false;\n task.cancel?.();\n this.deferred.delete(task);\n this.deferredByNode.get(task.node)?.delete(task);\n }\n }\n\n /** 行単位の wholesale destroy(設計 R3)。行を持たない session は従来どおり全部を捨てる */\n destroyRow(bindings: readonly IBindingInfo[]): void {\n const row = bindings.length > 0 ? this.rowOf(bindings[0]) : null;\n if (row === null) {\n this.destroyRecords();\n return;\n }\n this.destroyRowRecord(row);\n this.rows.delete(row);\n }\n\n private destroyRowRecord(row: IRowRecord): void {\n for (let i = 0; i < row.bindings.length; i++) {\n const address = row.addresses[i];\n if (address !== null) {\n removeBindingByAbsoluteStateAddress(address, row.bindings[i]);\n row.addresses[i] = null;\n }\n row.phases[i] = SLOT_DISPOSED;\n }\n }\n\n dispose(): void {\n for (const row of Array.from(this.rows)) {\n for (let i = 0; i < row.bindings.length; i++) this.disposeRowSlot(row, i);\n }\n for (const record of Array.from(this.records)) this.disposeRecord(record);\n for (const task of Array.from(this.deferred)) {\n task.active = false;\n task.cancel?.();\n this.deferred.delete(task);\n this.deferredByNode.get(task.node)?.delete(task);\n }\n }\n\n /**\n * wholesale destroy(全行クリアで teardown を GC に任せる高速経路)を適用して\n * よいか。定義待ち(DefinitionCoordinator の waiter / deferred spread タスク)は\n * 強参照 Map に閉包が残り、connect-snapshot 待ちは pending カウンタが戻らなく\n * なるため、1 つでもあれば従来経路(teardown 実行)に倒す。\n */\n canWholesaleDestroy(): boolean {\n if (this.deferred.size > 0) return false;\n if (this.records.size === 0) return true; // 空の Set の反復も割り当てるので先に抜ける\n for (const record of this.records) {\n if (record.pendingDefinitions > 0 || record.observationPending) return false;\n }\n return true;\n }\n\n /**\n * 全 record を teardown を走らせずに終端化する(canWholesaleDestroy が true の\n * content 専用)。イベント listener・loopContext・パターン台帳(listIndex キー)は\n * ノード/binding もろとも GC で崩壊する(recordByBinding 以下は全て弱参照)。\n * 例外は null-listIndex の従来台帳(record.address): キーの intern 済み\n * AbsoluteStateAddress が PathInfo キャッシュ経由で生涯生存するため GC で\n * 崩壊せず、共有エントリに残った binding が binding.node 経由で行 DOM 全体を\n * 永久リークする。ここだけ明示除去する(行イベント binding が典型で行あたり\n * 高々数件・Set.delete のみなので wholesale の速度特性は保たれる)。\n * handlerBindingRegistry のカウンタは減らないが、残るのはキー文字列と数値のみで\n * 実害はない設計(handlerBindingRegistry.ts の弱参照化コメント参照)。\n */\n destroyRecords(): void {\n for (const row of this.rows) this.destroyRowRecord(row);\n this.rows.clear();\n for (const record of this.records) {\n if (record.address !== null) {\n removeBindingByAbsoluteStateAddress(record.address, record.info);\n record.address = null;\n }\n record.phase = \"disposed\";\n record.teardowns = null;\n }\n this.records.clear();\n }\n\n /**\n * マウントスコープ専用(Phase 2・webComponent/mountScope.ts): 全 record の台帳登録を\n * **現在のループ文脈の listIndex** で張り直す。行 content のプール再利用でコンポーネント\n * 要素が別の行に付け替わると、スコープの binding は旧行の listIndex で台帳に載ったままに\n * なる — その 1 点だけを直す(listener・record・依存グラフは張り直し不要)。\n *\n * `for` binding は lastListValue(差分の基準)を旧アドレスから新アドレスへ引き継ぐ。\n * 引き継がないと再適用が全行 add と誤認し、旧行の DOM が残ったまま新行を重ねて\n * マウントする。戻り値は再適用すべき binding(呼び出し側が applyChangeFromBindings する)。\n */\n /**\n * マウントスコープ再接続専用: アクティブな record の binding ノード(text は差し替え前の\n * comment — ループ文脈の直接エントリはこのノードに載る)を列挙する。\n * remountScopeBindings が現在の行の文脈へ張り替えるために使う。\n */\n forEachActiveBindingNode(callback: (node: Node) => void): void {\n for (const row of this.rows) {\n for (let i = 0; i < row.bindings.length; i++) {\n if (row.phases[i] === SLOT_ACTIVE) callback(row.bindings[i].node);\n }\n }\n for (const record of this.records) {\n if (record.phase !== \"active\") continue;\n callback(record.info.node);\n }\n }\n\n rebindAddresses(): IBindingInfo[] {\n const rebound: IBindingInfo[] = [];\n for (const row of this.rows) {\n for (let i = 0; i < row.bindings.length; i++) {\n if (row.phases[i] !== SLOT_ACTIVE) continue;\n if (row.addresses[i] === null && row.patternPathInfos[i] === null) continue;\n const binding = row.bindings[i];\n this.unregisterRowSlot(row, i);\n this.registerRowSlot(row, i);\n if (this.shouldApplyState(binding)) rebound.push(binding);\n }\n }\n for (const record of this.records) {\n if (record.phase !== \"active\") continue;\n const binding = record.info;\n if (record.address === null && record.patternListIndex === null) continue;\n const oldAbs = binding.bindingType === \"for\" ? getAbsoluteStateAddressByBinding(binding) : null;\n unregisterFromLedger(binding, record.address, record.patternPathInfo, record.patternListIndex);\n record.address = null;\n record.patternPathInfo = null;\n record.patternListIndex = null;\n this.registerAddress(record);\n if (oldAbs !== null) {\n const newAbs = getAbsoluteStateAddressByBinding(binding);\n // 記録の有無は has で見る(get は未記録でも `[]` を返すため、!= null 判定は\n // 常に真 — 未記録の旧アドレスから空配列を持ち込んで、新アドレスに残っていた\n // 正当な記録を潰しうる)\n if (newAbs !== oldAbs && hasLastListValueByAbsoluteStateAddress(oldAbs)) {\n setLastListValueByAbsoluteStateAddress(newAbs, getLastListValueByAbsoluteStateAddress(oldAbs));\n }\n // state 側の基準(E1)も同じ理由で引き継ぐ。記録の有無は has で見る(同上)\n if (newAbs !== oldAbs && hasStateListBaseline(oldAbs)) {\n setStateListBaseline(newAbs, getStateListBaseline(oldAbs));\n }\n }\n if (this.shouldApplyState(binding)) {\n rebound.push(binding);\n }\n }\n return rebound;\n }\n\n observe(node: Node): void {\n const root = observableRootFor(node);\n if (root === null) return;\n // owner(root ごとの MutationObserver)の存在だけ保証する。session の配送先\n // 登録は node 単位(interestedSessionsByNode)で行い、owner は session を\n // 直接は保持しない。\n getBindingOwner(root);\n }\n\n handleMutations(root: IObservableRoot, removed: readonly Node[], added: readonly Node[]): void {\n for (const subtree of removed) {\n forEachInclusive(subtree, (node) => {\n if (root.contains(node)) return;\n this.handleRemovedNode(node);\n });\n }\n const reconnected: IBindingInfo[] = [];\n for (const subtree of added) {\n forEachInclusive(subtree, (node) => {\n if (!root.contains(node)) return;\n this.handleAddedNode(node, reconnected);\n });\n }\n if (reconnected.length > 0) applyChangeFromBindings(reconnected);\n }\n\n handleRemovedNode(node: Node): void {\n const known = this.knownBindingsByNode.get(node);\n if (typeof known !== \"undefined\") {\n if (known instanceof Map) {\n for (const binding of known.values()) this.disposeBinding(binding);\n } else {\n this.disposeBinding(known);\n }\n }\n const tasks = this.deferredByNode.get(node);\n if (typeof tasks !== \"undefined\") {\n for (const task of Array.from(tasks)) {\n task.active = false;\n task.cancel?.();\n tasks.delete(task);\n this.deferred.delete(task);\n }\n }\n }\n\n handleAddedNode(node: Node, reconnected: IBindingInfo[]): void {\n const known = this.knownBindingsByNode.get(node);\n if (typeof known === \"undefined\") return;\n const bindings = known instanceof Map ? known.values() : [known];\n for (const binding of bindings) {\n const record = recordByBinding.get(binding);\n if (record?.phase === \"active\") {\n this.settleConnectedSnapshot(record);\n continue;\n }\n if (record?.phase !== \"disposed\") continue;\n const options = this.optionsByBinding.get(binding);\n if (typeof options === \"undefined\") continue;\n try {\n this.start(binding, options);\n if (options.applyOnReconnect && this.shouldApplyState(binding)) reconnected.push(binding);\n } catch {\n // Mutation delivery cannot surface initialization errors to a caller.\n }\n }\n }\n\n /**\n * anchor の known 台帳を Map 形へ正規化して返す(remember のキー照合用)。\n * 単一値(プラン行 or 既存単独 binding)は実キーを引いて昇格する。\n */\n private knownMapFor(anchor: Node): Map<string, IBindingInfo> {\n const current = this.knownBindingsByNode.get(anchor);\n if (current instanceof Map) {\n return current;\n }\n const map = new Map<string, IBindingInfo>();\n if (typeof current !== \"undefined\") {\n let key = bindingKeyByBinding.get(current);\n if (typeof key === \"undefined\") {\n key = bindingKey(current);\n bindingKeyByBinding.set(current, key);\n }\n map.set(key, current);\n }\n this.knownBindingsByNode.set(anchor, map);\n return map;\n }\n\n private remember(binding: IBindingInfo, options: IBindingOptions): IBindingInfo {\n const anchor = binding.replaceNode;\n // detached fragment 上でも登録しておく(node 単位の台帳なので root 非依存)。\n // fragment 一括マウントで後から接続された行にも mutation 配送が届くようにする。\n addInterestedSession(anchor, this);\n const known = this.knownMapFor(anchor);\n let key = bindingKeyByBinding.get(binding);\n if (typeof key === \"undefined\") {\n key = bindingKey(binding);\n bindingKeyByBinding.set(binding, key);\n }\n const remembered = known.get(key);\n if (typeof remembered !== \"undefined\") {\n const rememberedOptions = this.optionsByBinding.get(remembered);\n if (typeof rememberedOptions !== \"undefined\") {\n rememberedOptions.registerAddress ||= options.registerAddress;\n rememberedOptions.registerPathInfo ||= options.registerPathInfo;\n rememberedOptions.applyOnReconnect ||= options.applyOnReconnect;\n }\n return remembered;\n }\n known.set(key, binding);\n this.optionsByBinding.set(binding, { ...options });\n return binding;\n }\n\n /**\n * RowPlan 経路の一括初期化(createContent 専用・docs/state-row-instantiation-redesign.md §3-2)。\n * プラン行の binding はこの呼び出しでのみ生成されるため remember(キー照合・\n * options マージ)を丸ごと省略し、policy/authority はテンプレート時に解決済みの\n * 値を焼き込む。options は行内共有の 1 オブジェクト(activate が\n * registerAddress を昇格するとき行内全 binding が同時に昇格する — 従来も\n * activate は全 binding を同順で昇格するため観測可能な差はない)。\n */\n initializeRow(plan: IRowPlan, bindings: readonly IBindingInfo[]): void {\n this.rowPlan = plan;\n const slots = plan.slots;\n const n = bindings.length;\n const row: IRowRecord = {\n id: ++nextRecordId,\n session: this,\n generation: ++nextGeneration,\n plan,\n bindings,\n registered: false,\n // 素の配列(Smi)。型付き配列は本体と backing store で 1 本あたり 100 B を超え、cold の\n // 生成では行ごとの割り当ての上位に出た(設計 R5)\n phases: new Array<number>(n).fill(SLOT_ACTIVE),\n flags: new Array<number>(n).fill(0),\n addresses: new Array<IAbsoluteStateAddress | null>(n).fill(null),\n patternPathInfos: new Array<ITreePath | null>(n).fill(null),\n patternListIndexes: new Array<IListIndex | null>(n).fill(null),\n };\n this.rows.add(row);\n for (let i = 0; i < n; i++) {\n const binding = bindings[i];\n const anchor = binding.replaceNode;\n addInterestedSession(anchor, this);\n this.addKnownRowBinding(anchor, binding, i);\n rowByBinding.set(binding, row);\n if (slots[i].isEvent) {\n try {\n attachEventHandler(binding);\n } catch (error) {\n row.phases[i] = SLOT_FAILED;\n throw error;\n }\n row.flags[i] |= FLAG_EVENT_ATTACHED;\n }\n // 非 event スロットはプラン適格性により双方向不能・radio/checkbox 不能・\n // token 配線不能が確定しているため attach 系を一切呼ばない\n }\n }\n\n /**\n * プラン行の活性化(activate の高速経路)。bindings は initializeRow と同一の\n * スロット整列配列(bindingsByContent がそのまま保持)である前提。\n * プラン行の record は policy/authority 解決済み・observable なし・\n * connect-snapshot なしが構造的に保証されているため、settleInitialRecord /\n * settleConnectedSnapshot の呼び出し自体を省略できる。\n * プール再利用(disposed/failed)では record オブジェクトを再利用し、\n * 世代だけ進めて listener attach とアドレス登録をやり直す(record 再割当なし)。\n */\n private activatePlanRows(plan: IRowPlan, bindings: readonly IBindingInfo[], knownRoot: Node): void {\n const row = bindings.length > 0 ? this.rowOf(bindings[0]) : null;\n if (row === null || row.bindings !== bindings) {\n // この session の行でない binding 配列(防御): 従来経路\n for (const binding of bindings) {\n this.initialize([binding], { registerAddress: true, registerPathInfo: false, applyOnReconnect: false });\n }\n return;\n }\n row.registered = true;\n const slots = plan.slots;\n let revived = false;\n for (let i = 0; i < bindings.length; i++) {\n if (row.phases[i] !== SLOT_ACTIVE) {\n // pool 再利用: 世代だけ進めて listener attach とアドレス登録をやり直す\n if (!revived) {\n row.generation = ++nextGeneration;\n revived = true;\n this.rows.add(row);\n }\n row.phases[i] = SLOT_ACTIVE;\n row.flags[i] = 0;\n if (slots[i].isEvent) {\n try {\n attachEventHandler(bindings[i]);\n } catch (error) {\n row.phases[i] = SLOT_FAILED;\n this.runRowSlotTeardowns(row, i);\n throw error;\n }\n row.flags[i] |= FLAG_EVENT_ATTACHED;\n }\n this.registerRowSlot(row, i, knownRoot);\n continue;\n }\n if (row.addresses[i] === null && row.patternPathInfos[i] === null) {\n // 初回活性化\n this.registerRowSlot(row, i, knownRoot);\n }\n }\n }\n\n private rowOf(binding: IBindingInfo): IRowRecord | null {\n const row = rowByBinding.get(binding);\n return typeof row !== \"undefined\" && row.session === this ? row : null;\n }\n\n private registerRowSlot(row: IRowRecord, slot: number, knownRoot?: Node | null): void {\n if (row.addresses[slot] !== null || row.patternPathInfos[slot] !== null) return;\n const binding = row.bindings[slot];\n const listIndex = getListIndexByBindingInfo(binding);\n if (listIndex !== null) {\n row.patternPathInfos[slot] = registerPattern(binding, listIndex, knownRoot);\n row.patternListIndexes[slot] = listIndex;\n } else {\n row.addresses[slot] = registerAbsoluteAddress(binding, knownRoot);\n }\n // registerPathInfo は行オプションで常に false\n }\n\n private unregisterRowSlot(row: IRowRecord, slot: number): void {\n const address = row.addresses[slot];\n const pathInfo = row.patternPathInfos[slot];\n if (address === null && pathInfo === null) return;\n // 外せなかった(台帳の throw)ときは器を残す: 後で生き返った行が登録し直さないように\n unregisterFromLedger(row.bindings[slot], address, pathInfo, row.patternListIndexes[slot]);\n row.addresses[slot] = null;\n row.patternPathInfos[slot] = null;\n row.patternListIndexes[slot] = null;\n }\n\n private disposeRowSlot(row: IRowRecord, slot: number): void {\n if (row.phases[slot] === SLOT_DISPOSED) return;\n row.phases[slot] = SLOT_DISPOSED;\n this.runRowSlotTeardowns(row, slot);\n for (let i = 0; i < row.phases.length; i++) {\n if (row.phases[i] === SLOT_ACTIVE) return;\n }\n this.rows.delete(row);\n }\n\n private runRowSlotTeardowns(row: IRowRecord, slot: number): void {\n try {\n this.unregisterRowSlot(row, slot);\n } catch {\n // Cleanup is best-effort; one faulty resource must not retain the rest.\n }\n if ((row.flags[slot] & FLAG_EVENT_ATTACHED) !== 0) {\n row.flags[slot] &= ~FLAG_EVENT_ATTACHED;\n try {\n detachEventHandler(row.bindings[slot]);\n } catch {\n // Cleanup is best-effort.\n }\n }\n }\n\n private addKnownRowBinding(anchor: Node, binding: IBindingInfo, slotIndex: number): void {\n const current = this.knownBindingsByNode.get(anchor);\n if (typeof current === \"undefined\") {\n this.knownBindingsByNode.set(anchor, binding);\n return;\n }\n // 同一 anchor に複数スロット(複数エントリの data-wcs): Map へ昇格。\n // プラン行はキー照合されないため添字ベースの合成キーで一意性だけ担保する\n if (current instanceof Map) {\n current.set(\"@plan:\" + slotIndex, binding);\n return;\n }\n const map = new Map<string, IBindingInfo>();\n map.set(\"@plan:first\", current);\n map.set(\"@plan:\" + slotIndex, binding);\n this.knownBindingsByNode.set(anchor, map);\n }\n\n private start(binding: IBindingInfo, options: IBindingOptions, knownRoot?: Node | null): void {\n replaceToReplaceNode(binding);\n const recordOptions = this.optionsByBinding.get(binding) ?? { ...options };\n const record: IInternalBindingRecord = {\n id: ++nextRecordId,\n info: binding,\n generation: ++nextGeneration,\n phase: \"discovered\",\n teardowns: null,\n session: this,\n anchor: binding.replaceNode,\n options: recordOptions,\n address: null,\n patternPathInfo: null,\n patternListIndex: null,\n pendingDefinitions: 0,\n initialPolicy: null,\n resolvedAuthority: null,\n initialSettled: false,\n initialApplyDone: false,\n outputOnlyMember: false,\n observationPending: false,\n eventSequence: 0,\n hasProducerValue: false,\n producerValue: undefined,\n eventAttached: false,\n twowayAttached: false,\n };\n recordByBinding.set(binding, record);\n this.records.add(record);\n // knownRoot が渡されたときは observe を省略する(null = detached fragment 上で\n // observableRootFor が必ず null、Node = activate 冒頭で owner 保証済み)\n if (typeof knownRoot === \"undefined\") this.observe(record.anchor);\n\n try {\n record.phase = \"attaching\";\n this.attachListeners(record);\n if (record.options.registerAddress) this.registerAddress(record, knownRoot);\n if (record.pendingDefinitions === 0) record.phase = \"active\";\n } catch (error) {\n record.phase = \"failed\";\n this.runTeardowns(record);\n this.records.delete(record);\n throw error;\n }\n }\n\n private attachListeners(record: IInternalBindingRecord): void {\n const binding = record.info;\n if (attachEventHandler(binding)) {\n record.eventAttached = true;\n return;\n }\n\n if (binding.propSegments[0] === EVENT_TOKEN_NAMESPACE) {\n this.attachAfterDefinition(record, () => {\n if (attachEventTokenHandler(binding)) {\n addRecordTeardown(record, () => detachEventTokenHandler(binding));\n }\n });\n return;\n }\n\n if (attachRadioEventHandler(binding)) {\n addRecordTeardown(record, () => detachRadioEventHandler(binding));\n }\n if (attachCheckboxEventHandler(binding)) {\n addRecordTeardown(record, () => detachCheckboxEventHandler(binding));\n }\n this.attachAfterDefinition(record, () => {\n // directional initial sync の producer-value observer は twowayEventHandlerFunction\n // からのみ呼ばれる(唯一の consumer)。その handler が attach されるのは\n // isPossibleTwoWay かつ非 ro の binding だけ(attachTwowayEventHandler と同条件)\n // なので、one-way / event / eventToken / radio(非value) 等では observer は決して\n // fire しない。以前は attachListeners 冒頭で全 binding に無条件登録していたが、\n // fire しえない大多数の binding に対する setup 死荷重だった。ここへ移すことで\n // 「twoway handler が付く binding のみ observer 登録」を構造的に保証する\n // (undefined custom element は attachAfterDefinition が定義後まで遅延するので\n // isPossibleTwoWay の未定義 CE raiseError も踏まない)。\n if (\n config.enableDirectionalInitialSync\n && isPossibleTwoWay(binding.node, binding.propName)\n && binding.propModifiers.indexOf(MODIFIER_READONLY) === -1\n ) {\n const removeObserver = addTwowayValueObserver(binding.node, binding.propName, (value) => {\n if (!this.isAlive(record, record.generation)) return;\n record.eventSequence += 1;\n record.hasProducerValue = true;\n record.producerValue = value;\n });\n addRecordTeardown(record, removeObserver);\n }\n attachTwowayEventHandler(binding);\n record.twowayAttached = true;\n });\n }\n\n private attachAfterDefinition(record: IInternalBindingRecord, attach: () => void): void {\n const tagName = getCustomElement(record.info.node);\n if (tagName === null) {\n attach();\n return;\n }\n const registry = getCustomElementRegistry(record.info.node);\n if (registry === null) {\n raiseError(`CustomElementRegistry is unavailable for <${tagName}>.`);\n }\n if (typeof registry.get(tagName) !== \"undefined\") {\n attach();\n return;\n }\n\n record.phase = \"waiting-definition\";\n record.pendingDefinitions += 1;\n const generation = record.generation;\n const coordinator: DefinitionCoordinator = getDefinitionCoordinator(registry);\n const cancel = coordinator.wait(tagName, () => {\n if (!this.isAlive(record, generation)) return;\n try {\n upgradeCustomElement(registry, record.info.node);\n attach();\n record.pendingDefinitions -= 1;\n if (record.pendingDefinitions === 0) {\n record.phase = \"active\";\n this.settleInitialRecord(record);\n }\n } catch {\n record.phase = \"failed\";\n this.runTeardowns(record);\n this.records.delete(record);\n }\n }, () => {\n if (!this.isAlive(record, generation)) return;\n record.phase = \"failed\";\n this.runTeardowns(record);\n this.records.delete(record);\n });\n addRecordTeardown(record, cancel);\n }\n\n private settleInitialRecord(record: IInternalBindingRecord): void {\n if (!config.enableDirectionalInitialSync || record.initialSettled || !record.options.registerAddress) return;\n record.phase = \"synchronizing\";\n try {\n const policy = resolveInitialSyncPolicy(record.info);\n const authority = resolveInitialAuthority(record.info, policy.authority);\n record.initialPolicy = policy;\n record.resolvedAuthority = authority;\n record.initialSettled = true;\n record.outputOnlyMember = policy.outputOnly;\n record.phase = \"active\";\n if (!policy.observable) return;\n if (\n policy.syncOn === \"connect\"\n && record.info.node instanceof HTMLElement\n && !record.info.node.isConnected\n ) {\n record.observationPending = true;\n // 待ちが 1 件でもある間は追加側 observer スキップを無効化する\n incrementPendingObservation();\n return;\n }\n this.readProducerSnapshot(record, policy.syncOn === \"call\");\n } catch (error) {\n record.phase = \"failed\";\n this.runTeardowns(record);\n this.records.delete(record);\n throw error;\n }\n }\n\n private readProducerSnapshot(record: IInternalBindingRecord, eventWins: boolean): void {\n if (!this.isAlive(record, record.generation)) return;\n const target = record.info.node as Node & Record<string, unknown>;\n const name = record.info.propName;\n if (!(name in target)) return;\n const sequence = record.eventSequence;\n const value = target[name];\n if (record.observationPending) {\n record.observationPending = false;\n decrementPendingObservation();\n }\n if (eventWins && record.eventSequence !== sequence) return;\n record.hasProducerValue = true;\n record.producerValue = value;\n if (record.resolvedAuthority === \"element\") {\n commitProducerValue(record.info, value);\n }\n }\n\n private settleConnectedSnapshot(record: IInternalBindingRecord): void {\n if (\n !config.enableDirectionalInitialSync\n || !record.observationPending\n || !(record.info.node instanceof HTMLElement)\n || !record.info.node.isConnected\n ) return;\n try {\n this.readProducerSnapshot(record, false);\n } catch {\n record.phase = \"failed\";\n this.runTeardowns(record);\n this.records.delete(record);\n }\n }\n\n private registerAddress(record: IInternalBindingRecord, knownRoot?: Node | null): void {\n if (record.address !== null || record.patternListIndex !== null) return;\n const binding = record.info;\n const listIndex = getListIndexByBindingInfo(binding);\n if (listIndex !== null) {\n record.patternPathInfo = registerPattern(binding, listIndex, knownRoot);\n record.patternListIndex = listIndex;\n } else {\n record.address = registerAbsoluteAddress(binding, knownRoot);\n }\n // 台帳解除は runTeardowns が record.address / pattern フィールドから\n // データ駆動で行う(クロージャ不要)\n if (!record.options.registerPathInfo) return;\n const rootNode = binding.replaceNode.getRootNode() as Node;\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n if (binding.bindingType !== \"event\") {\n stateElement.setPathInfo(binding.statePathName, binding.bindingType);\n }\n }\n\n private isAlive(record: IInternalBindingRecord, generation: number): boolean {\n return record.generation === generation\n && recordByBinding.get(record.info) === record\n && record.phase !== \"disposed\"\n && record.phase !== \"failed\";\n }\n\n private disposeRecord(record: IInternalBindingRecord): void {\n if (record.phase === \"disposed\") return;\n record.phase = \"disposed\";\n this.runTeardowns(record);\n this.records.delete(record);\n }\n\n private runTeardowns(record: IInternalBindingRecord): void {\n // runTeardowns は record の終端(disposed / failed)でのみ呼ばれる。未消化の\n // connect-snapshot 待ちが残っていれば必ずカウンタを戻す(スキップ再有効化)。\n if (record.observationPending) {\n record.observationPending = false;\n decrementPendingObservation();\n }\n const binding = record.info;\n // データ駆動の後始末(従来はクロージャで積んでいた頻出3種)。実行順は従来の\n // 逆順実行と同じ: アドレス台帳解除(最後に積まれていた)→ 双方向 detach →\n // 希少クロージャ群(逆順)→ イベント detach。各 detach は互いに独立した資源を\n // 対象とするため、この順序で意味論は変わらない。\n if (record.address !== null || record.patternListIndex !== null) {\n try {\n unregisterFromLedger(binding, record.address, record.patternPathInfo, record.patternListIndex);\n record.address = null;\n record.patternPathInfo = null;\n record.patternListIndex = null;\n } catch {\n // Cleanup is best-effort; one faulty resource must not retain the rest.\n }\n }\n if (record.twowayAttached) {\n record.twowayAttached = false;\n try {\n detachTwowayEventHandler(binding);\n } catch {\n // Cleanup is best-effort.\n }\n }\n if (record.teardowns !== null) {\n const teardowns = Array.from(record.teardowns).reverse();\n record.teardowns = null;\n for (const teardown of teardowns) {\n try {\n teardown();\n } catch {\n // Cleanup is best-effort; one faulty resource must not retain the rest.\n }\n }\n }\n if (record.eventAttached) {\n record.eventAttached = false;\n try {\n detachEventHandler(binding);\n } catch {\n // Cleanup is best-effort.\n }\n }\n }\n}\n\nexport function getOrCreateBindingSession(root: Node): BindingSession {\n let session = sessionByRoot.get(root);\n if (typeof session === \"undefined\") {\n session = new BindingSession(root);\n sessionByRoot.set(root, session);\n }\n return session;\n}\n\nexport function getBindingSession(binding: IBindingInfo): BindingSession | null {\n return recordByBinding.get(binding)?.session ?? rowByBinding.get(binding)?.session ?? null;\n}\n","import { IBindingInfo } from \"../types.js\";\n\nexport function replaceToReplaceNode(bindingInfo: IBindingInfo): void {\n const node = bindingInfo.node;\n const replaceNode = bindingInfo.replaceNode;\n if (node === replaceNode) {\n return;\n }\n if (node.parentNode === null) {\n // already replaced\n return;\n }\n node.parentNode.replaceChild(replaceNode, node);\n}\n","/**\n * core/componentApplyHooks.ts — カスタム要素のプロパティ束縛の受け口(設計案 S5)。\n *\n * `bind-component` の機能(webComponent/bindComponentLifecycle.ts)が install で置く。apply 側\n * (apply/applyChange.ts・apply/applyChangeToProperty.ts)は、置かれていなければカスタム要素への\n * 束縛も素のプロパティ書き込みとして扱い、何も控えない — 控えの読み手は bind-component の中にしか居ない。\n */\n\nexport interface IComponentApplyHooks {\n /** `bind-component` の配線が完了した (要素, state プロパティ)。値を運ばない通知チャネルへ切り替える */\n isComplete(element: Element, stateProp: string): boolean;\n /** 宣言済み・未完了。完了前の初期適用は書かない */\n isDeclared(element: Element, stateProp: string): boolean;\n /** 完了前の丸ごと書き込み(`state: user`)が置き換える作者のオブジェクトを控える */\n rememberOverwrittenObject(element: Element, prop: string, previous: object): void;\n /** 完了前の部分書き込み(`state.theme: theme`)が作者のオブジェクトに作ったキーを控える */\n recordInjectedKey(element: Element, prop: string, key: string): void;\n /** 完了前の部分書き込みが上書きする作者の既存キーの値を控える */\n rememberOverwrittenValue(element: Element, prop: string, key: string, previous: unknown): void;\n}\n\n/** 置かれていなければ null(apply 側は判定 1 回で素の書き込みに倒す) */\nexport let componentApplyHooks: IComponentApplyHooks | null = null;\n\n/** 機能の install が呼ぶ(冪等 — 置き換え) */\nexport function setComponentApplyHooks(hooks: IComponentApplyHooks | null): void {\n componentApplyHooks = hooks;\n}\n","import { IFilterInfo } from \"../binding/types.js\";\n\nexport function getFilteredValue(value: any, filters: IFilterInfo[]) {\n let filteredValue = value;\n for(const filter of filters) {\n filteredValue = filter.filterFn(filteredValue);\n }\n return filteredValue;\n}\n","import { createEmptyArray } from \"../createEmptyArray\";\nimport { IBindingInfo } from \"../types\";\nimport { getFilteredValue } from \"./getFilteredValue\";\nimport { IApplyContext } from \"./types\";\n\nconst EMPTY_ARRAY = createEmptyArray<unknown>();\n\nexport function applyChangeToCheckbox(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n const element = binding.node as HTMLInputElement;\n const elementValue = element.value;\n const elementFilteredValue = getFilteredValue(elementValue, binding.inFilters);\n const normalizedNewValue = Array.isArray(newValue) ? newValue : EMPTY_ARRAY;\n element.checked = normalizedNewValue.includes(elementFilteredValue);\n}\n","\nexport function createEmptyArray<T>(): Readonly<Array<T>> {\n return Object.freeze<Array<T>>([]);\n}\n","/**\n * command.<methodName>: <commandToken-path> バインディングの適用ハンドラ。\n *\n * subscribe lifecycle:\n * - 同一 binding に同じ token が再評価された場合は no-op。\n * - 異なる token が来た場合は古い subscription を解除し、新しい token に subscribe し直す。\n * 旧解除は新しい binding 妥当性検証(methodName・wcBindable.commands チェック)を\n * 通過した後に行うため、再評価が validation で失敗しても旧購読は温存される(fail-fast)。\n * - element は WeakRef で保持し、subscriber 経由で element を強参照しないようにする。\n * これにより、element が DOM から消えた後に subscriber が token._subscribers に\n * 残っていても element 本体は GC 可能。\n * - emit 時に下記いずれかなら自動で subscription を破棄する(lazy purge):\n * - WeakRef.deref() が undefined(element が既に GC 済み)\n * - element.isConnected が false(DOM から取り外されている)\n *\n * 既知の制約:\n * - emit が来なければ stale subscriber は token に残り続ける(要素が GC されても subscriber 関数自体は残る)。\n * registry は state 要素をキーにした WeakMap なので、state 要素ごと GC されたときに解放される。\n * 切断では registry を捨てない — 捨てると、ルート <wcs-state> を付け直した後の emit が\n * 購読者の居ない新しい token に届き、命令が無言で止まる(#273)。\n * element ライフサイクルに直接フックする手段が現状の binding 機構に無いため、能動的な purge は将来課題。\n */\n\nimport { isCommandToken } from \"../command/CommandToken\";\nimport { ICommandToken } from \"../command/types\";\nimport { didYouMean } from \"../errorGuidance\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration, ReadBindableResult } from \"../protocol/wcBindableReader\";\nimport { raiseError } from \"../raiseError\";\nimport { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\n\ninterface ICommandSubscription {\n readonly token: ICommandToken;\n readonly unsubscribe: () => void;\n readonly elementRef: WeakRef<Element>;\n}\n\nconst subscribedBindings: WeakMap<IBindingInfo, ICommandSubscription> = new WeakMap();\n\nfunction getWcBindable(element: Element): ReadBindableResult | null {\n const customTagName = getCustomElement(element);\n if (customTagName === null) {\n return null;\n }\n const customClass = getCustomElementRegistry(element)?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n raiseError(`Custom element <${customTagName}> is not defined for command binding.`);\n }\n return readBindableDeclaration(element);\n}\n\nexport function applyChangeToCommand(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n if (!isCommandToken(newValue)) {\n raiseError(`command binding requires a CommandToken value (use $command.<tokenName> with a name declared in $commandTokens).`);\n }\n const token = newValue as ICommandToken;\n\n const existing = subscribedBindings.get(binding);\n if (existing && existing.token === token) {\n return;\n }\n\n // 新しい binding 妥当性検証は、旧 subscription を解除する前に通す(fail-fast)。\n const element = binding.node as Element;\n const methodName = binding.propSegments[1];\n if (typeof methodName !== \"string\" || methodName.length === 0) {\n raiseError(`command binding requires a method name (e.g., \"command.fetch\").`);\n }\n\n const bindable = getWcBindable(element);\n if (bindable === null) {\n raiseError(`command binding requires a wc-bindable custom element. <${element.tagName.toLowerCase()}> is not wc-bindable.`);\n }\n if (!bindable.declaredCommands.has(methodName)) {\n // eventTokenHandler の property 検証と対双の did-you-mean(設計 §3)。\n raiseError(`Command \"${methodName}\" is not declared in wcBindable.commands of <${element.tagName.toLowerCase()}>.${didYouMean(methodName, bindable.declaredCommands.keys())}`);\n }\n\n // ここまで来たら旧解除して新 subscribe に切り替える。\n if (existing) {\n existing.unsubscribe();\n subscribedBindings.delete(binding);\n }\n\n const elementRef = new WeakRef(element);\n let unsubscribe: (() => void) | null = null;\n const subscriber = (...args: unknown[]): unknown => {\n const el = elementRef.deref();\n if (!el || !el.isConnected) {\n unsubscribe?.();\n subscribedBindings.delete(binding);\n return undefined;\n }\n const method = (el as unknown as Record<string, unknown>)[methodName];\n if (typeof method !== \"function\") {\n raiseError(`Method \"${methodName}\" is not a function on <${el.tagName.toLowerCase()}>.`);\n }\n return Reflect.apply(method as (...a: unknown[]) => unknown, el, args);\n };\n unsubscribe = token.subscribe(subscriber);\n subscribedBindings.set(binding, { token, unsubscribe, elementRef });\n}\n\nexport const __private__ = {\n subscribedBindings,\n};\n","import { IContent } from \"../structural/types\";\nimport { IBindingInfo } from \"../types\";\n\nconst bindingsByContent: WeakMap<IContent, IBindingInfo[]> = new WeakMap();\n\nexport function getBindingsByContent(content: IContent): IBindingInfo[] {\n return bindingsByContent.get(content) ?? [];\n}\n\nexport function setBindingsByContent(content: IContent, bindings: IBindingInfo[]): void {\n bindingsByContent.set(content, bindings);\n}\n","import { IContent } from \"../structural/types\";\nimport { IBindingInfo } from \"../types\";\n\nconst indexBindingsByContent: WeakMap<IContent, IBindingInfo[]> = new WeakMap();\n\nexport function getIndexBindingsByContent(content: IContent): IBindingInfo[] {\n return indexBindingsByContent.get(content) ?? [];\n}\n\nexport function setIndexBindingsByContent(content: IContent, bindings: IBindingInfo[]): void {\n indexBindingsByContent.set(content, bindings);\n}\n","/* v8 ignore file */\nexport {};\n\ndeclare global {\n interface Set<T> {\n difference(other: Set<T>): Set<T>;\n intersection(other: Set<T>): Set<T>;\n }\n}\n\nif (!Set.prototype.difference) {\n Set.prototype.difference = function <T>(this: Set<T>, other: Set<T>): Set<T> {\n const result = new Set(this);\n for (const elem of other) {\n result.delete(elem);\n }\n return result;\n };\n}\n\nif (!Set.prototype.intersection) {\n Set.prototype.intersection = function <T>(this: Set<T>, other: Set<T>): Set<T> {\n const result = new Set<T>();\n for (const elem of other) {\n if (this.has(elem)) {\n result.add(elem);\n }\n }\n return result;\n };\n}\n","\nlet count = 0;\nexport function getUUID(): string {\n return `u${(count++).toString(36)}`;\n}\n","import { getUUID } from \"../getUUID\";\nimport { IListIndex } from \"./types\";\n\nlet version = 0;\n/**\n * 親の付け替え(#256 の修理)の世代。`listIndexes` の WeakRef 連鎖は一度組んだら\n * 作り直されないので、祖先が付け替わったら子孫のキャッシュも無効にする必要がある。\n * `dirty`(version 比較)は `indexes` の再構築が消費してしまうため、連鎖専用の世代を持つ。\n */\nlet chainGeneration = 0;\n\n/** 値が一度も記録されていない行の印(`undefined` を持つ行と区別するため)。 */\nconst NO_VALUE = Symbol(\"wcs.listIndex.noValue\");\n\nclass ListIndex implements IListIndex {\n readonly uuid = getUUID();\n parentListIndex: IListIndex | null;\n readonly position: number;\n readonly length: number;\n\n private _index: number;\n private _version: number;\n private _indexes: number[] | undefined;\n private _listIndexes: WeakRef<IListIndex>[] | undefined;\n private _chainGeneration: number;\n /**\n * この行集合を最初に展開した親(`home`・#256)。付け替えても変わらない。退役した親から\n * 付け替えたあと、その親が戻ってきたら戻す先になる。既存の行集合を引き継ぐ行は、鋳造時の\n * 親ではなくその行集合の home を継ぐ(`createListDiff`)── 1 組の行集合に home は 1 つ。\n */\n private readonly _homeParentListIndex: IListIndex | null;\n\n /**\n * この行が表しているリスト要素(#256)。差分が返すたびに付け直す。\n * 「同じ行が戻ってきた」を配列インスタンスをまたいで言えるのはこの値だけ ──\n * 行を戻す普通のやり方(新しい配列に同じ要素を並べ直す)は ListIndex を作り直すので、\n * 行オブジェクトの identity では判定できない。\n */\n private _value: unknown;\n\n /**\n * Creates a new ListIndex instance.\n *\n * @param parentListIndex - Parent list index for nested loops, or null for top-level\n * @param index - Current index value in the loop\n * @param homeParentListIndex - Parent this row's set belongs to (#256)\n */\n constructor(parentListIndex: IListIndex | null, index: number, homeParentListIndex: IListIndex | null) {\n this.parentListIndex = parentListIndex;\n this.position = parentListIndex ? parentListIndex.position + 1 : 0;\n this.length = this.position + 1;\n this._homeParentListIndex = homeParentListIndex;\n this._value = NO_VALUE;\n this._index = index;\n this._version = version;\n this._chainGeneration = chainGeneration;\n }\n\n /**\n * Gets current index value.\n *\n * @returns Current index number\n */\n get index() {\n return this._index;\n }\n\n /**\n * Sets index value and updates version.\n *\n * @param value - New index value\n */\n set index(value: number) {\n this._index = value;\n this._version = ++version;\n this.indexes[this.position] = value;\n }\n\n /**\n * Gets current version number for change detection.\n *\n * @returns Version number\n */\n get version(): number {\n return this._version;\n }\n\n /** 行集合を最初に展開した親(付け替えても変わらない)。 */\n get homeParentListIndex(): IListIndex | null {\n return this._homeParentListIndex;\n }\n\n /** この行が表しているリスト要素(未記録なら `NO_VALUE`)。 */\n get value(): unknown {\n return this._value;\n }\n\n set value(value: unknown) {\n this._value = value;\n }\n\n /**\n * Checks if parent indexes have changed since last access.\n *\n * @returns true if parent has newer version, false otherwise\n */\n get dirty(): boolean {\n if (this.parentListIndex === null) {\n return false;\n } else {\n return this.parentListIndex.dirty || this.parentListIndex.version > this._version;\n }\n }\n\n /**\n * Gets array of all index values from root to current level.\n * Rebuilds array if parent indexes have changed (dirty).\n *\n * @returns Array of index values\n */\n get indexes(): number[] {\n if (this.parentListIndex === null) {\n if (typeof this._indexes === \"undefined\") {\n this._indexes = [this._index];\n }\n } else {\n if (typeof this._indexes === \"undefined\" || this.dirty) {\n this._indexes = [...this.parentListIndex.indexes, this._index];\n this._version = version;\n }\n }\n return this._indexes;\n }\n\n /**\n * Gets array of WeakRef to all ListIndex instances from root to current level.\n *\n * @returns Array of WeakRef<IListIndex>\n */\n get listIndexes(): WeakRef<IListIndex>[] {\n if (this.parentListIndex === null) {\n if (typeof this._listIndexes === \"undefined\") {\n this._listIndexes = [new WeakRef(this)];\n }\n } else {\n if (typeof this._listIndexes === \"undefined\" || this._chainGeneration !== chainGeneration) {\n this._listIndexes = [...this.parentListIndex.listIndexes, new WeakRef(this)];\n this._chainGeneration = chainGeneration;\n }\n }\n return this._listIndexes;\n }\n\n /**\n * Gets variable name for this loop index ($1, $2, etc.).\n *\n * @returns Variable name string\n */\n get varName(): string {\n return `$${this.position + 1}`;\n }\n\n /**\n * Gets ListIndex at specified position in hierarchy.\n * Supports negative indexing from end.\n *\n * @param pos - Position index (0-based, negative for from end)\n * @returns ListIndex at position or null if not found/garbage collected\n */\n /**\n * 退役した親を、同じ深さの生きた親へ差し替える(#256)。**行の identity は保つ**ので、\n * 描画済み content も、その行に紐づくバインドしていない DOM の状態も残る。\n * 添字の値は親が変われば変わりうる(並べ替えを伴う置換)ため、`indexes` と WeakRef 連鎖を\n * 捨て、version を進めて子孫の `dirty` を立てる。`_homeParentListIndex` は動かさない\n * ── 外した行が戻ってきたときに持ち主を返す先だから。\n */\n reparent(parentListIndex: IListIndex | null): void {\n this.parentListIndex = parentListIndex;\n this._indexes = undefined;\n this._listIndexes = undefined;\n this._version = ++version;\n chainGeneration++;\n }\n\n at(pos: number): IListIndex | null {\n if (pos >= 0) {\n return this.listIndexes[pos]?.deref() || null;\n } else {\n return this.listIndexes[this.listIndexes.length + pos]?.deref() || null;\n }\n }\n}\n\n/**\n * Factory function to create ListIndex instance.\n *\n * @param parentListIndex - Parent list index for nested loops, or null for top-level\n * @param index - Current index value in the loop\n * @param homeParentListIndex - Row set this row joins (#256); defaults to the minting parent\n * @returns New IListIndex instance\n */\nexport function createListIndex(\n parentListIndex: IListIndex | null,\n index: number,\n homeParentListIndex: IListIndex | null = parentListIndex,\n): IListIndex {\n return new ListIndex(parentListIndex, index, homeParentListIndex);\n}\n\n/**\n * 台帳(`listIndexesByList`)専用の入口。行は必ずこのモジュールが鋳造した実体なので、\n * 到達不能な防御分岐を置かずに直接呼ぶ。\n */\nexport function reparentListIndex(listIndex: IListIndex, parentListIndex: IListIndex | null): void {\n (listIndex as ListIndex).reparent(parentListIndex);\n}\n\n/**\n * 台帳専用の入口その 2。行集合の home を読む(`IListIndex` を広げないための cast ──\n * この型は dist/index.d.ts に出るので、内部だけの都合で公開面を増やさない)。\n */\nexport function getHomeParentListIndex(listIndex: IListIndex): IListIndex | null {\n return (listIndex as ListIndex).homeParentListIndex;\n}\n\n/** 台帳専用の入口その 3。差分が返した行に、その行が表している要素を憶えさせる(#256)。 */\nexport function setListIndexValue(listIndex: IListIndex, value: unknown): void {\n (listIndex as ListIndex).value = value;\n}\n\n/**\n * 2 つの行が**同じリスト要素**を表しているか(#256)。\n * 差分を通っていない行(`hydrateBindings` / `setByAddress` が鋳造する行)は値を持たないので、\n * 未記録どうしは「同じ」と見なさない ── 値の無い行を取り違えて付け替えないため。\n * 行を書き換えない読むだけの判定なので、台帳の外からも使う: `$scan` の drain が、行のアドレスが\n * いまその位置の要素を表しているかを見る(scan/scanRuntime.ts の placementOf)。\n */\nexport function isSameListIndexValue(listIndex: IListIndex, other: IListIndex): boolean {\n const value = (listIndex as ListIndex).value;\n return value !== NO_VALUE && value === (other as ListIndex).value;\n}\n","/**\n * list/listIndexesByList.ts\n *\n * 行(`IListIndex`)の正本台帳。1 本の配列につき行集合は **1 組**。\n *\n * #256 が扱うのは「共有」ではなく「陳腐化」である。台帳はこの 2 つを分ける:\n *\n * - **生きた共有** ── 1 本の配列が 2 つの生きた親から到達できる形。行集合は 1 組のまま\n * 全員で共有する(どの親から読んでも同じ値が見える)。親ごとに私有の行集合を持たせると\n * 同じスロットに 2 本の絶対アドレスができ、片方へ書いた値がもう片方から**永久に**\n * 見えなくなる。共有そのものの帰結(親を読む getter が持ち主の行の文脈で評価される・\n * 1 スロットへ到達経路の数だけ書かれる)は残るが、それはデータが実際に共有されている\n * ことの帰結であって、**もう存在しない古い値**ではない。\n * - **陳腐化** ── 行オブジェクトだけを作り直す置換(`nodes.map(n => ({...n}))` は\n * `children` を参照ごと引き継ぐ)で、台帳の行がぶら下がる親が**退役した**形。読み手は\n * 新しい行の絶対アドレスを見るのに、書き手は行の親ポインタを遡って旧行の絶対アドレスを\n * dirty にするので、葉への書き込みが集計へ届かない(#256)。\n *\n * 判別は「台帳の行が持つ親が、生きた親集合に属するか」。属さないときだけ、**行の identity を\n * 保ったまま**新しい親へ付け替える(`reparentListIndex`)。作り直さないのは、消費者が\n * 描画済み content を行 ListIndex の identity で持っているため ── 作り直すと、著者が何も\n * 間違えていないページで行の DOM が丸ごと失われる(`<details>` の開閉のような、バインド\n * していない状態ごと)。\n *\n * 退役の signal は差分の `deleteIndexSet`(=エンジン自身が「この行はもう無い」と決めた\n * 集合)で、**復活の signal は同じ差分の `newIndexes`**。印は差分ごとに付け直され、\n * 消えない印は残らない(`retireListIndexes` / `reviveListIndexes` を `createListDiff` が\n * 対で呼ぶ)。\n *\n * 付け替えは**一方通行ではない**。行は自分の行集合を最初に展開した親(`home`)を憶えていて、\n * その home が**リストに戻ってきたら**持ち主を返す。これが無いと「行を削除して戻す」ページで\n * 持ち主が隣の行に移ったまま固定され、削除の履歴によって集計が凍る行が変わってしまう。\n *\n * 戻ってきたかどうかは **行オブジェクト(ListIndex)の identity ではなく、行が表している\n * リスト要素の identity** で判定する。同じ配列インスタンスを戻す綴りなら home そのものが\n * 生き返るが、行を戻す普通のやり方(新しい配列に同じ要素を並べ直す)では差分が ListIndex を\n * 作り直すので、ListIndex の identity で見ると home は永久に退役したままになる。\n * 要素そのものを作り直した行は**別の行**なので home には一致しない。生き残った行が\n * 1 つでもあればそちらへ戻るが、**全ての行を作り直す**綴り(`map(n => ({...n}))`)では\n * どの要素も一致せず、退役した親からの付け替えが位置に対して働く。\n */\nimport { getHomeParentListIndex, isSameListIndexValue, reparentListIndex } from \"./createListIndex\";\nimport { IListIndex } from \"./types\";\n\nconst listIndexesByList = new WeakMap<readonly unknown[], IListIndex[]>();\n\n/**\n * 差分で `newIndexes` から外れた行 = 消費者が画面から外した行。\n * 「生きた親集合に属さない」の判定材料。復活した行はこの集合から外れる。\n */\nconst retiredListIndexes = new WeakSet<IListIndex>();\n\n/** 差分が捨てた行を退役として記録する(`createListDiff` が呼ぶ)。 */\nexport function retireListIndexes(listIndexes: Iterable<IListIndex>): void {\n for (const listIndex of listIndexes) {\n retiredListIndexes.add(listIndex);\n }\n}\n\n/**\n * 差分が「いま生きている」と返した行の退役印を落とす(`createListDiff` が呼ぶ)。\n * 同じ配列インスタンスを戻す・タブを切り替えて戻る等で、退役した行は実際に生き返る。\n */\nexport function reviveListIndexes(listIndexes: Iterable<IListIndex>): void {\n for (const listIndex of listIndexes) {\n retiredListIndexes.delete(listIndex);\n }\n}\n\n/**\n * 差分がリストから外し、まだ戻っていない行か。読むだけの判定で、`$scan` の drain が\n * 行のアドレスの指す行がもうリストに居ないかを見る(scan/scanRuntime.ts の placementOf)。\n */\nexport function isRetiredListIndex(listIndex: IListIndex): boolean {\n return retiredListIndexes.has(listIndex);\n}\n\n/**\n * 台帳の行がぶら下がる親(`oldParent`)を、いま要求している親(`newParent`)へ\n * 付け替えてよいか。**退役した親のときだけ**真 ── 生きているなら共有であって\n * 陳腐化ではないので、main と同じく 1 組の行集合に合流させる。\n * 深さ(`position`)が変わる付け替えはしない。行の `position` / `length` は鋳造時に\n * 確定していて、そこがずれると絶対アドレスの段数が壊れる(bind-component が 1 本の\n * 配列を 2 つの深さから展開する形が実際にある)。\n */\nfunction canReparent(oldParent: IListIndex | null, newParent: IListIndex | null): boolean {\n if (oldParent === newParent) {\n // 自分が展開した行集合(ここが圧倒的多数)。ルート直下どうし(両方 null)もここ。\n return false;\n }\n if (oldParent === null || newParent === null) {\n return false;\n }\n if (oldParent.position !== newParent.position) {\n return false;\n }\n return retiredListIndexes.has(oldParent) && !retiredListIndexes.has(newParent);\n}\n\n/**\n * 要求している親(`newParent`)が、退役した `home` の**行そのもの**か。\n * 行を戻す普通のやり方(新しい配列に同じ要素を並べ直す)では差分が ListIndex を作り直すので、\n * home の ListIndex は二度と生き返らない。同じリスト要素を同じ深さで表している生きた行が\n * 現れたら、それが戻ってきた home である。\n */\nfunction isRestoredHome(\n home: IListIndex | null,\n oldParent: IListIndex | null,\n newParent: IListIndex | null,\n): boolean {\n if (home === null || newParent === null) {\n return false;\n }\n if (newParent === oldParent) {\n // すでにそこにある(=毎回 reparent して version を進めない)。\n return false;\n }\n if (!retiredListIndexes.has(home)) {\n // home が生きているなら「生き返った home」の分岐が扱う。\n return false;\n }\n if (retiredListIndexes.has(newParent) || newParent.position !== home.position) {\n return false;\n }\n return isSameListIndexValue(newParent, home);\n}\n\n/**\n * 行集合の親をどこへ向けるか。`null` なら何もしない。\n * 優先順位は **「生き返った home」>「戻ってきた home の行」>「陳腐化した親の付け替え」**。\n */\nfunction getRepairTarget(first: IListIndex, parentListIndex: IListIndex | null): IListIndex | null {\n const home = getHomeParentListIndex(first);\n const oldParent = first.parentListIndex;\n if (home !== null && home !== oldParent && !retiredListIndexes.has(home)) {\n return home;\n }\n if (isRestoredHome(home, oldParent, parentListIndex)) {\n return parentListIndex;\n }\n return canReparent(oldParent, parentListIndex) ? parentListIndex : null;\n}\n\n/**\n * 台帳を**引き当てるだけ**。行の親ポインタには触らない。\n * 観測(テスト・世代の後始末・`$scan` の drain が行の置き換わりを見る判定)と存在判定はこちらを使う。\n */\nexport function getListIndexesByList(list: readonly unknown[]): IListIndex[] | null {\n const listIndexes = listIndexesByList.get(list);\n if (typeof listIndexes === \"undefined\") {\n return null;\n }\n return listIndexes;\n}\n\n/**\n * 台帳を引き当て、**必要なら親ポインタを修理して**返す(#256)。\n * 引き当てのついでに行を書き換えるので、観測目的では使わないこと ──\n * 修理が要るのは「その親の文脈で値を解決する」経路(差分・アドレス解決)だけ。\n */\nexport function resolveListIndexesByList(\n list: readonly unknown[],\n parentListIndex: IListIndex | null,\n): IListIndex[] | null {\n const listIndexes = listIndexesByList.get(list);\n if (typeof listIndexes === \"undefined\") {\n return null;\n }\n const first = listIndexes[0];\n if (typeof first !== \"undefined\") {\n const target = getRepairTarget(first, parentListIndex);\n if (target !== null) {\n // 1 組の行集合は 1 つの親のもとにある、を保つ(差分が別の親の行を混ぜて\n // 作った集合も、ここで揃える)。\n for (const listIndex of listIndexes) {\n reparentListIndex(listIndex, target);\n }\n }\n }\n return listIndexes;\n}\n\nexport function setListIndexesByList(list: readonly unknown[], listIndexes: IListIndex[] | null): void {\n if (listIndexes === null) {\n listIndexesByList.delete(list);\n return;\n }\n listIndexesByList.set(list, listIndexes);\n}\n","import { IAbsoluteStateAddress } from \"../address/types\";\nimport { ICacheEntry } from \"./types\";\n\nconst cacheEntryByAbsoluteStateAddress: WeakMap<IAbsoluteStateAddress, ICacheEntry> = new WeakMap();\n\nexport function getCacheEntryByAbsoluteStateAddress(\n address: IAbsoluteStateAddress\n): ICacheEntry | null {\n return cacheEntryByAbsoluteStateAddress.get(address) ?? null;\n}\n\nexport function setCacheEntryByAbsoluteStateAddress(\n address: IAbsoluteStateAddress,\n cacheEntry: ICacheEntry | null\n): void {\n if (cacheEntry === null) {\n cacheEntryByAbsoluteStateAddress.delete(address);\n } else {\n cacheEntryByAbsoluteStateAddress.set(address, cacheEntry);\n }\n}\n\nexport function dirtyCacheEntryByAbsoluteStateAddress(\n address: IAbsoluteStateAddress\n): void {\n const cacheEntry = cacheEntryByAbsoluteStateAddress.get(address);\n if (cacheEntry) {\n cacheEntry.dirty = true;\n }\n}","// ===========================================================================\n// AUTO-GENERATED FILE - DO NOT EDIT.\n// Generated from /protocol/transition-runner.ts by scripts/sync-protocol-types.mjs.\n// Run `node scripts/sync-protocol-types.mjs` after editing the source.\n// ===========================================================================\n\n// transition-runner protocol — how a package that mutates the DOM hands that\n// mutation to whoever is arbitrating view transitions on the page.\n//\n// @wcstack/state and @wcstack/router must not depend on @wcstack/view-transition\n// (zero runtime dependencies, independently publishable), so the arbiter installs\n// itself on a well-known global symbol and the participants look it up lazily.\n// No arbiter installed means the mutation is invoked directly, synchronously —\n// byte-for-byte the behavior these packages had before the protocol existed.\n//\n// docs/view-transition-design.md §4 is the normative description.\n//\n// SINGLE SOURCE OF TRUTH: edit only this file (/protocol/transition-runner.ts), then run\n// `node scripts/sync-protocol-types.mjs` to regenerate the per-package copies\n// (packages/<pkg>/src/protocol/transitionRunner.ts). Those copies are generated — do not edit them.\n\n/**\n * Global key the arbiter installs itself under. `Symbol.for` so independently\n * loaded copies of this file (two CDN bundles on one page) still agree.\n */\nexport const TRANSITION_RUNNER_KEY = Symbol.for(\"wcstack.transition-runner\");\n\n/** Who is asking. Backs the arbiter's `for=` participant gate. */\nexport type TransitionSource = \"router\" | \"state\";\n\n/** `view-transition-name` assignment policy the arbiter declares for participants. */\nexport type TransitionNaming = \"manual\" | \"auto\";\n\nexport interface IWcsTransitionRunOptions {\n /** Participant id, for the `for=` gate and for diagnostics. */\n readonly source?: string;\n /** Transition types, where the environment supports `startViewTransition({ types })`. */\n readonly types?: readonly string[];\n}\n\nexport interface IWcsTransitionRunner {\n readonly protocol: \"wcs-transition-runner\";\n /** Integer protocol version. All versions >= 1 are participant-compatible. */\n readonly version: number;\n /** `\"auto\"` licenses a participant to assign `view-transition-name` itself. */\n readonly naming: TransitionNaming;\n /** Upper bound on auto-assigned names; past it a participant stops naming. */\n readonly namingLimit: number;\n /** Whether this participant animates at all. */\n accepts(source: string): boolean;\n /**\n * Invoke `mutate` inside a view transition when one is possible.\n *\n * Contract (docs/view-transition-design.md §4):\n * - `mutate` is invoked exactly once, whatever happens to the transition.\n * - The promise resolves once `mutate` has run — never waits for the animation.\n * - When no transition is started, `mutate` runs synchronously inside `run()`.\n * - It rejects only if `mutate` threw.\n */\n run(mutate: () => void, options?: IWcsTransitionRunOptions): Promise<void>;\n}\n\n/**\n * The installed arbiter, or null when there is none, it speaks a version this\n * reader does not, or it does not accept this participant.\n *\n * Looked up on every call rather than cached: the tag can be added, removed, or\n * reconfigured at any point in a page's life, and a stale cache would either\n * animate what the author just switched off or miss what they switched on.\n */\nexport function getTransitionRunner(source: string): IWcsTransitionRunner | null {\n const candidate = (globalThis as Record<symbol, unknown>)[TRANSITION_RUNNER_KEY] as\n | IWcsTransitionRunner\n | undefined;\n if (candidate === undefined || candidate === null) return null;\n if (candidate.protocol !== \"wcs-transition-runner\") return null;\n if (typeof candidate.version !== \"number\" || candidate.version < 1) return null;\n if (typeof candidate.run !== \"function\") return null;\n if (typeof candidate.accepts !== \"function\" || !candidate.accepts(source)) return null;\n return candidate;\n}\n\n/**\n * Run `mutate` under the installed arbiter, or directly when there is none.\n *\n * Returns `undefined` in the no-arbiter case instead of a resolved promise: the\n * state drain calls this on every batch, and awaiting is a caller's choice, not\n * an allocation the common path should pay for. `await` accepts both.\n */\nexport function runTransition(\n source: string,\n mutate: () => void,\n types?: readonly string[],\n): Promise<void> | undefined {\n const runner = getTransitionRunner(source);\n if (runner === null) {\n mutate();\n return undefined;\n }\n return runner.run(mutate, { source, types });\n}\n","import { IAbsoluteStateAddress } from \"../address/types\";\nimport type { IStateElement } from \"../components/types\";\nimport { beginStateListBaselineBatch, endStateListBaselineBatch } from \"../list/stateListBaseline\";\nimport { applyChangeFromBindings } from \"../apply/applyChangeFromBindings\";\nimport { peekBindingsForAddress } from \"../binding/getBindingSetByAbsoluteStateAddress\";\nimport { inSsr } from \"../config\";\nimport { MAX_PROPAGATION_HOPS } from \"../define\";\nimport { runTransition } from \"../protocol/transitionRunner\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { IPropagationContext } from \"../propagation/types\";\nimport { IBindingInfo } from \"../types\";\n\n/**\n * drain(_applyChange)終了通知のリスナー(docs/state-streams-design.md §3-2)。\n * バッチ内の更新アドレス(AbsoluteStateAddress のインスタンス同一性で\n * dedup 済みの Set)を受け取る。stream runtime の依存駆動 restart が\n * この通知を交差判定の入力にする。\n */\nexport type UpdateBatchListener = (batch: ReadonlySet<IAbsoluteStateAddress>) => void;\n\ninterface IRegisteredBatchListener {\n readonly listener: UpdateBatchListener;\n readonly priority: number;\n}\n\nconst updateBatchListeners: IRegisteredBatchListener[] = [];\n\n/**\n * 書き込みの enqueue を見る機能(設計案 H2 の enqueue 側)。`$watch` の連鎖深さ(watch/chainDepth.ts)と\n * `on` scan の保留 reset(scan/eventReset.ts)が install で登録する。互いに独立なので順序契約は無い。\n * 登録が無ければ enqueue は配列長 0 の判定 1 回で抜ける。\n */\nexport type EnqueueListener = (absoluteAddress: IAbsoluteStateAddress) => void;\n\nconst enqueueListeners: EnqueueListener[] = [];\n\n/** 機能の install が呼ぶ(冪等 — 同じ listener は 1 回だけ) */\nexport function registerEnqueueListener(listener: EnqueueListener): void {\n if (!enqueueListeners.includes(listener)) {\n enqueueListeners.push(listener);\n }\n}\n\n/**\n * drain 終了リスナーを登録する。\n *\n * `priority` の昇順に呼ばれる(同値は登録順)。機構間の実行順序\n * (`$scan` → `$watch` → `$streams` restart。前の 2 つは同じ watch リスナーの中の順序で、\n * `$scan` は畳んで書いてから `$watch` を発火する —\n * docs/state-watch-hook-design.md §3-2 層 1・docs/state-scan-design.md D11)は\n * この優先度で固定する — import 順に順序を持たせると、無関係な import 整理で\n * 静かに壊れるため。定数は define.ts の `*_LISTENER_PRIORITY` を使うこと。\n */\nexport function registerUpdateBatchListener(listener: UpdateBatchListener, priority = 0): void {\n // 挿入ソート: 同値優先度の中では登録順を保つ(find は最初の「より大きい」要素を指す)\n const index = updateBatchListeners.findIndex((registered) => registered.priority > priority);\n const entry = { listener, priority };\n if (index === -1) {\n updateBatchListeners.push(entry);\n } else {\n updateBatchListeners.splice(index, 0, entry);\n }\n}\n\n/**\n * drain 終了リスナーを解除する(テスト間の分離用)。\n */\nexport function unregisterUpdateBatchListener(listener: UpdateBatchListener): void {\n const index = updateBatchListeners.findIndex((registered) => registered.listener === listener);\n if (index !== -1) {\n updateBatchListeners.splice(index, 1);\n }\n}\n\n/**\n * 全リスナーに drain のバッチを優先度順で通知する。\n * リスナーの throw は握りつぶさない(内部バグの隠蔽防止)。\n * stream / watch 側リスナーが entry ごとに自前で try/catch する契約(設計書 §3-2)。\n */\nfunction notifyUpdateBatchListeners(batch: ReadonlySet<IAbsoluteStateAddress>): void {\n // 反復中の register / unregister(ハンドラ内の切断・再 set)に耐えるためコピーする\n for (const registered of updateBatchListeners.slice()) {\n registered.listener(batch);\n }\n}\n\n/**\n * 遷移越しの適用が失敗したときの報告。\n *\n * 遷移の中では例外を同期的に呼び出し元へ投げ返せない。今日の drain は\n * queueMicrotask の中で throw する = uncaught として観測されるので、それと同じ\n * 「loud に出す」挙動へ揃える。握り潰すと `$updatedCallback` の throw が黙って\n * 消える(README の 3 層表が定める伝播の契約が破れる)。\n */\nexport function reportDeferredApplyFailure(error: unknown): void {\n queueMicrotask(() => { throw error; });\n}\n\n/** queue に積まれる update record(address + 書き込み時点の因果 context) */\ninterface IQueuedUpdateRecord {\n readonly absoluteAddress: IAbsoluteStateAddress;\n readonly context: IPropagationContext | null;\n}\n\nclass Updater {\n private _queueUpdateRecords: IQueuedUpdateRecord[] = [];\n /**\n * 描画だけをやり直すアドレス(`enqueueRenderOnlyAddress`)。書き込みの record とは別に持つ —\n * drain 終了リスナーへ渡すバッチにも、`hasQueuedPath`(`on` scan の保留 reset の判定)にも混ぜない。\n */\n private _queueRenderOnlyAddresses: IAbsoluteStateAddress[] = [];\n constructor() {\n }\n\n enqueueAbsoluteAddress(\n absoluteAddress: IAbsoluteStateAddress,\n context: IPropagationContext | null = null,\n ): void {\n // 書き込みの時点を見る機能(`$watch` の連鎖のマーク・`on` scan の `resetOn` の保留)。\n // install されていなければ配列長 0 の判定 1 回\n for (let i = 0; i < enqueueListeners.length; i++) {\n enqueueListeners[i](absoluteAddress);\n }\n const requireStartProcess = this._isQueueEmpty();\n this._queueUpdateRecords.push({ absoluteAddress, context });\n if (requireStartProcess) {\n this._scheduleDrain();\n }\n }\n\n /**\n * 描画だけをやり直させる(#4)。値を書いたわけではないので、書き込みの着地としては扱わない —\n * binding の適用には載せるが、drain 終了リスナー(`$scan` / `$watch` / `$streams` restart)へ渡す\n * バッチに入れず、`$watch` の連鎖や `on` scan の reset の印も付けない。同じバッチで同じアドレスが\n * 書き込みとしても積まれていれば、そちらが着地になる。\n * 呼び手は要素書き込みの入れ替えの完了(proxy/methods/setByAddress.ts の notifySwappedList)。\n */\n enqueueRenderOnlyAddress(absoluteAddress: IAbsoluteStateAddress): void {\n const requireStartProcess = this._isQueueEmpty();\n this._queueRenderOnlyAddresses.push(absoluteAddress);\n if (requireStartProcess) {\n this._scheduleDrain();\n }\n }\n\n private _isQueueEmpty(): boolean {\n return this._queueUpdateRecords.length === 0 && this._queueRenderOnlyAddresses.length === 0;\n }\n\n private _scheduleDrain(): void {\n // このバッチのあいだ、依存ウォークと読みが観測したリスト値は保留にする。\n // 確定は drain の finally(list/stateListBaseline.ts の頭のコメント)。\n beginStateListBaselineBatch();\n queueMicrotask(() => {\n const updateRecords = this._queueUpdateRecords;\n const renderOnlyAddresses = this._queueRenderOnlyAddresses;\n this._queueUpdateRecords = [];\n this._queueRenderOnlyAddresses = [];\n this._applyChange(updateRecords, renderOnlyAddresses);\n });\n }\n\n /**\n * まだ drain されていない書き込み(次のバッチ)に、この state のこのパスがあるか。\n * drain の最中のキューは次のバッチの分だけになっている(_applyChange の前に差し替える)。\n * `on` scan の保留 reset を、発火しない drain で捨ててよいかの判定に使う(scan/eventReset.ts)。\n */\n hasQueuedPath(stateElement: IStateElement, path: string): boolean {\n return this._queueUpdateRecords.some((record) =>\n record.absoluteAddress.absolutePathInfo.stateElement === stateElement\n && record.absoluteAddress.absolutePathInfo.pathInfo.path === path);\n }\n\n // テスト用に公開\n testApplyChange(\n absoluteAddresses: IAbsoluteStateAddress[],\n contexts?: readonly (IPropagationContext | null)[],\n ): void {\n this._applyChange(absoluteAddresses.map((absoluteAddress, index) => ({\n absoluteAddress,\n context: contexts?.[index] ?? null,\n })));\n }\n\n private _applyChange(\n updateRecords: IQueuedUpdateRecord[],\n renderOnlyAddresses: readonly IAbsoluteStateAddress[] = [],\n ): void {\n // Note: AbsoluteStateAddress はキャッシュされているため、\n // 同一の (stateElement, address) は同じインスタンスとなり、\n // Map / Set による重複排除が正しく機能する。\n // coalescing は last-write-wins: 同じ address は最後の update の\n // (値は state 側が既に保持) context をそのまま採用する(設計書 §4.1)。\n // visitedEdges の合成や synthetic transaction への置換は行わない。\n //\n // このメソッドの反復は for...of を使わない(添字ループと Map#forEach)。drain は 1 バッチに 1 回しか\n // 呼ばれないので最適化段に上がらず、for...of は反復ごとに結果オブジェクト(Map なら [key, value] の\n // 配列も)を割り当てる。cold の 1,000 行生成では行ごとに数件の依存アドレスが積まれ、その分が\n // 生成の割り当ての 1 割近くを占めていた(設計 R5)。\n const contextByAbsoluteAddress = new Map<IAbsoluteStateAddress, IPropagationContext | null>();\n // drain 終了リスナーへ渡すのは書き込みの着地だけ。描画だけのアドレスは、この後で適用の対象に足す\n // (同じアドレスの書き込みがあれば、その context のまま着地として残る)。Map の鍵から作り直さず\n // ここで積む(鍵の iterator は反復ごとに割り当てる。順序は同じ = 最初に現れた順)\n const landedAddresses = new Set<IAbsoluteStateAddress>();\n for (let i = 0; i < updateRecords.length; i++) {\n const record = updateRecords[i];\n const previous = contextByAbsoluteAddress.get(record.absoluteAddress);\n if (\n devtoolsSink !== null\n && typeof previous !== \"undefined\" && previous !== null\n && record.context !== null\n && previous.transactionId !== record.context.transactionId\n ) {\n devtoolsSink({\n type: \"propagation:coalesced\",\n absoluteAddress: record.absoluteAddress,\n droppedTransactionId: previous.transactionId,\n winnerTransactionId: record.context.transactionId,\n });\n }\n contextByAbsoluteAddress.set(record.absoluteAddress, record.context);\n landedAddresses.add(record.absoluteAddress);\n }\n for (let i = 0; i < renderOnlyAddresses.length; i++) {\n const absoluteAddress = renderOnlyAddresses[i];\n if (!contextByAbsoluteAddress.has(absoluteAddress)) {\n contextByAbsoluteAddress.set(absoluteAddress, null);\n }\n }\n const processBindings: IBindingInfo[] = [];\n const propagationContextByBinding = new Map<IBindingInfo, IPropagationContext | null>();\n contextByAbsoluteAddress.forEach((context, absoluteAddress) => {\n if (context !== null && context.hop >= MAX_PROPAGATION_HOPS) {\n // hop 上限超過: この transaction の未処理 record だけを quarantine する。\n // 既に適用した値は戻さず、updater から例外は投げない(設計書 §4 規則 6)。\n console.error(`[@wcstack/state] propagation hop limit exceeded; update record quarantined.`, {\n path: absoluteAddress.absolutePathInfo.pathInfo.path,\n transactionId: context.transactionId,\n hop: context.hop,\n maxHops: MAX_PROPAGATION_HOPS,\n });\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"propagation:hop-limit\",\n absoluteAddress,\n transactionId: context.transactionId,\n hop: context.hop,\n });\n }\n return;\n }\n // peek: バインディングの無いアドレス(リスト置換で enqueue される中間\n // アドレス等)に空エントリを生成・蓄積しない。エントリは単一 binding\n // (通常ケース)か Set(同一アドレスに 2 本以上)のどちらか。\n // 従来台帳 → パターン台帳(リスト行)の順で引く。\n const entry = peekBindingsForAddress(absoluteAddress);\n if (entry === undefined) {\n return;\n }\n if (entry instanceof Set) {\n for(const binding of entry) {\n if (binding.replaceNode.isConnected === false) {\n // 切断されているバインディングは無視\n continue;\n }\n processBindings.push(binding);\n if (context !== null) {\n propagationContextByBinding.set(binding, context);\n }\n }\n } else if (entry.replaceNode.isConnected !== false) {\n processBindings.push(entry);\n if (context !== null) {\n propagationContextByBinding.set(entry, context);\n }\n }\n });\n // drain 終了フック: binding 適用後に dedup 済みバッチを通知する(設計書 §3-2)。\n // testApplyChange も同じ _applyChange を通るため、テストから同期に駆動できる。\n // quarantine された address も state 値は適用済みのため通知対象に含める。\n //\n // try/finally なのは、適用側が throw しても `$watch` / `$streams` restart を\n // 落とさないため。binding 1 本の失敗は applyChangeFromBindings が隔離するので\n // ここへ来るのは $updatedCallback の throw(契約どおり loud に伝播させる)等に\n // 限られるが、そのとき drain フックまで道連れにすると「機構間の順序は固定」\n // (README の 3 層表)が黙って破れる。例外は握らない = 伝播は維持する。\n try {\n const applyBindings = (): void => {\n // context が無い場合は従来どおり 1 引数で呼ぶ(呼び出し契約の互換維持)\n if (propagationContextByBinding.size > 0) {\n applyChangeFromBindings(processBindings, propagationContextByBinding);\n } else {\n applyChangeFromBindings(processBindings);\n }\n };\n // View transition 参加点(docs/view-transition-design.md §7.2)。arbiter が\n // 居なければ runTransition はその場で applyBindings を呼び、undefined を返す\n // = 従来と完全に同じ同期適用。SSR では遷移そのものを持たない(G5)。\n //\n // 適用する binding が 0 本のバッチは arbiter へ渡さない。書き込みはバインドの\n // 有無に関わらず enqueue される(setByAddress)ため、headless なパス\n // (`$watch` 専用・`$streams` の内部状態・リスト置換の中間アドレス)への\n // 書き込みだけでもここへ到達する。それでページ全体をスナップショットするのは\n // 無駄なだけでなく、既定の mode=\"latest\" では「アニメーションすべき DOM 変更が\n // 無い遷移」が実行中の本物の遷移をスキップしてしまう(ルート遷移が毎回途中で\n // 切れる/active が空撃ちで振動する)。\n if (inSsr() || processBindings.length === 0) {\n applyBindings();\n } else {\n const pending = runTransition(\"state\", applyBindings);\n if (pending !== undefined) {\n pending.catch(reportDeferredApplyFailure);\n }\n }\n } finally {\n // バッチ中に溜めたリスト差分基準を確定する。notifyUpdateBatchListeners より先に\n // 置くのは、リスナー($watch / $streams restart)の中で走る書き込みが\n // 「このバッチの結果」を基準として見るべきだから。\n endStateListBaselineBatch();\n notifyUpdateBatchListeners(landedAddresses);\n }\n }\n\n}\n\n// コンストラクタは空でフィールド初期化だけ(純粋な割り当て)。バンドラが未使用時に落とせるよう\n// 明示する: ヘルパーだけの import(defineState / 型 / version)にランタイムを残さない\nconst updater = /*#__PURE__*/ new Updater();\n\nexport function getUpdater(): Updater {\n return updater;\n}\n\n// テスト用にprivateメソッドを公開\nexport const __private__ = {\n Updater,\n reportDeferredApplyFailure,\n};\n","/**\n * keyedDependency.ts — 鍵付き購読(`$eq(path, key)` / `$eqPath(path, keyPath)` / `$eqIndex(path, level)`)。\n *\n * 「`path` の値が鍵に等しいか」だけを知りたい getter は、`path` のパターン辺ではなく\n * その鍵の下に自分の行アドレスを登録する。`path` への書き込みは、旧値と新値の鍵に\n * 登録された行だけを dirty 化して enqueue する(パターン辺なら全行に展開されるところを\n * 高々 2 行に抑える。docs/state-next-major-tech-survey.md §10.1・§10.10、要件 N6 / D7)。\n *\n * - 行の購読は、差分がその行の listIndex を退役させた時点で落とす\n * (`dropKeyedSubscriptionsByListIndex`、list/createListDiff.ts が呼ぶ)。差分が行を\n * 復活させたときは、getter の再評価が購読を張り直す。\n * - `$eqIndex` は行の index を鍵にする(getter を index 依存には記録しない)。段によって 2 通り:\n * - 最内段(getter 自身の行の段)は行ごとの購読を持たず、リスト(listIndex 配列)単位の\n * 監視を 1 つ置く(`registerIndexWatcher`)。書き込みは `indexes[旧値]` と `indexes[新値]`\n * の行を、差分は配列が変わったとき(`moveIndexWatchers`)「最後の値の位置にいた行と来た行」\n * だけを enqueue する。移動行ごとの処理も退役時の解除も無い。\n * - 外側の段は行ごとに index を鍵にして購読し、差分が index を付け替えるとき\n * (syncListIndexes → `rekeyIndexSubscriptions`)に鍵も付け替える。移動した行は\n * 「`path` の最後の値が旧 index か新 index に等しい」ときだけ enqueue する。\n * どちらも 1 行削除で再評価されるのは高々 2 行。\n * - `path` の最後の値は登録時と書き込み時に控える(差分側の判定に使う)。書き込みが旧値を\n * 読めなかったとき(オブジェクトの書き込みは同値ガードを通らない)は、これを旧い鍵として使う\n * — 読めないまま新しい鍵の行だけを再評価すると、前に選ばれていた行が真のまま残る。\n * - `path` の祖先への書き込み(`$eq(\"sel.id\")` に対する `sel = {…}`)は `path` への書き込みを\n * 経ないので、祖先 → 配下の鍵付きパスの逆引きを持ち、旧い親と新しい親から鍵を辿って知らせる\n * (`keyedDescendantDependents`)。\n *\n * 不変条件: 同じ (アドレス, path) の購読は 1 つ。`keyByPathByAddress` が現在の鍵の正本で、\n * 台帳(`byPath`)とは常に一致する。退役した行のエントリは台帳・逆引きの両方から同時に消える。\n * 制約: Map の鍵比較は SameValueZero(`-0` と `+0` は同じ鍵、`NaN` 同士は同じ鍵)。\n */\nimport { IAbsoluteStateAddress, IPathInfo } from \"../address/types\";\nimport { getPathInfo } from \"../address/PathInfo\";\nimport { WILDCARD } from \"../define\";\nimport { createStateAddress } from \"../address/StateAddress\";\nimport { liftAddress } from \"../address/liftAddress\";\nimport { isRetiredListIndex } from \"../list/listIndexesByList\";\nimport { dirtyCacheEntryByAbsoluteStateAddress } from \"../cache/cacheEntryByAbsoluteStateAddress\";\nimport { IStateElement } from \"../components/types\";\nimport { IListIndex } from \"../list/types\";\nimport { getUpdater } from \"../updater/updater\";\n\ntype KeyMap = Map<unknown, Set<IAbsoluteStateAddress>>;\ninterface IElementLedger {\n readonly byPath: Map<string, KeyMap>;\n /** `path` の最後に見た値(登録時か書き込み時)。差分側の鍵付け替えが読む */\n readonly lastValue: Map<string, unknown>;\n /** 祖先の逆引きに載せ終えた path */\n readonly recorded: Set<string>;\n /**\n * getter の評価中に呼ばれたが、`path` が getter かその下にあるので鍵付きで購読できず、追跡付きの\n * 読みに落ちた path。台帳の動作には使わず、DevTools の要約(要件 D17)だけが読む\n */\n readonly tracked: Set<string>;\n}\ninterface IEntry {\n readonly stateElement: IStateElement;\n readonly path: string;\n readonly absAddress: IAbsoluteStateAddress;\n /** `$eqIndex` のとき、index を鍵にしている段の listIndex(それ以外は null) */\n readonly levelListIndex: IListIndex | null;\n}\nconst ledgerByElement = new WeakMap<IStateElement, IElementLedger>();\n// アドレス → (path → 現在の鍵)。再評価した getter が購読を新しい鍵へ移すための逆引き\nconst keyByPathByAddress = new WeakMap<IAbsoluteStateAddress, Map<string, unknown>>();\n// 行の listIndex にぶら下がる購読(退役時に落とす)\nconst entriesByListIndex = new WeakMap<IListIndex, IEntry[]>();\n// index を鍵にしている購読を、その index の段の listIndex から引く(付け替え用)\nconst indexKeyedByListIndex = new WeakMap<IListIndex, IEntry[]>();\n// 一度も登録が無ければ差分側のフックは Map 参照すら行わない\nlet anyRegistered = false;\n\n/**\n * リスト単位の index 監視(`$eqIndex` の最内段)。行ごとの購読を持たず、書き込みは\n * `indexes[旧値]` と `indexes[新値]` の行を、差分は「最後の値の位置にいた行と来た行」だけを\n * enqueue する。差分がリストの listIndex 配列を作り直したら監視を新しい配列へ移す。\n */\ninterface IIndexWatcher {\n readonly stateElement: IStateElement;\n readonly path: string;\n /** 監視中のリストの listIndex 配列(差分で付け替わる) */\n indexes: IListIndex[];\n /** この監視を張った getter のパス(同じリストの複数 getter を 1 監視で扱う) */\n readonly getters: Set<IPathInfo>;\n}\nconst watchersByElement = new WeakMap<IStateElement, Map<string, Set<IIndexWatcher>>>();\nconst watchersByIndexes = new WeakMap<IListIndex[], IIndexWatcher[]>();\n// 祖先パス → その配下の鍵付きパス(祖先への書き込みを配下の鍵付き購読へ届ける)\nconst descendantsByElement = new WeakMap<IStateElement, Map<string, Set<string>>>();\nconst EMPTY: IAbsoluteStateAddress[] = [];\n\n/** `path` の祖先を逆引きに載せる(同じ path は 1 回だけ)。祖先の無いトップレベルの path は載せない */\nfunction recordAncestors(stateElement: IStateElement, path: string): void {\n const ledger = ledgerOf(stateElement);\n if (ledger.recorded.has(path)) {\n return;\n }\n ledger.recorded.add(path);\n const cumulativePaths = getPathInfo(path).cumulativePaths;\n if (cumulativePaths.length < 2) {\n return;\n }\n let byAncestor = descendantsByElement.get(stateElement);\n if (typeof byAncestor === \"undefined\") {\n descendantsByElement.set(stateElement, byAncestor = new Map());\n }\n for (let i = 0; i < cumulativePaths.length - 1; i++) {\n let descendants = byAncestor.get(cumulativePaths[i]);\n if (typeof descendants === \"undefined\") {\n byAncestor.set(cumulativePaths[i], descendants = new Set());\n }\n descendants.add(path);\n }\n}\n\nfunction ledgerOf(stateElement: IStateElement): IElementLedger {\n let ledger = ledgerByElement.get(stateElement);\n if (typeof ledger === \"undefined\") {\n ledgerByElement.set(stateElement, ledger = { byPath: new Map(), lastValue: new Map(), recorded: new Set(), tracked: new Set() });\n }\n return ledger;\n}\n\nfunction keyMapOf(ledger: IElementLedger, path: string): KeyMap {\n let keyMap = ledger.byPath.get(path);\n if (typeof keyMap === \"undefined\") {\n ledger.byPath.set(path, keyMap = new Map());\n }\n return keyMap;\n}\n\nfunction addToKey(keyMap: KeyMap, key: unknown, absAddress: IAbsoluteStateAddress): void {\n let set = keyMap.get(key);\n if (typeof set === \"undefined\") {\n keyMap.set(key, set = new Set());\n }\n set.add(absAddress);\n}\n\n/** 鍵から行を外し、空になった鍵は Map から消す(オブジェクトの鍵を行の退役後まで握らない) */\nfunction removeFromKey(keyMap: KeyMap, key: unknown, absAddress: IAbsoluteStateAddress): void {\n const set = keyMap.get(key)!;\n set.delete(absAddress);\n if (set.size === 0) {\n keyMap.delete(key);\n }\n}\n\n/** 台帳へ登録する。既に同じ (アドレス, path) が登録済みなら鍵を移すだけで、false を返す */\nfunction subscribe(ledger: IElementLedger, path: string, key: unknown, absAddress: IAbsoluteStateAddress): boolean {\n const keyMap = keyMapOf(ledger, path);\n let previous = keyByPathByAddress.get(absAddress);\n if (typeof previous === \"undefined\") {\n keyByPathByAddress.set(absAddress, previous = new Map());\n }\n if (previous.has(path)) {\n const oldKey = previous.get(path);\n if (!Object.is(oldKey, key)) {\n removeFromKey(keyMap, oldKey, absAddress);\n previous.set(path, key);\n addToKey(keyMap, key, absAddress);\n }\n return false;\n }\n previous.set(path, key);\n addToKey(keyMap, key, absAddress);\n return true;\n}\n\nfunction pushEntry(map: WeakMap<IListIndex, IEntry[]>, listIndex: IListIndex, entry: IEntry): void {\n const entries = map.get(listIndex);\n if (typeof entries === \"undefined\") {\n map.set(listIndex, [entry]);\n } else {\n entries.push(entry);\n }\n}\n\nfunction record(ledger: IElementLedger, path: string, current: unknown, absAddress: IAbsoluteStateAddress, isNew: boolean, entry: IEntry): void {\n ledger.lastValue.set(path, current);\n if (!isNew) {\n return;\n }\n // 行の外(トップレベルの getter)からの登録は listIndex を持たず、退役で落ちることもない\n if (absAddress.listIndex !== null) {\n pushEntry(entriesByListIndex, absAddress.listIndex, entry);\n }\n if (entry.levelListIndex !== null) {\n pushEntry(indexKeyedByListIndex, entry.levelListIndex, entry);\n }\n}\n\n/** `$eq` / `$eqPath`: 評価中の getter のアドレスを `key` の下に登録する。`current` は今読んだ `path` の値 */\nexport function registerKeyedDependency(\n stateElement: IStateElement,\n path: string,\n key: unknown,\n absAddress: IAbsoluteStateAddress,\n current: unknown,\n): void {\n anyRegistered = true;\n const ledger = ledgerOf(stateElement);\n recordAncestors(stateElement, path);\n const isNew = subscribe(ledger, path, key, absAddress);\n record(ledger, path, current, absAddress, isNew, { stateElement, path, absAddress, levelListIndex: null });\n}\n\n/** `$eqIndex`: `levelListIndex.index` を鍵にして登録する。差分が index を変えたとき鍵も付け替える */\nexport function registerIndexKeyedDependency(\n stateElement: IStateElement,\n path: string,\n levelListIndex: IListIndex,\n absAddress: IAbsoluteStateAddress,\n current: unknown,\n): void {\n anyRegistered = true;\n const ledger = ledgerOf(stateElement);\n recordAncestors(stateElement, path);\n const isNew = subscribe(ledger, path, levelListIndex.index, absAddress);\n record(ledger, path, current, absAddress, isNew, { stateElement, path, absAddress, levelListIndex });\n}\n\n/** getter の評価中の `$eq` / `$eqPath` / `$eqIndex` が、`path` が getter 由来のため追跡付きの読みに落ちた */\nexport function recordTrackedKeyedPath(stateElement: IStateElement, path: string): void {\n ledgerOf(stateElement).tracked.add(path);\n}\n\n/** DevTools の要約(devtools/keyedSubscriptions.ts)が読む、この state の台帳。読むだけで変えない */\nexport interface IKeyedLedgerView {\n readonly byPath: ReadonlyMap<string, ReadonlyMap<unknown, ReadonlySet<IAbsoluteStateAddress>>>;\n readonly lastValue: ReadonlyMap<string, unknown>;\n readonly tracked: ReadonlySet<string>;\n /** `$eqIndex` の最内段のリスト単位の監視(path → 監視) */\n readonly watchers: ReadonlyMap<string, ReadonlySet<unknown>> | undefined;\n}\n\nexport function getKeyedLedgerView(stateElement: IStateElement): IKeyedLedgerView | null {\n const ledger = ledgerByElement.get(stateElement);\n if (typeof ledger === \"undefined\") {\n return null;\n }\n return { byPath: ledger.byPath, lastValue: ledger.lastValue, tracked: ledger.tracked, watchers: watchersByElement.get(stateElement) };\n}\n\nexport function hasKeyedDependents(stateElement: IStateElement, path: string): boolean {\n return ledgerByElement.get(stateElement)?.byPath.has(path) === true\n || watchersByElement.get(stateElement)?.has(path) === true;\n}\n\n/** `$eqIndex` の最内段: リスト(listIndex 配列)単位の監視を 1 つ登録し、getter のパスを足す */\nexport function registerIndexWatcher(\n stateElement: IStateElement,\n path: string,\n getterPathInfo: IPathInfo,\n indexes: IListIndex[],\n current: unknown,\n): void {\n anyRegistered = true;\n ledgerOf(stateElement).lastValue.set(path, current);\n recordAncestors(stateElement, path);\n let byPath = watchersByElement.get(stateElement);\n if (typeof byPath === \"undefined\") {\n watchersByElement.set(stateElement, byPath = new Map());\n }\n let watchers = byPath.get(path);\n if (typeof watchers === \"undefined\") {\n byPath.set(path, watchers = new Set());\n }\n let byList = watchersByIndexes.get(indexes);\n let watcher: IIndexWatcher | undefined;\n if (typeof byList === \"undefined\") {\n watchersByIndexes.set(indexes, byList = []);\n } else {\n watcher = byList.find((w) => w.stateElement === stateElement && w.path === path);\n }\n if (typeof watcher === \"undefined\") {\n watcher = { stateElement, path, indexes, getters: new Set() };\n byList.push(watcher);\n watchers.add(watcher);\n }\n watcher.getters.add(getterPathInfo);\n}\n\nfunction watchedRowsAt(watcher: IIndexWatcher, key: unknown, out: IAbsoluteStateAddress[]): void {\n if (typeof key !== \"number\") {\n return;\n }\n const listIndex = watcher.indexes[key];\n if (typeof listIndex === \"undefined\") {\n return;\n }\n for (const getterPathInfo of watcher.getters) {\n out.push(liftAddress(watcher.stateElement, createStateAddress(getterPathInfo, listIndex)));\n }\n}\n\n/**\n * 差分がリストの listIndex 配列を `oldIndexes` → `newIndexes` に付け替えた: 監視を新しい配列へ移し、\n * `path` の最後の値の位置にいた行と来た行(違うときだけ)を dirty 化して enqueue する。\n * 同じ差分の 2 回目の呼び出し(キャッシュ命中)は旧配列に監視が無いので何もしない。\n */\nexport function moveIndexWatchers(oldIndexes: IListIndex[], newIndexes: IListIndex[]): void {\n if (!anyRegistered || oldIndexes === newIndexes) {\n return;\n }\n const watchers = watchersByIndexes.get(oldIndexes);\n if (typeof watchers === \"undefined\") {\n return;\n }\n watchersByIndexes.delete(oldIndexes);\n const existing = watchersByIndexes.get(newIndexes);\n watchersByIndexes.set(newIndexes, typeof existing === \"undefined\" ? watchers : existing.concat(watchers));\n for (const watcher of watchers) {\n watcher.indexes = newIndexes;\n const last = ledgerOf(watcher.stateElement).lastValue.get(watcher.path);\n if (typeof last !== \"number\") {\n continue;\n }\n const before = oldIndexes[last];\n const after = newIndexes[last];\n if (before === after) {\n continue;\n }\n for (const listIndex of [before, after]) {\n if (typeof listIndex === \"undefined\" || isRetiredListIndex(listIndex)) {\n continue;\n }\n for (const getterPathInfo of watcher.getters) {\n const absAddress = liftAddress(watcher.stateElement, createStateAddress(getterPathInfo, listIndex));\n dirtyCacheEntryByAbsoluteStateAddress(absAddress);\n getUpdater().enqueueAbsoluteAddress(absAddress, null);\n }\n }\n }\n}\n\nfunction collect(set: Set<IAbsoluteStateAddress> | undefined, out: IAbsoluteStateAddress[]): void {\n if (typeof set === \"undefined\") {\n return;\n }\n for (const address of set) {\n out.push(address);\n }\n}\n\n/**\n * `path` への書き込み: 旧値(同値ガードが読めたとき)と新値の鍵に登録された行アドレス。\n * 控えていた最後の値が旧値と違う(旧値を読めなかった)ときは、その鍵の行も加える。\n * 新値を `path` の最後の値として控える。呼び出し側は hasKeyedDependents で門を通す。\n */\nexport function keyedDependents(\n stateElement: IStateElement,\n path: string,\n hasOldKey: boolean,\n oldKey: unknown,\n newKey: unknown,\n): IAbsoluteStateAddress[] {\n const ledger = ledgerByElement.get(stateElement);\n const keyMap = ledger?.byPath.get(path);\n const watchers = watchersByElement.get(stateElement)?.get(path);\n if (typeof ledger === \"undefined\" || (typeof keyMap === \"undefined\" && typeof watchers === \"undefined\")) {\n return EMPTY;\n }\n const hasLast = ledger.lastValue.has(path);\n const last = ledger.lastValue.get(path);\n ledger.lastValue.set(path, newKey);\n const out: IAbsoluteStateAddress[] = [];\n const newDiffers = !hasOldKey || !Object.is(oldKey, newKey);\n // 行が最後に見た値。旧値を読めなかったときに真のまま残る行はここにいる\n const lastDiffers = hasLast && (!hasOldKey || !Object.is(last, oldKey)) && !Object.is(last, newKey);\n if (typeof keyMap !== \"undefined\") {\n if (hasOldKey) {\n collect(keyMap.get(oldKey), out);\n }\n if (lastDiffers) {\n collect(keyMap.get(last), out);\n }\n if (newDiffers) {\n collect(keyMap.get(newKey), out);\n }\n }\n if (typeof watchers !== \"undefined\") {\n for (const watcher of watchers) {\n if (hasOldKey) {\n watchedRowsAt(watcher, oldKey, out);\n }\n if (lastDiffers) {\n watchedRowsAt(watcher, last, out);\n }\n if (newDiffers) {\n watchedRowsAt(watcher, newKey, out);\n }\n }\n }\n return out;\n}\n\nexport function hasKeyedDescendants(stateElement: IStateElement, path: string): boolean {\n return descendantsByElement.get(stateElement)?.has(path) === true;\n}\n\n/** `value` から `segments` を辿った値(途中がオブジェクトでなければ undefined) */\nfunction valueAt(value: unknown, segments: readonly string[]): unknown {\n let current = value;\n for (const segment of segments) {\n if (typeof current !== \"object\" || current === null) {\n return undefined;\n }\n current = (current as Record<string, unknown>)[segment];\n }\n return current;\n}\n\n/**\n * `path`(鍵付きパスの祖先)への書き込み: 配下の鍵付きパスごとに、旧い親と新しい親から鍵を辿り、\n * その鍵の行を返す(`keyedDependents` と同じ扱い)。残りのパスにワイルドカードがあると行ごとの鍵が\n * 辿れないので、そのパスに購読している行をすべて返す。呼び出し側は hasKeyedDescendants で門を通す。\n */\nexport function keyedDescendantDependents(\n stateElement: IStateElement,\n path: string,\n oldValue: unknown,\n newValue: unknown,\n): IAbsoluteStateAddress[] {\n const depth = getPathInfo(path).segments.length;\n const out: IAbsoluteStateAddress[] = [];\n for (const descendant of descendantsByElement.get(stateElement)!.get(path)!) {\n const rest = getPathInfo(descendant).segments.slice(depth);\n if (rest.includes(WILDCARD)) {\n allDependents(stateElement, descendant, out);\n continue;\n }\n for (const address of keyedDependents(stateElement, descendant, true, valueAt(oldValue, rest), valueAt(newValue, rest))) {\n out.push(address);\n }\n }\n return out;\n}\n\n/** `path` に鍵付きで購読しているすべての行 */\nfunction allDependents(stateElement: IStateElement, path: string, out: IAbsoluteStateAddress[]): void {\n const keyMap = ledgerByElement.get(stateElement)!.byPath.get(path);\n if (typeof keyMap !== \"undefined\") {\n for (const set of keyMap.values()) {\n collect(set, out);\n }\n }\n const watchers = watchersByElement.get(stateElement)?.get(path);\n if (typeof watchers !== \"undefined\") {\n for (const watcher of watchers) {\n for (let index = 0; index < watcher.indexes.length; index++) {\n watchedRowsAt(watcher, index, out);\n }\n }\n }\n}\n\nfunction removeIndexEntry(entry: IEntry): void {\n const entries = indexKeyedByListIndex.get(entry.levelListIndex!)!;\n const at = entries.indexOf(entry);\n entries.splice(at, 1);\n}\n\n/** 差分が `listIndex` を退役させた: その行にぶら下がる購読を台帳と逆引きから落とす(復活した行は再評価で張り直す) */\nexport function dropKeyedSubscriptionsByListIndex(listIndex: IListIndex): void {\n if (!anyRegistered) {\n return;\n }\n const entries = entriesByListIndex.get(listIndex);\n if (typeof entries === \"undefined\") {\n return;\n }\n entriesByListIndex.delete(listIndex);\n for (const entry of entries) {\n const { stateElement, path, absAddress } = entry;\n const keys = keyByPathByAddress.get(absAddress)!;\n const key = keys.get(path);\n keys.delete(path);\n removeFromKey(ledgerByElement.get(stateElement)!.byPath.get(path)!, key, absAddress);\n if (entry.levelListIndex !== null) {\n removeIndexEntry(entry);\n }\n }\n}\n\n/**\n * 差分が `listIndex` の index を `oldIndex` → `newIndex` に変えた: その段を鍵にする `$eqIndex` の購読を\n * 新しい鍵へ移し、`path` の最後の値が旧 index か新 index に等しい行だけを dirty 化して enqueue する\n * (それ以外の移動行では `$eqIndex` の答えは変わらない)。syncListIndexes から、drain が差分を\n * 適用する前に呼ばれる。\n */\nexport function rekeyIndexSubscriptions(listIndex: IListIndex, oldIndex: number, newIndex: number): void {\n if (!anyRegistered) {\n return;\n }\n const entries = indexKeyedByListIndex.get(listIndex);\n if (typeof entries === \"undefined\") {\n return;\n }\n for (const { stateElement, path, absAddress } of entries) {\n const ledger = ledgerByElement.get(stateElement)!;\n const keyMap = ledger.byPath.get(path)!;\n removeFromKey(keyMap, oldIndex, absAddress);\n addToKey(keyMap, newIndex, absAddress);\n keyByPathByAddress.get(absAddress)!.set(path, newIndex);\n const last = ledger.lastValue.get(path);\n if (Object.is(last, oldIndex) || Object.is(last, newIndex)) {\n dirtyCacheEntryByAbsoluteStateAddress(absAddress);\n getUpdater().enqueueAbsoluteAddress(absAddress, null);\n }\n }\n}\n\n/** テスト用: この state で `path` の下に購読されている行アドレスの数 */\nexport function countKeyedSubscriptions(stateElement: IStateElement, path: string): number {\n const keyMap = ledgerByElement.get(stateElement)?.byPath.get(path);\n if (typeof keyMap === \"undefined\") {\n return 0;\n }\n let n = 0;\n for (const set of keyMap.values()) {\n n += set.size;\n }\n return n;\n}\n","import \"../polyfills\";\nimport { createListIndex, getHomeParentListIndex, setListIndexValue } from \"./createListIndex\";\nimport { resolveListIndexesByList, retireListIndexes, reviveListIndexes, setListIndexesByList } from \"./listIndexesByList\";\nimport { IListDiff, IListIndex } from \"./types\";\nimport { dropKeyedSubscriptionsByListIndex, moveIndexWatchers, rekeyIndexSubscriptions } from \"../dependency/keyedDependency\";\n\nconst listDiffByOldListByNewList = new WeakMap<readonly unknown[], WeakMap<readonly unknown[], IListDiff>>();\n\nconst EMPTY_LIST = Object.freeze([]);\nconst EMPTY_SET = new Set<IListIndex>();\n\nfunction getListDiff(rawOldList: readonly unknown[], rawNewList: readonly unknown[]): IListDiff | null {\n const oldList = (Array.isArray(rawOldList) && rawOldList.length > 0) ? rawOldList : EMPTY_LIST;\n const newList = (Array.isArray(rawNewList) && rawNewList.length > 0) ? rawNewList : EMPTY_LIST;\n let diffByNewList = listDiffByOldListByNewList.get(oldList);\n if (!diffByNewList) {\n return null;\n }\n return diffByNewList.get(newList) || null;\n}\n\nfunction setListDiff(oldList: readonly unknown[], newList: readonly unknown[], diff: IListDiff): void {\n let diffByNewList = listDiffByOldListByNewList.get(oldList);\n if (!diffByNewList) {\n diffByNewList = new WeakMap<readonly unknown[], IListDiff>();\n listDiffByOldListByNewList.set(oldList, diffByNewList);\n }\n diffByNewList.set(newList, diff);\n}\n/**\n * Checks if two lists are identical by comparing length and each element.\n * @param oldList - Previous list to compare\n * @param newList - New list to compare\n * @returns True if lists are identical, false otherwise\n */\nfunction isSameList(oldList: readonly unknown[], newList: readonly unknown[]): boolean {\n if (oldList.length !== newList.length) {\n return false;\n }\n\n for (let i = 0; i < oldList.length; i++) {\n if (oldList[i] !== newList[i]) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Aligns each list index's .index with its position in the new list.\n * A diff only becomes the rendered state once the updater applies it: an\n * earlier diff in the same batch (two replacements in one microtask) may have\n * moved shared indexes toward a list that never got applied, and a cache hit\n * skips recomputation entirely — so every createListDiff return re-aligns.\n * 同じ走査で、行が表している要素も憶えさせる(#256)。行を戻す普通のやり方は\n * 配列を作り直すので ListIndex も作り直される ── 「同じ行が戻ってきた」と言えるのは\n * 行オブジェクトの identity ではなく、この値だけ。\n */\nfunction syncListIndexes(newIndexes: IListIndex[], newList: readonly unknown[]): void {\n for (let i = 0; i < newIndexes.length; i++) {\n if (newIndexes[i].index !== i) {\n const oldIndex = newIndexes[i].index;\n newIndexes[i].index = i;\n // `$eqIndex` の購読は差分側で鍵を付け替える(dependency/keyedDependency.ts)\n rekeyIndexSubscriptions(newIndexes[i], oldIndex, i);\n }\n setListIndexValue(newIndexes[i], newList[i]);\n }\n}\n\n/**\n * Creates or updates list indexes by comparing old and new lists.\n * Optimizes by reusing existing list indexes when values match.\n * @param parentListIndex - Parent list index for nested lists, or null for top-level\n * @param oldList - Previous list (will be normalized to array)\n * @param newList - New list (will be normalized to array)\n * @param oldIndexes - Array of existing list indexes to potentially reuse\n * @returns Array of list indexes for the new list\n */\nexport function createListDiff(\n parentListIndex: IListIndex | null,\n rawOldList: unknown,\n rawNewList: unknown,\n): IListDiff {\n const diff = computeListDiff(parentListIndex, rawOldList, rawNewList);\n syncListIndexes(\n diff.newIndexes,\n (Array.isArray(rawNewList) && rawNewList.length > 0) ? rawNewList : EMPTY_LIST,\n );\n // 捨てた行を退役、返した行を復活として記録する。台帳はこれを見て「共有」と「陳腐化」を\n // 分ける(#256)。両方を毎回の差分で付け直すので、消えない印は残らない。\n // deleteIndexSet と newIndexes は構造上交わらない。\n retireListIndexes(diff.deleteIndexSet);\n // 退役した行の鍵付き購読(`$eq` 系)は行と一緒に落とす\n for (const retired of diff.deleteIndexSet) {\n dropKeyedSubscriptionsByListIndex(retired);\n }\n reviveListIndexes(diff.newIndexes);\n // `$eqIndex` の最内段の監視は listIndex 配列に付く: 配列が変わったら移し、最後の値の位置の行を enqueue\n moveIndexWatchers(diff.oldIndexes, diff.newIndexes);\n return diff;\n}\n\nfunction computeListDiff(\n parentListIndex: IListIndex | null,\n rawOldList: unknown,\n rawNewList: unknown,\n): IListDiff {\n // Normalize inputs to arrays (handles null/undefined)\n const oldList: readonly unknown[] = (Array.isArray(rawOldList) && rawOldList.length > 0) ? rawOldList : EMPTY_LIST;\n const newList: readonly unknown[] = (Array.isArray(rawNewList) && rawNewList.length > 0) ? rawNewList : EMPTY_LIST;\n const cachedDiff = getListDiff(oldList, newList);\n if (cachedDiff) {\n return cachedDiff;\n }\n // 台帳は 1 本の配列につき行集合 1 組(listIndexesByList.ts)。親は「行がぶら下がる親が\n // 退役していたら、この親へ付け替える」ための差し替え先として渡す(#256)。\n const oldIndexes = resolveListIndexesByList(oldList, parentListIndex) || [];\n // 1 組の行集合の home は 1 つ(#256)。前の行集合を引き継ぐ差分で新しく鋳造する行は、\n // 鋳造時の親ではなくその行集合の home を継ぐ ── 行ごとに home が違う集合ができると、\n // 「持ち主が戻ってきたか」の判定が行の並び順で変わる。\n const homeParentListIndex = oldIndexes.length > 0 ?\n getHomeParentListIndex(oldIndexes[0]) : parentListIndex;\n let retValue: IListDiff | undefined;\n try {\n // Early return for empty list\n if (newList.length === 0) {\n return retValue = {\n oldIndexes: oldIndexes,\n newIndexes: [] as IListIndex[],\n changeIndexSet: EMPTY_SET,\n deleteIndexSet: new Set<IListIndex>(oldIndexes),\n addIndexSet: EMPTY_SET,\n };\n }\n // If old list was empty, create all new indexes\n let newIndexes: IListIndex[] | null = resolveListIndexesByList(newList, parentListIndex);\n if (oldList.length === 0) {\n if (newIndexes === null) {\n newIndexes = [];\n for(let i = 0; i < newList.length; i++) {\n const newListIndex = createListIndex(parentListIndex, i, homeParentListIndex);\n newIndexes.push(newListIndex);\n }\n }\n return retValue = {\n oldIndexes: oldIndexes,\n newIndexes: newIndexes,\n changeIndexSet: EMPTY_SET,\n deleteIndexSet: EMPTY_SET,\n addIndexSet: new Set<IListIndex>(newIndexes),\n };\n }\n // If lists are identical, return existing indexes unchanged (optimization)\n if (isSameList(oldList, newList)) {\n return retValue = {\n oldIndexes: oldIndexes,\n newIndexes: oldIndexes,\n changeIndexSet: EMPTY_SET,\n deleteIndexSet: EMPTY_SET,\n addIndexSet: EMPTY_SET,\n };\n }\n if (newIndexes !== null) {\n return calcDiffIndexes(oldIndexes, newIndexes);\n }\n newIndexes = [];\n\n // Use index-based map for efficiency\n // Supports duplicate values by storing array of indexes\n const indexByValue = new Map<unknown, number[]>();\n for(let i = 0; i < oldList.length; i++) {\n const val = oldList[i];\n let indexes = indexByValue.get(val);\n if (!indexes) {\n indexes = [];\n indexByValue.set(val, indexes);\n }\n indexes.push(i);\n }\n\n // Build new indexes array by matching values with old list\n const changeIndexSet: Set<IListIndex> = new Set();\n const addIndexSet: Set<IListIndex> = new Set();\n for(let i = 0; i < newList.length; i++) {\n const newValue = newList[i];\n const existingIndexes = indexByValue.get(newValue);\n const oldIndex = existingIndexes && existingIndexes.length > 0 ? existingIndexes.shift() : undefined;\n \n if (typeof oldIndex === \"undefined\") {\n // New element\n const newListIndex = createListIndex(parentListIndex, i, homeParentListIndex);\n newIndexes.push(newListIndex);\n addIndexSet.add(newListIndex);\n } else {\n // Reuse existing element\n const existingListIndex = oldIndexes[oldIndex];\n // Judge position change against the old list's order (oldIndexes array\n // order), not the mutable .index — an earlier diff in the same batch\n // may have already moved .index toward a list that was never applied.\n // The .index itself is re-aligned by syncListIndexes on return.\n if (oldIndex !== i) {\n changeIndexSet.add(existingListIndex);\n }\n newIndexes.push(existingListIndex);\n }\n }\n \n const deleteIndexSet: Set<IListIndex> = (new Set(oldIndexes)).difference(new Set(newIndexes));\n return retValue = {\n oldIndexes: oldIndexes,\n newIndexes: newIndexes,\n changeIndexSet: changeIndexSet,\n deleteIndexSet: deleteIndexSet,\n addIndexSet: addIndexSet,\n };\n } finally {\n if (typeof retValue !== \"undefined\") {\n setListDiff(oldList, newList, retValue);\n setListIndexesByList(newList, retValue.newIndexes);\n }\n }\n}\n\n/**\n * Diff between two lists whose listIndex ledgers both already exist.\n * Rows are joined by listIndex identity — the same key applyChangeToFor and\n * walkDependency consume the result sets with. A value-based join could mark\n * oldIndexes-side objects that are absent from newIndexes (ledgers built along\n * unconnected diff chains hold different objects for the same value); such\n * orphan markers never match the consumers' has() lookups and only pollute\n * the dirty set. Rows without shared identity are represented as add+delete.\n */\nfunction calcDiffIndexes(\n oldIndexes: IListIndex[],\n newIndexes: IListIndex[],\n): IListDiff {\n const newIndexSet: Set<IListIndex> = new Set(newIndexes);\n const oldIndexSet: Set<IListIndex> = new Set(oldIndexes);\n const changeIndexSet: Set<IListIndex> = new Set();\n const addIndexSet: Set<IListIndex> = newIndexSet.difference(oldIndexSet);\n const deleteIndexSet: Set<IListIndex> = oldIndexSet.difference(newIndexSet);\n // Old positions come from the oldIndexes array order (.index may have been\n // mutated by an unapplied diff in the same batch).\n const oldPosByIndex = new Map<IListIndex, number>();\n for (let i = 0; i < oldIndexes.length; i++) {\n oldPosByIndex.set(oldIndexes[i], i);\n }\n for (let i = 0; i < newIndexes.length; i++) {\n const index = newIndexes[i];\n if (addIndexSet.has(index)) {\n continue;\n }\n if (oldPosByIndex.get(index) !== i) {\n // 位置が違うことだけを記録\n changeIndexSet.add(index);\n }\n }\n return {\n oldIndexes: oldIndexes,\n newIndexes: newIndexes,\n changeIndexSet: changeIndexSet,\n deleteIndexSet: deleteIndexSet,\n addIndexSet: addIndexSet,\n };\n}","import { IListDiff, IListIndex } from \"./types\";\n\n/**\n * Indices into `seq` whose values form a longest strictly-increasing\n * subsequence, returned in ascending order. Classic patience-sorting\n * LIS in O(n log n). `seq` values are assumed distinct (old list\n * positions are unique).\n */\nexport function longestIncreasingSubsequence(seq: number[]): number[] {\n const n = seq.length;\n // tails[k] = index into seq of the smallest tail of an increasing\n // subsequence of length k+1; prev[i] = predecessor index to rebuild the chain.\n const tails: number[] = [];\n const prev: number[] = new Array(n).fill(-1);\n for (let i = 0; i < n; i++) {\n const value = seq[i];\n let lo = 0;\n let hi = tails.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (seq[tails[mid]] < value) {\n lo = mid + 1;\n } else {\n hi = mid;\n }\n }\n if (lo > 0) {\n prev[i] = tails[lo - 1];\n }\n tails[lo] = i;\n }\n const result: number[] = [];\n let k = tails.length > 0 ? tails[tails.length - 1] : -1;\n while (k >= 0) {\n result.push(k);\n k = prev[k];\n }\n result.reverse();\n return result;\n}\n\n/**\n * Determines which reused list indexes can stay where they are when the DOM\n * is brought into the new list order.\n *\n * Returns null when the reused indexes already appear in their old relative\n * order (no inversions) — the caller's existing position guard then performs\n * no moves, so nothing extra is needed. When inversions exist, returns the\n * set of indexes forming a longest increasing subsequence of old positions:\n * leaving exactly those in place and moving every other content yields the\n * correct final order with the fewest content moves (the naive forward walk\n * otherwise cascades: a single swap of rows 2/999 in 1000 rows moves ~997\n * contents instead of 2).\n *\n * Note: IListIndex.index is already mutated to the NEW position by\n * createListDiff, so old positions must come from the oldIndexes array order.\n */\nexport function computeStableIndexSet(diff: IListDiff): ReadonlySet<IListIndex> | null {\n // No reused index changed position, or nothing was reused: relative order\n // is already correct and the walk performs no moves.\n if (diff.changeIndexSet.size === 0 || diff.addIndexSet.size === diff.newIndexes.length) {\n return null;\n }\n const oldPosByIndex = new Map<IListIndex, number>();\n for (let i = 0; i < diff.oldIndexes.length; i++) {\n oldPosByIndex.set(diff.oldIndexes[i], i);\n }\n const reused: IListIndex[] = [];\n const seq: number[] = [];\n let prevPos = -1;\n let sorted = true;\n for (const index of diff.newIndexes) {\n if (diff.addIndexSet.has(index)) {\n continue;\n }\n const pos = oldPosByIndex.get(index);\n if (pos === undefined) {\n // Invariant break (a reused index missing from oldIndexes): fall back\n // to the settle walk rather than compute a stable set from bad data.\n return null;\n }\n if (pos < prevPos) {\n sorted = false;\n }\n prevPos = pos;\n reused.push(index);\n seq.push(pos);\n }\n if (sorted) {\n return null;\n }\n const lis = longestIncreasingSubsequence(seq);\n const stable = new Set<IListIndex>();\n for (const seqIndex of lis) {\n stable.add(reused[seqIndex]);\n }\n return stable;\n}\n","/**\n * 要素書き込みの入れ替えが揃ったとき、`for` の描画基準に据える「書き込む前の並びの写し」の印(#4)。\n *\n * `for` はこの写しとの差分でだけ、同じ位置で外す行と入る行の Content をその場で使い回す\n * (applyChangeToFor の collectInPlaceContents)。配列の置換の差分は、これまでどおり外した行の\n * Content をプールに通す。\n */\nconst swapBaselineLists = new WeakSet<object>();\n\nexport function markSwapBaselineList(list: readonly unknown[]): void {\n swapBaselineLists.add(list);\n}\n\nexport function isSwapBaselineList(list: unknown): boolean {\n return swapBaselineLists.has(list as object);\n}\n","import { IContent } from \"../structural/types\";\nimport type { BindingSession } from \"./BindingSession\";\n\nconst bindingSessionByContent = new WeakMap<IContent, BindingSession>();\n\nexport function getBindingSessionByContent(content: IContent): BindingSession | null {\n return bindingSessionByContent.get(content) ?? null;\n}\n\nexport function setBindingSessionByContent(content: IContent, session: BindingSession): void {\n bindingSessionByContent.set(content, session);\n}\n","import { IContent } from \"../structural/types\";\n\nconst nodesByContent: WeakMap<IContent, Node[]> = new WeakMap();\n\nexport function getNodesByContent(content: IContent): Node[] {\n return nodesByContent.get(content) ?? [];\n}\n\nexport function setNodesByContent(content: IContent, nodes: Node[]): void {\n nodesByContent.set(content, nodes);\n}\n","import { setLoopContextByNode } from \"../list/loopContextByNode\";\nimport { ILoopContext } from \"../list/types\";\nimport { IContent } from \"../structural/types\";\nimport { getNodesByContent } from \"./nodesByContent\";\n\nexport function bindLoopContextToContent(content: IContent, loopContext: ILoopContext | null): void {\n const nodes = getNodesByContent(content);\n for(const node of nodes) {\n setLoopContextByNode(node, loopContext);\n }\n}\n\nexport function unbindLoopContextToContent(content: IContent): void {\n const nodes = getNodesByContent(content);\n for (let i = 0; i < nodes.length; i++) { // 添字ループ(消去の窓に反復子のごみを残さない)\n setLoopContextByNode(nodes[i], null);\n }\n}\n","import type { IContent, IRowPlan } from \"./types\";\n\n/**\n * structural/planByContent.ts — 行プランから実体化した content の逆引き(行ランタイム設計 R2)。\n *\n * プラン経路で作られた content だけがここに載る。活性化のとき、その行が「プラン行か」を\n * 1 回の WeakMap 引きで判定するためのもの(プラン初期描画の門)。\n */\nconst planByContent = new WeakMap<IContent, IRowPlan>();\n\nexport function setPlanByContent(content: IContent, plan: IRowPlan): void {\n planByContent.set(content, plan);\n}\n\nexport function getPlanByContent(content: IContent): IRowPlan | null {\n return planByContent.get(content) ?? null;\n}\n","import { applyChange, applyValueToBinding } from \"../apply/applyChange\";\nimport { IApplyContext } from \"../apply/types\";\nimport { getAbsoluteStateAddressByBinding } from \"../binding/getAbsoluteStateAddressByBinding\";\nimport { addBindingByAbsoluteStateAddress, removeBindingByAbsoluteStateAddress } from \"../binding/getBindingSetByAbsoluteStateAddress\";\nimport { getBindingsByContent } from \"../bindings/bindingsByContent\";\nimport { getBindingSessionByContent } from \"../bindings/bindingSessionByContent\";\nimport type { BindingSession } from \"../bindings/BindingSession\";\nimport { bindLoopContextToContent, unbindLoopContextToContent } from \"../bindings/bindLoopContextToContent\";\nimport { ILoopContext } from \"../list/types\";\nimport { getByAddressSymbol } from \"../proxy/symbols\";\nimport type { IBindingInfo } from \"../types\";\nimport { getPlanByContent } from \"./planByContent\";\nimport { IContent, IRowPlan } from \"./types\";\n\n/**\n * プラン初期描画(行ランタイム設計 R2)の下ごしらえ。\n *\n * 行の下の**素の葉**(どの接頭辞も getter でなく、tail にワイルドカードが無く、event /\n * index 束縛でもない)の slot は、行オブジェクトを proxy で 1 回読めば値が取れる。その\n * 「行のパスからの残り」をプランと行パスの組ごとに 1 回だけ作って持つ(行不変)。\n * null は「この slot はプラン初期描画に載せない」。\n */\ninterface ISlotTail {\n /** 行オブジェクトからの残りのセグメント */\n readonly tail: string[];\n /** getter 判定のための、行パスからの累積パス */\n readonly prefixes: string[];\n}\n\nconst tailsByPlan = new WeakMap<IRowPlan, Map<string, (ISlotTail | null)[]>>();\n\nfunction slotTails(plan: IRowPlan, bindings: readonly IBindingInfo[], rowPath: string): (ISlotTail | null)[] {\n let byRowPath = tailsByPlan.get(plan);\n if (typeof byRowPath === \"undefined\") {\n tailsByPlan.set(plan, byRowPath = new Map());\n }\n const cached = byRowPath.get(rowPath);\n if (typeof cached !== \"undefined\") {\n return cached;\n }\n const prefix = rowPath + \".\";\n const tails = bindings.map((binding, i) => {\n const slot = plan.slots[i];\n if (slot.isEvent || slot.isIndexBinding) {\n return null;\n }\n const path = binding.statePathInfo.path;\n if (!path.startsWith(prefix)) {\n return null;\n }\n const tail = path.slice(prefix.length).split(\".\");\n const prefixes: string[] = [];\n let accumulated = rowPath;\n for (const segment of tail) {\n if (segment === \"*\") {\n // 行より下のワイルドカード(入れ子リスト)は行オブジェクトの素の読みでは解けない\n return null;\n }\n accumulated += \".\" + segment;\n prefixes.push(accumulated);\n }\n return { tail, prefixes };\n });\n byRowPath.set(rowPath, tails);\n return tails;\n}\n\n/**\n * getter は state ごとの集合で、`_state` の再セットで作り直される。行ごとに引き直す\n * (プラン側にキャッシュすると、再セット後も古い判定を使ってしまう)。\n */\nfunction hasGetterOnPrefix(prefixes: string[], getterPaths: ReadonlySet<string>): boolean {\n for (let k = 0; k < prefixes.length; k++) {\n if (getterPaths.has(prefixes[k])) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * プラン行の初期描画。行オブジェクトを proxy で 1 回読み、素の葉の slot にはその生の値を\n * そのまま渡す(読み 7 → 4・適用 3 → 1 回/行。調査 §10.13)。getter の slot と、\n * 載せられない slot は従来どおり `applyChange` を通る。\n */\nfunction applyPlanRow(\n plan: IRowPlan,\n bindings: readonly IBindingInfo[],\n session: BindingSession,\n loopContext: ILoopContext,\n context: IApplyContext,\n): void {\n const tails = slotTails(plan, bindings, loopContext.pathInfo.path);\n const getterPaths = context.stateElement.getterPaths;\n let rowValue: any;\n let rowRead = false;\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n if (!session.shouldApplyState(binding)) {\n continue;\n }\n const slotTail = tails[i];\n if (slotTail === null || hasGetterOnPrefix(slotTail.prefixes, getterPaths)) {\n applyChange(binding, context);\n continue;\n }\n if (context.appliedBindingSet.has(binding)) {\n continue;\n }\n context.appliedBindingSet.add(binding);\n if (!rowRead) {\n rowValue = (context.state as any)[getByAddressSymbol](loopContext);\n rowRead = true;\n }\n const tail = slotTail.tail;\n let value: any = rowValue;\n for (let k = 0; k < tail.length; k++) {\n if (value === null || typeof value === \"undefined\") {\n value = undefined;\n break;\n }\n value = value[tail[k]];\n }\n applyValueToBinding(binding, context, value);\n }\n}\n\nexport function activateContent(\n content: IContent,\n loopContext: ILoopContext | null,\n context: IApplyContext,\n): void {\n bindLoopContextToContent(content, loopContext);\n const bindings = getBindingsByContent(content);\n const session = getBindingSessionByContent(content);\n if (session !== null) {\n // createContent 側の initialize で remember 済みの同一 binding 配列なので、\n // remember を再実行しない専用パスで活性化する(リスト行生成のホットパス)。\n // context.rootNode は applyChangeFromBindings が確定済みの root(fragment\n // バッファ中は setRootNodeByFragment の対応先と同一)で、binding ごとの\n // getRootNode を省略できる\n session.activate(bindings, context.rootNode);\n // プラン初期描画(設計 R2)。載せないのは 2 つ:\n // `$updatedCallback` を持つ state — 束縛ごとのアドレス集計が要る\n // `**` を持つ state — 展開形の getter が `getterPaths` に無いので素の葉と見分けられない\n if (loopContext !== null\n && context.stateElement.hasUpdatedCallback === false\n && context.stateElement.hasRecursion !== true) {\n const plan = getPlanByContent(content);\n if (plan !== null) {\n applyPlanRow(plan, bindings, session, loopContext, context);\n return;\n }\n }\n }\n for (const binding of bindings) {\n if (session === null) {\n const absoluteStateAddress = getAbsoluteStateAddressByBinding(binding);\n addBindingByAbsoluteStateAddress(absoluteStateAddress, binding);\n }\n if (session !== null && !session.shouldApplyState(binding)) {\n continue;\n }\n applyChange(binding, context);\n }\n}\n\nexport function deactivateContent(\n content: IContent,\n): void {\n if (!content.mounted) {\n return;\n }\n const bindings = getBindingsByContent(content);\n const session = getBindingSessionByContent(content);\n for (let i = 0; i < bindings.length; i++) { // 添字ループ(消去の窓に反復子のごみを残さない)\n const binding = bindings[i];\n if (session !== null) {\n session.disposeBinding(binding);\n } else {\n const absoluteStateAddress = getAbsoluteStateAddressByBinding(binding);\n removeBindingByAbsoluteStateAddress(absoluteStateAddress, binding);\n }\n }\n unbindLoopContextToContent(content);\n}\n","\nexport function createEmptySet<T>(): Readonly<Set<T>> {\n return Object.freeze(new Set<T>());\n}\n","import { createEmptySet } from \"../createEmptySet\";\nimport { IContent } from \"./types\";\n\nconst contentSetByNode = new WeakMap<Node, Set<IContent>>();\n\nconst EMPTY_SET = /*#__PURE__*/ createEmptySet<IContent>();\n\nexport function setContentByNode(node: Node, content: IContent): void {\n const contents = contentSetByNode.get(node);\n if (contents) {\n contents.add(content);\n } else {\n contentSetByNode.set(node, new Set([content]));\n }\n}\n\nexport function getContentSetByNode(node: Node): Readonly<Set<IContent>> {\n const contents = contentSetByNode.get(node);\n if (typeof contents !== \"undefined\") {\n return contents;\n }\n return EMPTY_SET;\n}\n\nexport function deleteContentByNode(node: Node, content: IContent): void {\n const contents = contentSetByNode.get(node);\n if (contents) {\n contents.delete(content);\n if (contents.size === 0) {\n contentSetByNode.delete(node);\n }\n }\n}","/**\n * bindings/planFilters.ts — 束縛計画の段でフィルタの実関数を引く(要件 D16)。\n *\n * 解析の段(`bindTextParser/parseFilters.ts`)は名前と引数しか作らない。実関数は\n * 登録簿(`core/filterRegistry.ts`)から**ここで**引く。未知のフィルタが名指しで落ちるのも\n * ここ — ページの構築時であって、最初の更新の最中ではない。\n *\n * 呼び出し点は 2 つ: 通常経路の `getBindingInfos`(ノードごと)と、行プラン\n * `structural/rowPlan.ts`(テンプレートごとに 1 回、行不変の解決として焼き込む)。\n */\nimport type { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { resolveFilterFn } from \"../core/filterRegistry\";\nimport type { FilterIOType } from \"../filters/types\";\nimport type { IBindingInfo, IFilterInfo, IParsedFilter } from \"../types\";\n\n/** node / replaceNode 以外が確定したバインディング(行プランのスロットが持つ形) */\nexport type IPlannedBinding = Omit<IBindingInfo, \"node\" | \"replaceNode\">;\n\nexport function planFilters(filters: IParsedFilter[], filterIOType: FilterIOType): IFilterInfo[] {\n if (filters.length === 0) {\n // 空配列は共有してよい(フィルタ無しの宣言が大多数)\n return filters as IFilterInfo[];\n }\n const planned: IFilterInfo[] = [];\n for (let i = 0; i < filters.length; i++) {\n const filter = filters[i];\n planned.push({\n filterName: filter.filterName,\n args: filter.args,\n filterFn: resolveFilterFn(filter.filterName, filter.args, filterIOType, filter.literals ?? filter.args),\n });\n }\n return planned;\n}\n\nexport function planBinding(parsed: ParseBindTextResult): IPlannedBinding {\n return {\n ...parsed,\n inFilters: planFilters(parsed.inFilters, \"input\"),\n outFilters: planFilters(parsed.outFilters, \"output\"),\n };\n}\n","import { clearAbsoluteStateAddressByBinding } from \"../binding/getAbsoluteStateAddressByBinding.js\";\nimport { clearStateAddressByBindingInfo } from \"../binding/getStateAddressByBindingInfo.js\";\nimport { getBindingsByContent, setBindingsByContent } from \"../bindings/bindingsByContent.js\";\nimport { getBindingSessionByContent, setBindingSessionByContent } from \"../bindings/bindingSessionByContent.js\";\nimport { markNodeRegistered } from \"../bindings/collectNodesAndBindingInfos.js\";\nimport { setIndexBindingsByContent } from \"../bindings/indexBindingsByContent.js\";\nimport { initializeBindingsByFragment, initializeRowBindings } from \"../bindings/initializeBindings.js\";\nimport { resolveInitializedBinding } from \"../bindings/initializeBindingPromiseByNode.js\";\nimport { setNodesByContent } from \"../bindings/nodesByContent.js\";\nimport { markObserverSkipOnAdd, markObserverSkipOnRemove } from \"../bindings/observerSkip.js\";\nimport { config, inSsr } from \"../config.js\";\nimport { INDEX_BY_INDEX_NAME } from \"../define.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { IBindingInfo } from \"../types.js\";\nimport { getContentSetByNode, setContentByNode } from \"./contentsByNode.js\";\nimport { getFragmentInfoByUUID } from \"./fragmentInfoByUUID.js\";\nimport { resolveNodePath } from \"./resolveNodePath.js\";\nimport { compileRowPlan } from \"./rowPlan.js\";\nimport { setPlanByContent } from \"./planByContent.js\";\nimport { IContent, IFragmentInfo, IRowPlan } from \"./types.js\";\n\nconst recursiveBindingTypes = new Set(['if', 'elseif', 'else', 'for']);\n\nclass Content implements IContent {\n private _content: DocumentFragment;\n private _childNodeArray: Node[] = [];\n private _firstNode: Node | null = null;\n private _lastNode: Node | null = null;\n private _mounted: boolean = false;\n /**\n * 範囲モード。トップレベルに構造ディレクティブを持つ content でのみ true。\n * この content の実レンジは自分の childNodeArray より広い(ネストした\n * if/for が自分のアンカー直後に実ノードを挿すため)ので、移動は\n * firstNode..lastNode の DOM レンジで行う。\n */\n private _ranged: boolean = false;\n constructor(content: DocumentFragment, ranged: boolean = false) {\n this._content = content;\n this._ranged = ranged;\n // childNodes(NodeList)と Array.from の iterator を作らずに兄弟ポインタで集める。複製した\n // ばかりの fragment ではここが childNodes に触れる最初の場所になる(resolveNodePath と同じ理由、設計 R5)\n const childNodeArray: Node[] = [];\n for (let node = content.firstChild; node !== null; node = node.nextSibling) {\n childNodeArray.push(node);\n }\n this._childNodeArray = childNodeArray;\n this._firstNode = this._childNodeArray.length > 0 ? this._childNodeArray[0] : null;\n this._lastNode = this._childNodeArray.length > 0 ? this._childNodeArray[this._childNodeArray.length - 1] : null;\n }\n\n get firstNode(): Node | null {\n return this._firstNode;\n }\n\n get lastNode(): Node | null {\n return this._lastNode;\n }\n\n get mounted(): boolean {\n return this._mounted;\n }\n\n appendTo(targetNode: Node): void {\n const childNodes = this._childNodeArray;\n for (let i = 0; i < childNodes.length; i++) {\n const node = childNodes[i];\n // framework 起点のマウントを observer に伝える。中間 fragment へ append する\n // 経路でも、後続の一括 insertBefore(fragment) の mutation record には\n // この top-level node が addedNodes として現れるため、ここでのマークが届く。\n markObserverSkipOnAdd(node);\n targetNode.appendChild(node);\n }\n this._mounted = true;\n }\n\n /**\n * 移動対象ノード列。通常は自分のトップレベルノードそのもの(同一参照を返すので\n * 追加アロケーション無し)。範囲モードでマウント中のときだけ、ネストした構造\n * ディレクティブが挿した実ノードを含む DOM レンジを収集する。\n */\n private _movableNodes(): Node[] {\n if (!this._ranged || !this._mounted) {\n return this._childNodeArray;\n }\n const first = this._firstNode;\n const last = this._lastNode;\n if (first === null || last === null || first.parentNode === null) {\n return this._childNodeArray;\n }\n // 移動でsiblingが変わるため、先に列を確定させてから動かす\n const nodes: Node[] = [];\n for (let node: Node | null = first; node !== null; node = node.nextSibling) {\n nodes.push(node);\n if (node === last) {\n return nodes;\n }\n }\n // last へ到達しない(想定外の不連続)→ 従来どおり自分のノードだけ動かす\n return this._childNodeArray;\n }\n\n mountAfter(targetNode: Node): void {\n const parentNode = targetNode.parentNode;\n if (parentNode) {\n // マウント済み content にも再突入する(if の true→true 再適用・SSR\n // ハイドレーション産 content 等)。固定の nextSibling へ一括 insertBefore\n // すると、マウント済みでは nextSibling が自分の先頭ノードを指すため\n // 先頭ノードが末尾へ回転する。anchor を進めながら位置一致ノードを\n // スキップすることで冪等にする(mutation record も発生させない)。\n let anchor: Node = targetNode;\n for(const node of this._movableNodes()) {\n if (anchor.nextSibling !== node) {\n // moveBefore も childList mutation record を出すため、マークは両分岐の前\n markObserverSkipOnAdd(node);\n // moveBefore は取り外しを伴わない移動 — 接続済み行の reorder で\n // フォーカス・iframe・アニメーション状態を保存する(docs/a11y-design.md §4-1)。\n // この 1 文は 4 つのノード状態を共有する: (a) 接続済み reorder、\n // (b) clone フラグメント由来(root 違い)、(c) プール/unmount 済み(親なし)、\n // (d) バッチフラグメント内。moveBefore は「同一ツリー・親あり」を要求し\n // (b)(c)(d) では HierarchyRequestError を投げるため、same-parent ガード\n // (同 root かつ親が非 null の同時証明 = フォーカス保存が意味を持つ (a) と\n // 正確に一致)は外せない。ガードを外す「簡略化」をしてはならない。\n const mover = parentNode as Node & {\n moveBefore?: (node: Node, child: Node | null) => void;\n };\n if (node.parentNode === parentNode && typeof mover.moveBefore === \"function\") {\n mover.moveBefore(node, anchor.nextSibling);\n } else {\n parentNode.insertBefore(node, anchor.nextSibling);\n }\n }\n anchor = node;\n }\n }\n this._mounted = true;\n }\n\n tryDestroy(): boolean {\n const session = getBindingSessionByContent(this);\n // session 無し(SSR ハイドレーション産)や、定義待ち・connect-snapshot 待ちを\n // 抱える content は teardown 省略でリークするため従来経路に倒す。\n if (session === null || !session.canWholesaleDestroy()) {\n return false;\n }\n session.destroyRow(getBindingsByContent(this));\n // 添字ループ: for...of の反復子オブジェクトを行ごとに割り当てない(消去の scavenge を窓から外す)\n const childNodes = this._childNodeArray;\n for (let i = 0; i < childNodes.length; i++) {\n const node = childNodes[i];\n // unmount と同じ理由の observer 向け削除マーク(clear の一括削除でも\n // top-level node が mutation record の root に現れる)\n // この content が自分でノードを外すときだけ印を付ける(親の一括削除は親側で件数を数える)\n if (node.parentNode !== null) {\n markObserverSkipOnRemove(node);\n node.parentNode.removeChild(node);\n }\n }\n const bindings = getBindingsByContent(this);\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n if (recursiveBindingTypes.has(binding.bindingType)) {\n getContentSetByNode(binding.node).forEach((content) => {\n if (!content.tryDestroy()) {\n content.unmount();\n }\n });\n }\n }\n this._mounted = false;\n return true;\n }\n\n /**\n * 自分のノードを DOM に残したまま、unmount と同じ解体をする(#4)。\n *\n * 行の置き換えで `for` が同じ位置の Content を新しい行に使い回すとき、入力中の欄を DOM から\n * 外さないための経路。解体そのものは省けない — 中の構造ディレクティブ(ネストした for / if)が\n * 持つ Content を古い行のまま残すと、新しい行として活性化したときに内側の行が二重に描かれ、\n * `if` の中身は古い行のアドレスに紐づいたまま取り残される。\n */\n unmountInPlace(): void {\n {\n // 共有 session(`for` 束縛ごとに 1 つ)ではこの content の行だけを解体する(設計 R3)。\n // session ごと dispose すると同じリストの生きている行まで巻き込む\n const session = getBindingSessionByContent(this);\n if (session !== null) {\n if (session.isRowSession) session.disposeBindings(getBindingsByContent(this));\n else session.dispose();\n }\n }\n this._teardownBindings();\n }\n\n /** binding ごとの解体(ネストした構造ディレクティブの Content・アドレス台帳) */\n private _teardownBindings(): void {\n const bindings = getBindingsByContent(this);\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n if (recursiveBindingTypes.has(binding.bindingType)) {\n getContentSetByNode(binding.node).forEach((content) => { content.unmount(); });\n }\n clearStateAddressByBindingInfo(binding);\n clearAbsoluteStateAddressByBinding(binding);\n }\n }\n\n unmount(): void {\n {\n // 共有 session(`for` 束縛ごとに 1 つ)ではこの content の行だけを解体する(設計 R3)。\n // session ごと dispose すると同じリストの生きている行まで巻き込む\n const session = getBindingSessionByContent(this);\n if (session !== null) {\n if (session.isRowSession) session.disposeBindings(getBindingsByContent(this));\n else session.dispose();\n }\n }\n for(const node of this._childNodeArray) {\n // framework 起点の削除であることを observer に伝える。clear の\n // parentNode.textContent='' 一括削除でも、この top-level node が\n // 削除サブツリーの root として mutation record に現れるため、ここで\n // マークしておけば observer の冗長走査をスキップできる。マークは\n // 同期実行中に立ち、observer は次 microtask で読むので順序は保証される。\n if (node.parentNode !== null) {\n markObserverSkipOnRemove(node);\n node.parentNode.removeChild(node);\n }\n }\n const bindings = getBindingsByContent(this);\n for (let i = 0; i < bindings.length; i++) {\n const binding = bindings[i];\n if (recursiveBindingTypes.has(binding.bindingType)) {\n getContentSetByNode(binding.node).forEach((content) => { content.unmount(); });\n }\n clearStateAddressByBindingInfo(binding);\n clearAbsoluteStateAddressByBinding(binding);\n }\n this._mounted = false;\n }\n}\n\n/**\n * トップレベルに構造ディレクティブのプレースホルダを持つか。\n *\n * これを持つ content は、ネストした if/for が「自分のアンカー直後」に実ノードを\n * 挿すため、自分の childNodeArray が実レンジより狭くなる。その状態だと\n * (1) 呼び出し側の位置追跡(applyChangeToFor の lastNode)が実ノードの手前で\n * 止まり後続行が割り込む、(2) 移動時にネスト分を置き去りにする、の 2 つが起きる。\n * 該当テンプレートにだけ終端マーカーを持たせて実レンジを閉じる。\n */\nfunction hasTopLevelStructural(fragment: DocumentFragment): boolean {\n // config は setConfig で差し替わりうるので都度組む。テンプレート単位に一度しか\n // 走らない判定なので、この生成コストが行あたりに乗ることはない。\n const structural = new RegExp(\n `^@@(?:${config.commentForPrefix}|${config.commentIfPrefix}`\n + `|${config.commentElseIfPrefix}|${config.commentElsePrefix}):`,\n );\n for (let node = fragment.firstChild; node !== null; node = node.nextSibling) {\n if (node.nodeType !== Node.COMMENT_NODE) {\n continue;\n }\n // Comment の data は常に文字列(textContent の null 分岐を持ち込まない)\n if (structural.test((node as Comment).data)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * 範囲モードの要否をテンプレート単位で一度だけ判定してキャッシュする。\n * 大多数のテンプレート(トップレベルが素の要素)は false を引くだけで、\n * 行ごとの追加コストはゼロ。\n */\nfunction resolveRanged(fragmentInfo: IFragmentInfo): boolean {\n let ranged = fragmentInfo.topLevelStructural;\n if (typeof ranged === 'undefined') {\n ranged = fragmentInfo.topLevelStructural = hasTopLevelStructural(fragmentInfo.fragment);\n }\n return ranged;\n}\n\nconst ROW_END_PREFIX = 'wcs-row-end';\n\n/**\n * 終端マーカーの付与。バインディング初期化の後に足すので nodePath 解決には影響しない\n * (末尾追加なので既存 index もずれない)。SSR 描画中は付けない — SSR は行ごとに\n * `@@wcs-for-start/end` を出力しており、そちらがレンジの正本かつハイドレーション\n * が読む対象なので、余計なコメントを混ぜない。\n */\nfunction appendRowEndMarker(cloneFragment: DocumentFragment, uuid: string): void {\n cloneFragment.appendChild(document.createComment(`${ROW_END_PREFIX}:${uuid}`));\n}\n\n/**\n * SSR ハイドレーション用: 既存の DOM ノード配列から Content を生成する。\n * テンプレートからの clone ではなく、SSR で描画済みのノードをそのまま使う。\n */\nexport function createContentFromNodes(\n nodes: Node[],\n): IContent {\n const fragment = document.createDocumentFragment();\n // ノードを fragment に移動せず、参照だけ持つ Content を作る\n const content = new Content(fragment);\n // Content の内部状態を直接設定\n (content as any)._childNodeArray = nodes;\n (content as any)._firstNode = nodes.length > 0 ? nodes[0] : null;\n (content as any)._lastNode = nodes.length > 0 ? nodes[nodes.length - 1] : null;\n (content as any)._mounted = true; // SSR で既にマウント済み\n return content;\n}\n\n/**\n * RowPlan 経路の実体化: clone → nodePath 解決 → スロットから薄い binding を複製 →\n * initializeRowBindings。パース再生(spread 展開・remember・キー文字列・options\n * オブジェクト・policy 再解決)を行ごとに繰り返さない\n * (docs/state-row-instantiation-redesign.md §3-1/§3-2)。\n */\nfunction createPlanContent(\n bindingInfo: IBindingInfo,\n fragmentInfo: IFragmentInfo,\n plan: IRowPlan,\n): IContent {\n const cloneFragment = document.importNode(fragmentInfo.fragment, true);\n const nodeInfos = fragmentInfo.nodeInfos;\n const nodes: Node[] = new Array(nodeInfos.length);\n for (let i = 0; i < nodeInfos.length; i++) {\n const node = resolveNodePath(cloneFragment, nodeInfos[i].nodePath);\n if (node === null) {\n raiseError(`Node not found by path [${nodeInfos[i].nodePath.join(', ')}] in fragment.`);\n }\n // 再スキャン防止と初期化完了マークは従来経路と同じ台帳に載せる\n markNodeRegistered(node);\n resolveInitializedBinding(node);\n nodes[i] = node;\n }\n const slots = plan.slots;\n const bindings: IBindingInfo[] = new Array(slots.length);\n const indexBindings: IBindingInfo[] = [];\n for (let k = 0; k < slots.length; k++) {\n const slot = slots[k];\n const node = nodes[slot.nodeIndex];\n // text スロットは事前正規化済みの Text がそのまま replaceNode(従来経路の\n // getBindingInfos と同じ帰結)。prop/event は node === replaceNode\n const binding: IBindingInfo = { ...slot.template, node, replaceNode: node };\n bindings[k] = binding;\n if (slot.isIndexBinding) {\n indexBindings.push(binding);\n }\n }\n const session = initializeRowBindings(plan, bindings, bindingInfo.node);\n // プラン経路の content は範囲モードにならない: compileRowPlan は bindingType が\n // text / prop / event のもの以外(= for / if / elseif / else)を含む時点で不適格に\n // するため、プラン適格なフラグメントはトップレベル構造アンカーを持ち得ない。\n const content = new Content(cloneFragment);\n setBindingSessionByContent(content, session);\n setBindingsByContent(content, bindings);\n // 活性化がこの行をプラン初期描画に載せてよいか判定するための逆引き(設計 R2)\n setPlanByContent(content, plan);\n setIndexBindingsByContent(content, indexBindings);\n setNodesByContent(content, nodes);\n setContentByNode(bindingInfo.node, content);\n return content;\n}\n\nexport function createContent(\n bindingInfo: IBindingInfo,\n): IContent {\n if (typeof bindingInfo.uuid === 'undefined' || bindingInfo.uuid === null) {\n raiseError(`BindingInfo.uuid is null.`);\n }\n const fragmentInfo = getFragmentInfoByUUID(bindingInfo.uuid);\n if (!fragmentInfo) {\n raiseError(`Fragment with UUID \"${bindingInfo.uuid}\" not found.`);\n }\n // SSR 描画中は行ごとの @@wcs-for-start/end がレンジの正本なので終端マーカーは付けない\n const ranged = !inSsr() && resolveRanged(fragmentInfo);\n let plan = fragmentInfo.rowPlan;\n if (typeof plan === 'undefined' || (plan !== null && plan.directional !== config.enableDirectionalInitialSync)) {\n // 初回 or config(directional)が変わったときだけコンパイル。不適格は null を\n // キャッシュして以後は従来経路へ直行する\n plan = fragmentInfo.rowPlan = compileRowPlan(fragmentInfo);\n }\n if (plan !== null) {\n return createPlanContent(bindingInfo, fragmentInfo, plan);\n }\n const cloneFragment = document.importNode(fragmentInfo.fragment, true);\n const initialInfo = initializeBindingsByFragment(cloneFragment, fragmentInfo.nodeInfos);\n if (ranged) {\n // uuid は冒頭のガードで非 null が確定している(raiseError は never を返す)\n appendRowEndMarker(cloneFragment, bindingInfo.uuid);\n }\n const content = new Content(cloneFragment, ranged);\n setBindingSessionByContent(content, initialInfo.bindingSession);\n setBindingsByContent(content, initialInfo.bindingInfos);\n const indexBindings: IBindingInfo[] = [];\n for(const binding of initialInfo.bindingInfos) {\n if (binding.statePathName in INDEX_BY_INDEX_NAME) {\n indexBindings.push(binding);\n }\n }\n setIndexBindingsByContent(content, indexBindings);\n setNodesByContent(content, initialInfo.nodes);\n setContentByNode(bindingInfo.node, content);\n return content;\n}\n","import { ILoopContext } from \"../list/types\";\nimport { IBindingInfo } from \"../types\";\nimport {\n collectNodesAndBindingInfos,\n collectNodesAndBindingInfosByFragment,\n IDeferredSpreadEntry,\n ParseResultTransform,\n processDeferredNode,\n} from \"./collectNodesAndBindingInfos\";\nimport { IFragmentNodeInfo, IRowPlan } from \"../structural/types\";\nimport { setLoopContextByNode } from \"../list/loopContextByNode\";\nimport { applyChangeFromBindings } from \"../apply/applyChangeFromBindings\";\nimport { IInitialBindingInfo } from \"./types\";\nimport { BindingSession, getOrCreateBindingSession } from \"./BindingSession\";\n\nfunction scheduleDeferredSpreads(\n deferredSpreads: IDeferredSpreadEntry[],\n parentLoopContext: ILoopContext | null,\n session: BindingSession,\n): void {\n for (const entry of deferredSpreads) {\n session.deferUntilDefined(entry.node, entry.tagName, () => {\n const bindings = processDeferredNode(entry);\n if (bindings.length === 0) return;\n setLoopContextByNode(entry.node, parentLoopContext);\n const initialized = session.initialize(bindings);\n applyChangeFromBindings(initialized);\n }, (error: unknown) => {\n console.error(`[@wcstack/state] deferred spread failed for <${entry.tagName}>.`, error);\n });\n }\n}\n\nexport function initializeBindings(\n root: Document | DocumentFragment | Element,\n parentLoopContext: ILoopContext | null,\n transform?: ParseResultTransform,\n): void {\n const [subscriberNodes, allBindings, deferredSpreads] = collectNodesAndBindingInfos(root, transform);\n const session = getOrCreateBindingSession(root);\n for (const node of subscriberNodes) {\n setLoopContextByNode(node, parentLoopContext);\n }\n const initialized = session.initialize(allBindings);\n applyChangeFromBindings(initialized);\n scheduleDeferredSpreads(deferredSpreads, parentLoopContext, session);\n}\n\nexport function initializeBindingsByFragment(\n root: DocumentFragment,\n nodeInfos: IFragmentNodeInfo[],\n): IInitialBindingInfo {\n const [subscriberNodes, allBindings] = collectNodesAndBindingInfosByFragment(root, nodeInfos);\n const session = new BindingSession();\n // knownRoot=null: detached fragment 上の初期化。observableRootFor が必ず null を\n // 返す(observe は no-op)ため、binding ごとの getRootNode を省略する\n const initialized = session.initialize(allBindings, {\n registerAddress: false,\n applyOnReconnect: false,\n }, null);\n return {\n nodes: subscriberNodes,\n bindingInfos: initialized,\n bindingSession: session,\n };\n}\n\n/**\n * RowPlan 経路の行初期化(createContent 専用)。remember / spread 展開 /\n * shouldApplyState フィルタを経ず、プランのスロットから直接 record を構築する。\n * 返す session は従来経路と同じ活性化(activate)・破棄(dispose/wholesale)\n * インターフェースを持つ。\n */\n// `for` 束縛(そのノード)ごとに 1 つの session を全行で共有する(設計 R3)。\n// プランが差し替わったら(再セット・方向性初期同期の設定変更)新しい session に切り替える。\nconst rowSessionByForNode = new WeakMap<Node, BindingSession>();\nexport function initializeRowBindings(plan: IRowPlan, bindings: IBindingInfo[], forNode: Node): BindingSession {\n let session = rowSessionByForNode.get(forNode);\n if (typeof session === \"undefined\" || session.currentRowPlan !== plan) {\n session = new BindingSession();\n rowSessionByForNode.set(forNode, session);\n }\n session.initializeRow(plan, bindings);\n return session;\n}\n","import { IInitialSyncPolicy, resolveInitialSyncPolicy } from \"../bindings/initialSync\";\nimport { planBinding } from \"../bindings/planFilters\";\nimport { config } from \"../config\";\nimport { COMMAND_NAMESPACE, EVENT_TOKEN_NAMESPACE, INDEX_BY_INDEX_NAME } from \"../define\";\nimport { isPossibleTwoWay } from \"../event/isPossibleTwoWay\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { IBindingInfo } from \"../types\";\nimport { resolveNodePath } from \"./resolveNodePath\";\nimport { IFragmentInfo, IRowPlan, IRowPlanSlot } from \"./types\";\n\n/**\n * rowPlan.ts — 行実体化プランのコンパイル(docs/state-row-instantiation-redesign.md §3-1)。\n *\n * テンプレート(fragmentInfo)を初回行生成時に一度だけ検査し、全スロットが\n * 「行不変の判定をテンプレート時に確定できる」種別のときだけプランを返す。\n * 1 スロットでも確定できなければ null(テンプレート丸ごと従来経路 = 部分適用しない。\n * 経路混在のデバッグ困難を避ける設計判断・同 §5)。\n *\n * プラン適格の条件(すべて満たすこと):\n * - bindingType が text / prop / event のみ(構造 for/if・radio/checkbox・spread は不適格)\n * - バインディング先ノードがカスタム要素でない(定義待ち・wcBindable 検証が不要)\n * - prop が command / eventToken 名前空間でない(token 配線 teardown が要るため)\n * - prop が双方向可能(isPossibleTwoWay)でない(connect-snapshot / observer 配線が要るため)\n * - initial-sync policy が観測不要(observable=false)かつ authority が \"auto\" でない\n * - text スロットは事前正規化済みの Text ノードである\n */\nexport function compileRowPlan(fragmentInfo: IFragmentInfo): IRowPlan | null {\n const directional = config.enableDirectionalInitialSync;\n const slots: IRowPlanSlot[] = [];\n const nodeInfos = fragmentInfo.nodeInfos;\n for (let nodeIndex = 0; nodeIndex < nodeInfos.length; nodeIndex++) {\n const nodeInfo = nodeInfos[nodeIndex];\n const node = resolveNodePath(fragmentInfo.fragment, nodeInfo.nodePath);\n if (node === null) {\n return null;\n }\n for (const template of nodeInfo.parseBindTextResults) {\n const bindingType = template.bindingType;\n if (bindingType !== \"text\" && bindingType !== \"prop\" && bindingType !== \"event\") {\n return null;\n }\n // command.<name>(prop 扱い)と eventToken.<prop>(event 扱い)は token 配線の\n // teardown / attach 分岐が要るため不適格\n const namespace = template.propSegments[0];\n if (namespace === COMMAND_NAMESPACE || namespace === EVENT_TOKEN_NAMESPACE) {\n return null;\n }\n if (bindingType === \"text\") {\n if (node.nodeType !== Node.TEXT_NODE) {\n return null;\n }\n } else if (getCustomElement(node) !== null) {\n return null;\n }\n if (bindingType === \"prop\" && isPossibleTwoWay(node, template.propName)) {\n return null;\n }\n // フィルタの実関数は行不変なので、テンプレートごとに 1 回だけ引く(要件 D16。\n // 未知のフィルタはここで名指しで落ちる — 不適格として倒さない。従来経路へ倒しても\n // 同じ診断が出るだけで、行の生成まで遅れる)\n const planned = planBinding(template);\n let policy: IInitialSyncPolicy;\n try {\n // 判定はテンプレートのノードで行う(policy は node の宣言と行不変フィールドの\n // 純関数)。修飾子エラー等の throw は不適格として従来経路に倒し、従来経路が\n // 同じエラーを同じタイミング(初回行生成)で報告する。\n const probe: IBindingInfo = { ...planned, node, replaceNode: node };\n policy = resolveInitialSyncPolicy(probe);\n } catch {\n return null;\n }\n if (policy.observable || policy.authority === \"auto\") {\n return null;\n }\n slots.push({\n nodeIndex,\n template: planned,\n isEvent: bindingType === \"event\",\n isIndexBinding: template.statePathName in INDEX_BY_INDEX_NAME,\n policy,\n authority: policy.authority,\n });\n }\n }\n return { directional, slots };\n}\n","import { getTransitionRunner } from \"../protocol/transitionRunner\";\nimport { IContent } from \"../structural/types\";\n\n/**\n * Automatic `view-transition-name` assignment (docs/view-transition-design.md §6).\n *\n * A name has to be on the element *before* the browser snapshots the old state,\n * so it cannot be assigned inside the transition's update callback — \"name only\n * what changed\" is impossible. The names are therefore assigned as structural\n * content mounts, and only when the page's arbiter declares `naming=\"auto\"`.\n *\n * The name follows the *content*, not the row's data: a pooled content reused for\n * another item keeps its name, which is exactly what the DOM does, so the\n * transition morphs the element that really was reused.\n */\nexport interface IAutoNaming {\n readonly limit: number;\n}\n\nexport type TransitionNameKind = \"row\" | \"branch\";\n\n/** Elements that already carry a generated name (never renamed). */\nconst namedElements = new WeakSet<Element>();\n\n/**\n * The generated-name ledger is per *document*, not per module instance.\n *\n * `view-transition-name` has to be unique across the whole document: the moment\n * two elements share one, the browser aborts the transition outright. A\n * module-scope counter breaks that as soon as `@wcstack/state` is loaded twice on\n * one page (two CDN bundles), because both copies would start minting\n * `wcs-row-1`. The transition-runner key is a `Symbol.for` for exactly this\n * reason, and the counter needs the same protection.\n *\n * Sharing the cap is right for the same reason: the cost a cap exists to bound —\n * one snapshot group per named element — is a document-wide cost, not a\n * per-bundle one.\n */\nconst NAMING_LEDGER_KEY = Symbol.for(\"wcstack.state.view-transition-naming\");\n\ninterface INamingLedger {\n counter: number;\n assigned: number;\n warned: boolean;\n}\n\nfunction getLedger(): INamingLedger {\n const slot = globalThis as Record<symbol, INamingLedger | undefined>;\n return (slot[NAMING_LEDGER_KEY] ??= { counter: 0, assigned: 0, warned: false });\n}\n\n// テスト用: ドキュメント単位の命名台帳を初期化する\nexport function __test_resetTransitionNaming(): void {\n const ledger = getLedger();\n ledger.counter = 0;\n ledger.assigned = 0;\n ledger.warned = false;\n}\n\n/**\n * The active auto-naming policy, or null when names are the author's business\n * (the default) — one arbiter lookup per structural apply, not per row.\n */\nexport function getAutoNaming(): IAutoNaming | null {\n const runner = getTransitionRunner(\"state\");\n if (runner === null || runner.naming !== \"auto\") {\n return null;\n }\n return { limit: runner.namingLimit };\n}\n\nfunction firstElementOf(content: IContent): Element | null {\n const first = content.firstNode;\n if (first === null) {\n return null;\n }\n const last = content.lastNode;\n for (let node: Node | null = first; node !== null; node = node.nextSibling) {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return node as Element;\n }\n if (node === last) {\n break;\n }\n }\n return null;\n}\n\n/**\n * Give this content's first element a unique name plus a class for group\n * styling, unless it already has one or the cap has been reached.\n *\n * The cap exists because every named element becomes its own snapshot group; a\n * few hundred of them make a transition visibly slow. Past it naming stops and\n * says so once — silently degrading would leave the author wondering why only\n * the first part of a list animates.\n */\nexport function applyTransitionName(\n content: IContent,\n kind: TransitionNameKind,\n naming: IAutoNaming,\n): void {\n const element = firstElementOf(content);\n if (element === null || namedElements.has(element)) {\n return;\n }\n // A node without `style` (anything outside HTMLElement / SVGElement) cannot\n // carry a name. Bail before touching the ledger: consuming the cap and marking\n // the element as named would burn a slot for a name that was never written,\n // and leave that element permanently ineligible.\n const style = (element as HTMLElement).style;\n if (style === undefined) {\n return;\n }\n const ledger = getLedger();\n if (ledger.assigned >= naming.limit) {\n if (!ledger.warned) {\n ledger.warned = true;\n console.warn(\n `[@wcstack/state] auto view-transition-name limit (${naming.limit}) reached; ` +\n \"further elements are left unnamed. Raise naming-limit on <wcs-view-transition>, \" +\n 'or switch to naming=\"manual\" and name only what should morph.',\n );\n }\n return;\n }\n namedElements.add(element);\n ledger.assigned += 1;\n ledger.counter += 1;\n style.setProperty(\"view-transition-name\", `wcs-${kind}-${ledger.counter}`);\n // Group handle for CSS (`::view-transition-group(*.wcs-row)`). Ignored by\n // engines that predate view-transition-class, which costs nothing.\n style.setProperty(\"view-transition-class\", `wcs-${kind}`);\n}\n","import { getPathInfo } from \"../address/PathInfo\";\nimport { createStateAddress } from \"../address/StateAddress\";\nimport { getAbsoluteStateAddressByBinding } from \"../binding/getAbsoluteStateAddressByBinding\";\nimport { getBindingsByContent } from \"../bindings/bindingsByContent\";\nimport { markObserverSkipRemovedChildren } from \"../bindings/observerSkip\";\nimport { getIndexBindingsByContent } from \"../bindings/indexBindingsByContent\";\nimport { inSsr } from \"../config\";\nimport { WILDCARD } from \"../define\";\nimport { createListDiff } from \"../list/createListDiff\";\nimport { getListIndexByBindingInfo } from \"../list/getListIndexByBindingInfo\";\nimport { getLastListValueByAbsoluteStateAddress } from \"../list/lastListValueByAbsoluteStateAddress\";\nimport { computeStableIndexSet } from \"../list/stableListOrder\";\nimport { isSwapBaselineList } from \"../list/swapBaselineList\";\nimport { IListDiff, IListIndex } from \"../list/types\";\nimport { raiseError } from \"../raiseError\";\nimport { activateContent, deactivateContent } from \"../structural/activateContent\";\nimport { deleteContentByNode, getContentSetByNode } from \"../structural/contentsByNode\";\nimport { createContent } from \"../structural/createContent\";\nimport { IContent } from \"../structural/types\";\nimport { IBindingInfo } from \"../types\";\nimport { applyChange } from \"./applyChange\";\nimport { setRootNodeByFragment } from \"./rootNodeByFragment\";\nimport { IApplyContext } from \"./types\";\nimport { applyTransitionName, getAutoNaming } from \"./viewTransitionNaming\";\n\nconst lastNodeByNode: WeakMap<Node, Node> = new WeakMap();\nconst contentByListIndexByNode: WeakMap<Node, WeakMap<IListIndex, IContent>> = new WeakMap();\nconst pooledContentsByNode: WeakMap<Node, IContent[]> = new WeakMap();\nconst isOnlyNodeInParentContentByNode: WeakMap<Node, boolean> = new WeakMap();\n\n// テスト用ヘルパー(内部状態の操作)\nexport function __test_setContentByListIndex(node: Node, index: IListIndex, content: IContent | null): void {\n setContent(node, index, content);\n}\n\nexport function __test_deleteLastNodeByNode(node: Node): void {\n lastNodeByNode.delete(node);\n}\n\n// SSR ハイドレーション用: Content を ListIndex に登録する\nexport function hydrateSetContent(node: Node, index: IListIndex, content: IContent): void {\n setContent(node, index, content);\n}\n\nexport function hydrateSetLastNode(node: Node, lastNode: Node): void {\n lastNodeByNode.set(node, lastNode);\n}\n\nexport function __test_deleteContentByNode(node: Node): void {\n contentByListIndexByNode.delete(node);\n}\n\nfunction getPooledContents(bindingInfo: IBindingInfo): IContent[] {\n return pooledContentsByNode.get(bindingInfo.node) || [];\n}\n\n// プールの上限(アンカーごと)。プールはアンカー(文書に永続するコメントノード)\n// から content とその DOM サブツリー・バインディング群を強参照するため、無制限だと\n// 大きなリストのクリア後もメモリが解放されない(10k 行で 10MB 級)。上限超過分は\n// contentSetByNode の台帳からも外して GC 可能にする。再追加時は createContent で\n// 作り直すコストと引き換えになる。\nconst MAX_POOLED_CONTENTS = 1000;\nlet maxPooledContents = MAX_POOLED_CONTENTS;\n\n// テスト用: プール上限の変更と現在のプールサイズ取得\nexport function __test_setMaxPooledContents(limit: number): number {\n const prev = maxPooledContents;\n maxPooledContents = limit;\n return prev;\n}\n\nexport function __test_getPooledContentsCount(node: Node): number {\n return (pooledContentsByNode.get(node) || []).length;\n}\n\nfunction setPooledContent(bindingInfo: IBindingInfo, content: IContent): void {\n let contents = pooledContentsByNode.get(bindingInfo.node);\n if (typeof contents === 'undefined') {\n contents = [];\n pooledContentsByNode.set(bindingInfo.node, contents);\n }\n if (contents.length < maxPooledContents) {\n contents.push(content);\n } else {\n // 上限超過: content を完全に手放す。contentSetByNode は createContent 時に\n // 追加されたきり解放経路が無いため、ここで外さないと GC できない。\n deleteContentByNode(bindingInfo.node, content);\n }\n}\n\n/**\n * 親の中身を一括で捨てて良いか(全行削除の近道)の判定に数えるノードか。要素・空白でないテキストの\n * ほかに、**構造ディレクティブのアンカー(コメント)** も数える(#4)。数えないと、同じ親に居る `if` の\n * アンカーまで textContent='' で消え、その `if` は以後何も描けない — 行の中が `if` だけの形では、\n * 行の器ごと壊れる(行を描き直さない main では表に出ないが、消えているのは同じ)。\n */\nfunction countsAsParentContent(node: Node): boolean {\n if (node.nodeType === Node.ELEMENT_NODE) {\n return true;\n }\n if (node.nodeType === Node.TEXT_NODE) {\n return (node.textContent?.trim() ?? '') !== '';\n }\n return node.nodeType === Node.COMMENT_NODE && (node as Comment).data.startsWith('@@wcs-');\n}\n\nfunction isOnlyNodeInParentContent(firstNode: Node, lastNode: Node): boolean {\n let prevCheckNode = firstNode.previousSibling;\n let nextCheckNode = lastNode.nextSibling;\n let onlyNode = true;\n while(prevCheckNode !== null) {\n if (countsAsParentContent(prevCheckNode)) {\n onlyNode = false;\n break;\n }\n prevCheckNode = prevCheckNode.previousSibling;\n }\n while(nextCheckNode !== null) {\n if (countsAsParentContent(nextCheckNode)) {\n onlyNode = false;\n break;\n }\n nextCheckNode = nextCheckNode.nextSibling;\n }\n return onlyNode;\n}\n\n// A stable content may be left in place only when its first node verifiably\n// follows the settled walk position in the same tree: the listIndexes ledger\n// can lag the physical DOM (element-write swaps reorder listIndexes without\n// moving nodes; hidden regions unmount contents that stay registered). Empty\n// contents (null firstNode) always take the settle walk so their mount\n// bookkeeping matches the pre-LIS behavior.\nfunction isPhysicallyAfter(lastNode: Node, firstNode: Node | null): boolean {\n if (firstNode === null) {\n return false;\n }\n if (lastNode.nextSibling === firstNode) {\n return true;\n }\n const position = lastNode.compareDocumentPosition(firstNode);\n return (position & Node.DOCUMENT_POSITION_FOLLOWING) !== 0\n && (position & Node.DOCUMENT_POSITION_DISCONNECTED) === 0;\n}\n\ninterface IInPlaceContents {\n /** 入る行の listIndex → その場で使い回す Content */\n readonly byAddedIndex: Map<IListIndex, IContent>;\n readonly reused: Set<IContent>;\n}\n\n/**\n * 要素書き込みの入れ替えを描き直す差分(基準が「書き込む前の並びの写し」— swapBaselineList.ts)で、\n * 同じ位置の「外す行」と「入る行」を組にし、外す行の Content を入る行にその場で使い回す(#4)。\n * 行の置き換え(リストに無かった値の書き込み)はその位置の行が新しい行に替わるだけなので、プールを通して\n * ブロックを DOM から外す必要が無い — 外すと、双方向バインドの入力で打鍵ごとにフォーカスが失われる。\n * 配列の置換の差分は対象にしない(外した行の Content はこれまでどおりプールを通す)。\n */\nfunction collectInPlaceContents(\n contentMap: WeakMap<IListIndex, IContent>,\n lastValue: unknown,\n diff: IListDiff,\n): IInPlaceContents | null {\n if (!isSwapBaselineList(lastValue)) {\n return null;\n }\n let inPlace: IInPlaceContents | null = null;\n for (let position = 0; position < diff.newIndexes.length; position++) {\n const added = diff.newIndexes[position];\n const removed = diff.oldIndexes[position];\n const content = diff.addIndexSet.has(added) && diff.deleteIndexSet.has(removed)\n ? contentMap.get(removed)\n : undefined;\n if (typeof content === \"undefined\") {\n continue;\n }\n inPlace ??= { byAddedIndex: new Map(), reused: new Set() };\n inPlace.byAddedIndex.set(added, content);\n inPlace.reused.add(content);\n }\n return inPlace;\n}\n\nconst STRUCTURAL_BINDING_TYPES = new Set(['if', 'elseif', 'else', 'for']);\n\n/**\n * 使い回す Content の「適用済み」の印を落とす。入れ子の構造ディレクティブが持つ Content も辿る —\n * `if` の中の `for` や、`elseif` / `else` のアンカーは行の Content ではなく**内側の** Content に\n * 属するので、行の binding だけ落としても新しい行として適用し直されない(印が残ったまま\n * activateContent の applyChange に飛ばされ、解体した内側が描き直されないまま空になる)。\n */\nfunction clearAppliedMarks(content: IContent, context: IApplyContext): void {\n for (const binding of getBindingsByContent(content)) {\n context.appliedBindingSet.delete(binding);\n if (!STRUCTURAL_BINDING_TYPES.has(binding.bindingType)) {\n continue;\n }\n for (const nested of getContentSetByNode(binding.node)) {\n clearAppliedMarks(nested, context);\n }\n }\n}\n\n/**\n * 入れ子の `for` が持つ Content を解体して台帳から外す(#4)。その場で使い回す行の中身は新しい行として\n * 作り直されるので、外した Content をアンカーの content 台帳(contentSetByNode)に残すと、置き換えの\n * たびに伸び続ける。プールへ返さないのは、返すと次の適用で内側の `for` が「全行削除」の近道\n * (親の textContent を空にする)に入り、囲む `if` のアンカーごと行を壊すため。`if` の Content は\n * アンカーごとに 1 つを使い回すので外さない。\n */\nfunction dropNestedContents(content: IContent): void {\n for (const binding of getBindingsByContent(content)) {\n if (!STRUCTURAL_BINDING_TYPES.has(binding.bindingType)) {\n continue;\n }\n const dropped = binding.bindingType === 'for';\n for (const nested of getContentSetByNode(binding.node)) {\n dropNestedContents(nested);\n if (!dropped || !nested.mounted) {\n continue;\n }\n deactivateContent(nested);\n nested.unmount();\n deleteContentByNode(binding.node, nested);\n }\n }\n}\n\nfunction setContent(node: Node, listIndex: IListIndex, content: IContent | null): void {\n let contentByListIndex = contentByListIndexByNode.get(node);\n if (typeof contentByListIndex === 'undefined') {\n if (content === null) {\n return;\n }\n contentByListIndex = new WeakMap<IListIndex, IContent>();\n contentByListIndexByNode.set(node, contentByListIndex);\n }\n if (content === null) {\n contentByListIndex.delete(listIndex);\n } else {\n contentByListIndex.set(listIndex, content);\n }\n}\n\nexport function applyChangeToFor(\n bindingInfo: IBindingInfo, \n context: IApplyContext,\n newValue: unknown, \n): void {\n const listPathInfo = bindingInfo.statePathInfo;\n const listIndex = getListIndexByBindingInfo(bindingInfo);\n const absAddress = getAbsoluteStateAddressByBinding(bindingInfo);\n const recordedLastValue = getLastListValueByAbsoluteStateAddress(absAddress);\n // lastListValue はアドレスキーの共有台帳。まだ何も描いていない binding ノード\n //(content 台帳が空)が、既に描画済みのアドレスに後から参加する形 — マウント\n // スコープの再初期化(コンポーネントが connectedCallback で shadow を張り直す)や\n // 後着ノードの binder 適用 — では、共有の記録で差分を取ると「既存 content の\n // 再利用・維持」を指示され、この binding には無いので落ちる。自分の台帳が空なら\n // 白紙から全行 add で描く(同じアドレスの他の binding の差分には影響しない)\n const lastValue = recordedLastValue.length > 0 && !contentByListIndexByNode.has(bindingInfo.node)\n ? []\n : recordedLastValue;\n const diff = createListDiff(listIndex, lastValue, newValue);\n context.newListValueByAbsAddress.set(absAddress, Array.isArray(newValue) ? newValue : []);\n\n let contentMap = contentByListIndexByNode.get(bindingInfo.node);\n // 要素書き込みの入れ替えを描き直す差分では、同じ位置で外す行の Content を入る行がその場で使い回す(#4)\n const inPlaceContents = typeof contentMap !== 'undefined' ? collectInPlaceContents(contentMap, lastValue, diff) : null;\n const fullDelete = Array.isArray(lastValue)\n && lastValue.length === diff.deleteIndexSet.size\n && diff.deleteIndexSet.size > 0;\n // その場で使い回す Content があるときは、親を空にする近道を取らない(使い回す行の DOM も消える)\n if (fullDelete && inPlaceContents === null && bindingInfo.node.parentNode !== null) {\n let isOnlyNode = isOnlyNodeInParentContentByNode.get(bindingInfo.node);\n if (typeof isOnlyNode === 'undefined') {\n const lastNode = lastNodeByNode.get(bindingInfo.node) || bindingInfo.node;\n isOnlyNode = isOnlyNodeInParentContent(bindingInfo.node, lastNode);\n isOnlyNodeInParentContentByNode.set(bindingInfo.node, isOnlyNode);\n }\n if (isOnlyNode) {\n const parentNode = bindingInfo.node.parentNode;\n // 全行は 1 つの mutation record で消えるので、親に「framework の削除がこの件数」と 1 回書けば\n // observer はその record を丸ごと飛ばせる(行ごとの印を消費しない。bindings/observerSkip.ts)\n markObserverSkipRemovedChildren(parentNode, parentNode.childNodes.length);\n parentNode.textContent = '';\n parentNode.appendChild(bindingInfo.node);\n }\n }\n // 全削除時、プールに収まらない content は再利用されないため、per-binding の\n // teardown(listener 解除・アドレス台帳・loopContext 掃除)を丸ごと省略して\n // ノードごと GC に任せる(tryDestroy)。プール行きの分だけ従来どおり解体する\n // (プール行は binding が生存し続けるため address キャッシュのクリアが必須)。\n // content 台帳の WeakMap ビルトインは V8 プロファイルで本関数の self に計上される\n // ホットスポット: 外側の node→map 解決はループ外に持ち上げ、fullDelete(旧全行が\n // deleteIndexSet に載る=台帳の全エントリが消える)では per-index delete を廃して\n // 台帳ごと 1 回で手放す。\n let poolBudget = fullDelete\n ? maxPooledContents - getPooledContents(bindingInfo).length\n : Number.POSITIVE_INFINITY;\n if (typeof contentMap !== 'undefined') {\n // Set の for...of は行ごとに反復子の結果オブジェクトを割り当てる(消去の scavenge の引き金)ので forEach で回す\n const map = contentMap;\n diff.deleteIndexSet.forEach((deleteIndex) => {\n const content = map.get(deleteIndex);\n if (typeof content !== 'undefined') {\n if (inPlaceContents !== null && inPlaceContents.reused.has(content)) {\n // 同じ位置に入る行がその場で使い回す。自分のノードは DOM に残し、プールにも入れないが、\n // 解体は unmount と同じ(ネストした for / if の Content とアドレス台帳を落とす)\n deactivateContent(content);\n dropNestedContents(content);\n content.unmountInPlace();\n } else if (poolBudget <= 0 && content.tryDestroy()) {\n deleteContentByNode(bindingInfo.node, content);\n } else {\n deactivateContent(content);\n content.unmount();\n setPooledContent(bindingInfo, content);\n poolBudget -= 1;\n }\n if (!fullDelete) {\n map.delete(deleteIndex);\n }\n }\n });\n if (fullDelete) {\n contentByListIndexByNode.delete(bindingInfo.node);\n contentMap = undefined;\n }\n }\n\n let lastNode = bindingInfo.node;\n const elementPathInfo = getPathInfo(listPathInfo.path + '.' + WILDCARD);\n const loopContextStack = context.stateElement.loopContextStack;\n // When the new order contains inversions, contents in the stable set (an LIS\n // of old positions) keep their relative order and must not be moved; moving\n // only the rest avoids the cascade where one swap relocates every row in\n // between. null = no inversions; the position guard below then does no moves.\n const stableIndexSet = computeStableIndexSet(diff);\n let fragment: DocumentFragment | null = null;\n if (diff.newIndexes.length == diff.addIndexSet.size \n && diff.newIndexes.length > 0\n && lastNode.isConnected\n && inPlaceContents === null\n ) {\n // 全部追加の場合はまとめて処理\n fragment = document.createDocumentFragment();\n setRootNodeByFragment(fragment, context.rootNode);\n }\n const ssrMode = inSsr();\n // 自動命名ポリシーは行ごとではなく apply ごとに 1 回だけ引く\n // (docs/view-transition-design.md §6)。既定の manual では null で、\n // 以降の行ループは分岐 1 つ分しか増えない。\n const autoNaming = getAutoNaming();\n const uuid = bindingInfo.uuid ?? '';\n // 追加行ごとの WeakMap 解決を避けるためプール配列も 1 回だけ引く(プールの配列\n // 実体は setPooledContent が一度作ったら不変なので、delete ループ後の参照で安定)\n const pooledContents = pooledContentsByNode.get(bindingInfo.node);\n for(const index of diff.newIndexes) {\n let content: IContent | undefined;\n // add\n if (diff.addIndexSet.has(index)) {\n const stateAddress = createStateAddress(elementPathInfo, index);\n loopContextStack.createLoopContext(stateAddress, (loopContext) => {\n content = inPlaceContents?.byAddedIndex.get(index)\n ?? (typeof pooledContents !== 'undefined' ? pooledContents.pop() : undefined);\n if (typeof content === 'undefined') {\n content = createContent(bindingInfo);\n } else {\n // プール(か同じ位置)から使い回す Content の binding は、同じバッチで**外した行として**適用済みのことがある。\n // 外した行のアドレスへの書き込み(行の葉・要素の置き換え)で enqueue された binding が、この `for`\n // より先に適用された形。印が残ると activateContent の applyChange が飛ばし、新しい行に外した行の\n // 値が残る(表示と state が食い違う)。新しい行として適用し直す\n clearAppliedMarks(content, context);\n }\n // コンテント活性化の前にDOMツリーに追加しておく必要がある\n if (fragment !== null) {\n if (ssrMode) {\n fragment.appendChild(document.createComment(`@@wcs-for-start:${uuid}:${listPathInfo.path}:${index.index}`));\n }\n content.appendTo(fragment);\n if (ssrMode) {\n fragment.appendChild(document.createComment(`@@wcs-for-end:${uuid}:${listPathInfo.path}:${index.index}`));\n }\n } else {\n // Update lastNode for next iteration to ensure correct order\n // Ensure content is in correct position (e.g. if previous siblings were deleted/moved)\n if (lastNode.nextSibling !== content.firstNode) {\n if (ssrMode) {\n const startComment = document.createComment(`@@wcs-for-start:${uuid}:${listPathInfo.path}:${index.index}`);\n lastNode.parentNode!.insertBefore(startComment, lastNode.nextSibling);\n lastNode = startComment;\n }\n content.mountAfter(lastNode);\n }\n if (ssrMode) {\n const endComment = document.createComment(`@@wcs-for-end:${uuid}:${listPathInfo.path}:${index.index}`);\n const afterNode = content.lastNode ?? lastNode;\n afterNode.parentNode!.insertBefore(endComment, afterNode.nextSibling);\n }\n }\n // コンテントを活性化\n activateContent(content, loopContext, context);\n if (autoNaming !== null) {\n applyTransitionName(content, \"row\", autoNaming);\n }\n });\n if (typeof content === 'undefined') {\n raiseError(`Content not found for ListIndex: ${index.index} at path \"${listPathInfo.path}\"`);\n }\n if (inPlaceContents !== null && inPlaceContents.reused.has(content)) {\n // その場で使い回した行の中のコンポーネントは DOM から外れない = 付け替えを知らせる\n // connectedCallback が来ないので、マウントスコープを新しい行の listIndex へ張り直す(#4)。\n // スコープ機能の rowReused hook(webComponent/addressHooks.ts)。hook の無い state は判定 1 個で抜ける\n const hooks = context.stateElement.addressHooks;\n if (hooks) {\n const reused = hooks.rowReused;\n for (let i = 0; i < reused.length; i++) {\n reused[i](context.stateElement, content);\n }\n }\n }\n } else {\n // getContent 相当(undefined→null 正規化は後段の raiseError 判定が null 比較のため維持)\n content = (typeof contentMap !== 'undefined' ? contentMap.get(index) ?? null : null)!;\n if (diff.changeIndexSet.has(index)) {\n // change\n const indexBindings = getIndexBindingsByContent(content);\n for(const indexBinding of indexBindings) {\n applyChange(indexBinding, context);\n }\n }\n // Update lastNode for next iteration to ensure correct order\n // Ensure content is in correct position (e.g. if previous siblings were deleted/moved)\n if (content === null) {\n raiseError(`Content not found for ListIndex: ${index.index} at path \"${listPathInfo.path}\"`);\n }\n // 祖先の unmount(if の非表示など)で解体された行は、ここで物理的に\n // 戻されるだけでは binding が dispose 済みのまま復活しない。位置合わせの\n // 前に判定しておき(mountAfter が mounted を立てる)、戻した後に再活性化する。\n const unmountedByAncestor = !content.mounted;\n // Stable contents are already in correct relative order — but only\n // trust that after physical verification (see isPhysicallyAfter).\n // Contents out of order (and everything unverifiable) settle via the\n // self-healing mountAfter walk below.\n const stable = stableIndexSet !== null && stableIndexSet.has(index)\n && isPhysicallyAfter(lastNode, content.firstNode);\n if (!stable && lastNode.nextSibling !== content.firstNode) {\n content.mountAfter(lastNode);\n }\n if (unmountedByAncestor) {\n // 再活性化しないと、行の同一性が保たれる更新が以後すべて無視される\n // (docs/state-deactivated-content-stale-update.md)。activate は\n // disposed record の再構築を含むので、プール再利用と同じ経路で戻る。\n const revivedContent = content;\n const stateAddress = createStateAddress(elementPathInfo, index);\n loopContextStack.createLoopContext(stateAddress, (loopContext) => {\n activateContent(revivedContent, loopContext, context);\n });\n }\n }\n lastNode = content.lastNode || lastNode;\n if (typeof contentMap === 'undefined') {\n contentMap = new WeakMap<IListIndex, IContent>();\n contentByListIndexByNode.set(bindingInfo.node, contentMap);\n }\n contentMap.set(index, content);\n }\n lastNodeByNode.set(bindingInfo.node, lastNode);\n if (fragment !== null) {\n // Mount all at once\n bindingInfo.node.parentNode!.insertBefore(fragment, bindingInfo.node.nextSibling);\n setRootNodeByFragment(fragment, null);\n }\n}\n","import { config, inSsr } from \"../config\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { activateContent, deactivateContent } from \"../structural/activateContent\";\nimport { getContentSetByNode } from \"../structural/contentsByNode\";\nimport { createContent } from \"../structural/createContent\";\nimport { IContent } from \"../structural/types\";\nimport { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\nimport { applyTransitionName, getAutoNaming } from \"./viewTransitionNaming\";\n\nfunction bindingInfoText(bindingInfo: IBindingInfo): string {\n return `${bindingInfo.bindingType} ${bindingInfo.statePathName} ${bindingInfo.outFilters.map(f => f.filterName).join('|')} ${bindingInfo.node.isConnected ? '(connected)' : '(disconnected)'}`;\n}\n\nexport function applyChangeToIf(\n bindingInfo: IBindingInfo,\n context: IApplyContext,\n rawNewValue: unknown,\n): void {\n const newValue = Boolean(rawNewValue);\n let content: IContent | undefined;\n const contents = getContentSetByNode(bindingInfo.node);\n if (contents.size === 0) {\n content = createContent(bindingInfo);\n } else {\n content = contents.values().next().value!;\n }\n const ssrMode = inSsr();\n const uuid = bindingInfo.uuid ?? '';\n const keyword = bindingInfo.bindingType; // if, elseif, else\n if (!newValue) {\n if (config.debug) {\n console.log(`unmount if content : ${bindingInfoText(bindingInfo)}`);\n }\n deactivateContent(content);\n content.unmount();\n }\n if (newValue) {\n if (config.debug) {\n console.log(`mount if content : ${bindingInfoText(bindingInfo)}`);\n }\n if (ssrMode) {\n const startComment = document.createComment(`@@wcs-${keyword}-start:${uuid}:${bindingInfo.statePathName}`);\n bindingInfo.node.parentNode!.insertBefore(startComment, bindingInfo.node.nextSibling);\n content.mountAfter(startComment);\n const endComment = document.createComment(`@@wcs-${keyword}-end:${uuid}:${bindingInfo.statePathName}`);\n const afterNode = content.lastNode ?? startComment;\n afterNode.parentNode!.insertBefore(endComment, afterNode.nextSibling);\n } else {\n content.mountAfter(bindingInfo.node);\n }\n const loopContext = getLoopContextByNode(bindingInfo.node);\n activateContent(content, loopContext, context);\n // 自動命名(docs/view-transition-design.md §6)。manual(既定)では null。\n const autoNaming = getAutoNaming();\n if (autoNaming !== null) {\n applyTransitionName(content, \"branch\", autoNaming);\n }\n }\n}\n\n","/**\n * SSR 時に HTML 属性で表現できないプロパティバインディングを蓄積するストア。\n * ハイドレーション時にクライアント側で復元する。\n */\n\nexport interface ISsrPropertyEntry {\n propName: string;\n value: unknown;\n}\n\n// node → プロパティエントリのリスト\nconst store: WeakMap<Node, ISsrPropertyEntry[]> = new WeakMap();\n\nexport function addSsrProperty(node: Node, propName: string, value: unknown): void {\n let entries = store.get(node);\n if (!entries) {\n entries = [];\n store.set(node, entries);\n }\n // 同じプロパティの既存エントリは上書き\n const existing = entries.find(e => e.propName === propName);\n if (existing) {\n existing.value = value;\n } else {\n entries.push({ propName, value });\n }\n}\n\nexport function getSsrProperties(node: Node): ISsrPropertyEntry[] {\n return store.get(node) ?? [];\n}\n\nexport function getAllSsrPropertyNodes(): Node[] {\n // WeakMap は列挙不可なので、別途トラッキングが必要\n return Array.from(trackedNodes);\n}\n\nconst trackedNodes: Set<Node> = new Set();\n\nexport function trackSsrPropertyNode(node: Node): void {\n trackedNodes.add(node);\n}\n\nexport function clearSsrPropertyStore(): void {\n trackedNodes.clear();\n}\n","/**\n * Trusted Types (`require-trusted-types-for 'script'`) 対応。正本は docs/csp.md §7。\n *\n * state が HTML sink に流すのは **状態の値**(`innerHTML: path` などのプロパティ\n * バインド)で、ユーザー入力が混ざり得る文字列そのもの。ここに identity policy を\n * 噛ませて通すのは TT の無効化と同義なので、state は自前の policy を作らない。\n * 利用側が sanitizer を持つ policy を注入したときだけ通し、無ければ従来どおり\n * ブラウザに弾かせる(ただし何を設定すれば直るかは必ず言う)。\n *\n * 注入口は全 @wcstack パッケージ共通のグローバルスロット。buildless(CDN 一発)でも\n * inline script 1 本で差し込める:\n *\n * ```js\n * globalThis[Symbol.for(\"wcstack.trustedTypes.policy\")] =\n * trustedTypes.createPolicy(\"my-app\", { createHTML: (s) => DOMPurify.sanitize(s) });\n * ```\n *\n * バンドラ経由なら `setTrustedTypesPolicy()` を使う。値は毎回スロットから読むので\n * 後から差し替えても効く(identity policy を作る router / worker 側だけは\n * `createPolicy` の重複を避けるため生成結果をシングルトンで保持する)。\n */\n\nexport interface IWcsTrustedTypesPolicy {\n createHTML?(input: string): unknown;\n createScriptURL?(input: string): unknown;\n}\n\n/** 利用側が policy を差し込むグローバルスロット(全 @wcstack パッケージ共通)。 */\nexport const TRUSTED_TYPES_POLICY_SLOT = Symbol.for(\"wcstack.trustedTypes.policy\");\n\ntype SymbolSlotHolder = { [key: symbol]: unknown };\n\n/**\n * 利用側が注入した policy を返す。state はここに identity policy をフォールバック\n * させない(それをやると TT を無効化することになる)。\n */\nexport function getTrustedTypesPolicy(): IWcsTrustedTypesPolicy | null {\n const value = (globalThis as SymbolSlotHolder)[TRUSTED_TYPES_POLICY_SLOT];\n if (value === null || typeof value !== \"object\") return null;\n return value as IWcsTrustedTypesPolicy;\n}\n\n/** 利用側 policy を設定する(`null` で解除)。最初のバインド適用前に呼ぶこと。 */\nexport function setTrustedTypesPolicy(policy: IWcsTrustedTypesPolicy | null): void {\n (globalThis as SymbolSlotHolder)[TRUSTED_TYPES_POLICY_SLOT] = policy;\n}\n\n/**\n * TrustedHTML が要求されるプロパティか。`textContent` などの安全な sink は含めない。\n * ホットパス(全プロパティ書き込み)から呼ばれるので文字列比較だけで済ませる。\n */\nexport function isHtmlSinkProp(prop: string): boolean {\n return prop === \"innerHTML\" || prop === \"outerHTML\" || prop === \"srcdoc\";\n}\n\n/**\n * HTML sink へ書く値を利用側 policy に通す。policy が無ければ値をそのまま返す\n * = TT 有効下ではブラウザが弾く(意図どおり)。policy がある場合は TT 非対応\n * ブラウザでも通す: sanitizer は Chromium だけで効いても意味がないため。\n */\nexport function trustHtmlValue(value: unknown): unknown {\n if (typeof value !== \"string\") return value;\n const policy = getTrustedTypesPolicy();\n const createHTML = policy?.createHTML;\n if (typeof createHTML !== \"function\") return value;\n return createHTML.call(policy, value);\n}\n\nlet _enforced: boolean | undefined = undefined;\n\n/**\n * TT が実際に強制されているかを実測する。エラーメッセージの文言に依存しないよう、\n * 使い捨ての要素へ実際に書いて確かめる。`default` policy がある場合は書き込みが\n * 通る=我々の書き込みも通るので、正しく false になる。\n *\n * cold path(書き込みが失敗した後)でしか呼ばれない。\n */\nexport function isTrustedTypesEnforced(): boolean {\n if (_enforced !== undefined) return _enforced;\n if (!(\"trustedTypes\" in globalThis)) {\n _enforced = false;\n return _enforced;\n }\n try {\n document.createElement(\"div\").innerHTML = \"<i></i>\";\n _enforced = false;\n } catch {\n _enforced = true;\n }\n return _enforced;\n}\n\nlet _reported = false;\n\n/** テスト用: 実測キャッシュと一度きりの診断をリセットする。 */\nexport function _resetTrustedTypesDiagnostics(): void {\n _enforced = undefined;\n _reported = false;\n}\n\n/**\n * HTML sink への書き込み失敗を診断する。applyChangeToProperty の catch は\n * `config.debug` 時しか warn しないため、TT が原因のときは黙って壊れていた。\n * 原因と直し方が分かる形で一度だけ報告する。\n */\nexport function reportTrustedTypesBlock(element: Element, prop: string): void {\n if (_reported) return;\n if (!isTrustedTypesEnforced()) return;\n _reported = true;\n const hasPolicy = typeof getTrustedTypesPolicy()?.createHTML === \"function\";\n const cause = hasPolicy\n ? \"The injected policy's createHTML() did not return a TrustedHTML.\"\n : \"No sanitizing policy is installed, and @wcstack/state deliberately does not \"\n + \"pass state values through an identity policy — that would defeat the CSP.\";\n console.error(\n `[@wcstack/state] Writing to \"${prop}\" was blocked by Trusted Types `\n + `(require-trusted-types-for 'script'). ${cause}\\n`\n + `Install a sanitizing policy before the first binding is applied:\\n`\n + ` globalThis[Symbol.for(\"wcstack.trustedTypes.policy\")] =\\n`\n + ` trustedTypes.createPolicy(\"my-app\", { createHTML: (s) => DOMPurify.sanitize(s) });\\n`\n + `Or bind the value as text instead of HTML. See docs/csp.md section 7.`,\n { element, property: prop },\n );\n}\n","import { config, inSsr } from \"../config\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { applyMirrorAttribute, getInputAttributeMirror } from \"../event/getInputAttributeMirror\";\nimport { beginPropagationTransaction, extendPropagationContext, getCurrentPropagationContext, getEdgeId, getWireId, runWithPropagationContext, runWithWriteReceipt } from \"../propagation/propagation\";\nimport { isPossibleTwoWay } from \"../event/isPossibleTwoWay\";\nimport { getCustomElement } from \"../getCustomElement\";\nimport { IBindingInfo } from \"../types\";\nimport { componentApplyHooks } from \"../core/componentApplyHooks\";\nimport { IApplyContext } from \"./types\";\nimport { addSsrProperty, trackSsrPropertyNode } from \"./ssrPropertyStore\";\nimport { isHtmlSinkProp, reportTrustedTypesBlock, trustHtmlValue } from \"../trustedTypes\";\n\n// SSR 時に HTML 属性で代替可能なプロパティ\n// これら以外のプロパティは ssrPropertyStore に蓄積してハイドレーション時に復元\nconst SSR_ATTR_PROPS: Record<string, (element: Element, value: unknown) => void> = {\n value(element, value) {\n if (element.tagName === 'TEXTAREA') {\n element.textContent = String(value ?? '');\n } else {\n element.setAttribute('value', String(value ?? ''));\n }\n },\n checked(element, value) {\n if (value) element.setAttribute('checked', '');\n else element.removeAttribute('checked');\n },\n selected(element, value) {\n if (value) element.setAttribute('selected', '');\n else element.removeAttribute('selected');\n },\n disabled(element, value) {\n if (value) element.setAttribute('disabled', '');\n else element.removeAttribute('disabled');\n },\n selectedIndex(element, value) {\n const options = element.querySelectorAll('option');\n const idx = Number(value);\n for (let i = 0; i < options.length; i++) {\n if (i === idx) options[i].setAttribute('selected', '');\n else options[i].removeAttribute('selected');\n }\n },\n};\n\n/**\n * 表示のプロパティ(要件 B8)。ここへの undefined は「値が無い」ので空にする — 要素の入力と違って\n * 生かすべき既定値が無く、スキップすると、使い回した行に前の行の表示が残る。\n */\nconst DISPLAY_PROPS = new Set<string>([\"textContent\", \"innerText\", \"innerHTML\"]);\n\nexport function applyChangeToProperty(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n if (typeof newValue === \"undefined\" && binding.propSegments.length === 1 && DISPLAY_PROPS.has(binding.propSegments[0])) {\n newValue = \"\";\n }\n // 要素の入力への undefined は「状態が値を持たない=無意見」であり、書き込み自体をスキップして\n // 要素側の既定値を生かす。書き込んでしまうと setter の文字列化で\n // \"undefined\" 属性や removeAttribute が走り要素が壊れる (spread で未初期化\n // slot を配線したときに顕在化)。明示的なクリアは null で表現する。\n // mirror 属性 (applyMirrorAttribute) の「undefined → 属性削除」と同じ語彙。\n if (typeof newValue === \"undefined\") {\n if (config.debug) {\n console.debug(`Skipped property write: state value is undefined.`, {\n element: binding.node,\n propSegments: binding.propSegments,\n statePathName: binding.statePathName,\n });\n }\n return;\n }\n const element = binding.node as Element;\n const propSegments = binding.propSegments;\n if (propSegments.length === 1) {\n const firstSegment = propSegments[0];\n\n const current = (element as any)[firstSegment];\n if (current !== newValue) {\n // 完了前の丸ごとマウント(`state: user`)は、作者の state オブジェクトを親の\n // オブジェクトで置き換えてしまう。あとで戻せるように置き換え前を控える\n // (webComponent/preCompletionWrites.ts — bind-component の機能が core/componentApplyHooks.ts に置く。\n // 置かれていなければ判定 1 回で抜ける)。オブジェクト → オブジェクトの書き込みで\n // 相手がカスタム要素のときだけ台帳に触る(通常の書き込みは typeof 判定で抜ける)。\n if (componentApplyHooks !== null && current !== null && typeof current === 'object'\n && newValue !== null && typeof newValue === 'object'\n && getCustomElement(element) !== null) {\n componentApplyHooks.rememberOverwrittenObject(element, firstSegment, current);\n }\n // Trusted Types: HTML sink (`innerHTML` 等) への書き込みだけ、利用側が注入した\n // sanitizer 付き policy を通す。state が identity policy を作って素通しさせるのは\n // TT の無効化と同義なので採らない(docs/csp.md §7)。sink 以外は文字列比較 3 回で\n // 抜けるので、ホットパスの実コストはほぼ無い。\n const isHtmlSink = isHtmlSinkProp(firstSegment);\n\n const performWrite = (): void => {\n let propertyWriteSucceeded = false;\n try {\n (element as any)[firstSegment] = isHtmlSink ? trustHtmlValue(newValue) : newValue;\n propertyWriteSucceeded = true;\n } catch (error) {\n // TT が原因のときは config.debug に関係なく報告する。ここを黙って握り潰すと\n // 「バインドを書いたのに何も起きない」という最悪の壊れ方をする。\n if (isHtmlSink) {\n reportTrustedTypesBlock(element, firstSegment);\n }\n if (config.debug) {\n console.warn(`Failed to set property '${firstSegment}' on element.`, {\n element,\n newValue,\n error\n });\n }\n }\n // wc-bindable inputs[].attribute ミラー。プロパティ書き込みが成功したときだけ\n // 属性へ反映する。setter が値を拒否した場合に属性だけ進んでしまうと\n // property と attribute が乖離し、attributeChangedCallback や CSS セレクタが\n // 実際のプロパティ値と矛盾した状態で発火するため、ここでガードする。\n if (propertyWriteSucceeded) {\n const mirrorAttr = getInputAttributeMirror(element, firstSegment);\n if (mirrorAttr !== null) {\n try {\n applyMirrorAttribute(element, mirrorAttr, newValue);\n } catch (error) {\n if (config.debug) {\n console.warn(`Failed to mirror attribute '${mirrorAttr}' on element.`, {\n element,\n newValue,\n error\n });\n }\n }\n }\n }\n };\n // Zero-cost fast path (§4 最適化): the propagation edge / WriteReceipt\n // machinery only matters when the element write can *echo* — i.e. the setter\n // may synchronously dispatch an event a two-way wire feeds back to state.\n // `isPossibleTwoWay` is the same conservative check the two-way listener\n // registration uses, and it is cheap for the common one-way case (textContent\n // / class / style on plain elements return false fast). One-way bindings can\n // never re-traverse an edge, so skipping the context/receipt is safe and\n // avoids a per-apply Set copy + receipt allocation. Diamond / coalescing are\n // unaffected — those ride the write-transaction context threaded through the\n // updater, not the element edge.\n if (config.enablePropagationContext && isPossibleTwoWay(element, firstSegment)) {\n // Phase 3: state → element edge の通過を記録し、同じ transaction が\n // 同じ edge を再度通ろうとした場合だけ抑止する(設計書 §4 規則 2)。\n // 書き込みは WriteReceipt scope で包み、setter が同期 dispatch する\n // event が confirmation / 正規化を判定できるようにする(規則 3)。\n const wireId = getWireId(element, firstSegment, binding.statePathName);\n const edgeId = getEdgeId(wireId, \"to-element\");\n const baseContext = _context?.propagationContextByBinding?.get(binding)\n ?? getCurrentPropagationContext()\n ?? beginPropagationTransaction(wireId);\n if (baseContext.visitedEdges.has(edgeId)) {\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"propagation:suppressed\",\n reason: \"visited-edge\",\n transactionId: baseContext.transactionId,\n edgeId,\n node: element,\n member: firstSegment,\n });\n }\n } else {\n const extendedContext = extendPropagationContext(baseContext, edgeId);\n runWithPropagationContext(extendedContext, () =>\n runWithWriteReceipt(element, firstSegment, newValue, wireId, extendedContext.transactionId, performWrite));\n }\n } else {\n performWrite();\n }\n }\n if (inSsr()) {\n const attrHandler = SSR_ATTR_PROPS[firstSegment];\n if (attrHandler) {\n // 属性で代替可能 → HTML 属性に反映\n attrHandler(element, newValue);\n } else {\n // 属性で代替不可 → ハイドレーション用ストアに蓄積\n addSsrProperty(element, firstSegment, newValue);\n trackSsrPropertyNode(element);\n }\n }\n return;\n }\n const firstSegment = propSegments[0];\n let subObject = (element as any)[firstSegment];\n for (let i = 1; i < propSegments.length - 1; i++) {\n const segment = propSegments[i];\n if (subObject == null) {\n return;\n }\n subObject = subObject[segment];\n }\n const lastSegment = propSegments[propSegments.length - 1];\n const oldValue = subObject[lastSegment];\n if (oldValue !== newValue) {\n if (Object.isFrozen(subObject)) {\n if (config.debug) {\n console.warn(`Attempting to set property on frozen object.`, {\n element,\n propSegments,\n oldValue,\n newValue\n });\n }\n return;\n }\n // 完了前の部分マウント(`state.theme: theme`)が、作者の state オブジェクトに無かった\n // キーを作る(積み)ことを控える。R1 の衝突報告はこのキーを作者のものとして扱わない\n // (webComponent/preCompletionWrites.ts — core/componentApplyHooks.ts 越し)\n if (componentApplyHooks !== null && propSegments.length === 2 && typeof subObject === 'object' && subObject !== null\n && getCustomElement(element) !== null) {\n if (!(lastSegment in subObject)) {\n componentApplyHooks.recordInjectedKey(element, firstSegment, lastSegment);\n } else {\n // 既存キーの上書き: 作者の値を控える(v2 の厳格 R1 が snapshot 前に復元する)。\n // 完了後の (element, stateProp) への適用はここへルーティングされない\n //(applyChangeToWebComponent の no-op へ行く — apply/applyChange.ts)ので、\n // ここに来る上書きは常に完了前=控えの対象で良い\n componentApplyHooks.rememberOverwrittenValue(element, firstSegment, lastSegment, subObject[lastSegment]);\n }\n }\n try {\n subObject[lastSegment] = newValue;\n } catch (error) {\n if (config.debug) {\n console.warn(`Failed to set property on sub-object.`, {\n element,\n propSegments,\n oldValue,\n newValue,\n error\n });\n }\n }\n }\n // サブオブジェクトプロパティ (e.g. style.xxx) は属性に反映済みなのでストア不要\n}\n","import { getCustomElement } from \"../getCustomElement\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry\";\nimport { readBindableDeclaration } from \"../protocol/wcBindableReader\";\n\n/**\n * 要素 `element` の `propName` プロパティ書き込みに対して、\n * wc-bindable inputs の `attribute` ミラー先属性名を返す。\n *\n * - wc-bindable でないネイティブ要素や、inputs 未宣言、attribute フィールド無しは null\n * - inputs に同名宣言があっても `attribute` を持たないものはミラー対象外\n *\n * 戻り値の string がそのまま `setAttribute(name, value)` の name となる。\n */\nexport function getInputAttributeMirror(element: Element, propName: string): string | null {\n const customTagName = getCustomElement(element);\n if (customTagName === null) {\n return null;\n }\n const customClass = getCustomElementRegistry(element)?.get(customTagName);\n if (typeof customClass === \"undefined\") {\n return null;\n }\n const input = readBindableDeclaration(element)?.declaredInputs.get(propName);\n if (typeof input?.attribute === \"string\" && input.attribute.length > 0) {\n return input.attribute;\n }\n return null;\n}\n\n/**\n * mirror 属性値の表現を決める。\n * - null / undefined → 属性削除\n * - object / array → JSON.stringify (失敗時は String(value))\n * - その他 (string / number / boolean / bigint) → String(value)\n */\nexport function applyMirrorAttribute(element: Element, attributeName: string, value: unknown): void {\n if (value === null || typeof value === \"undefined\") {\n element.removeAttribute(attributeName);\n return;\n }\n let formatted: string;\n if (typeof value === \"object\") {\n try {\n formatted = JSON.stringify(value);\n } catch {\n formatted = String(value);\n }\n } else {\n formatted = String(value);\n }\n element.setAttribute(attributeName, formatted);\n}\n","import { inSsr } from \"../config\";\nimport { IBindingInfo } from \"../binding/types\";\nimport { IApplyContext } from \"./types\";\n\nconst ssrWrappedNodes: WeakSet<Node> = new WeakSet();\n\nexport function applyChangeToText(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n // nodeValue は nullable DOMString(実ブラウザでは null / undefined とも空文字に\n // 正規化される)ため、比較前に同じ規則で文字列化する。生値のまま比較すると\n // 数値など非文字列値は常に不一致になり、同値でも毎回 DOM 書き込みが走る。\n // 注: happy-dom は undefined を \"undefined\" にする非準拠実装なので String() に\n // 頼らず明示的に \"\" へ正規化する。\n const text = newValue === null || newValue === undefined ? \"\" : String(newValue);\n if (binding.replaceNode.nodeValue !== text) {\n binding.replaceNode.nodeValue = text;\n }\n // SSR モード時: テキストノードの前後にコメントを挿入して境界を明示\n if (inSsr() && !ssrWrappedNodes.has(binding.replaceNode)) {\n ssrWrappedNodes.add(binding.replaceNode);\n const parentNode = binding.replaceNode.parentNode;\n if (parentNode) {\n const path = binding.statePathName;\n const startComment = document.createComment(`@@wcs-text-start:${path}`);\n const endComment = document.createComment(`@@wcs-text-end:${path}`);\n parentNode.insertBefore(startComment, binding.replaceNode);\n parentNode.insertBefore(endComment, binding.replaceNode.nextSibling);\n }\n }\n}\n","import { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\n\n/**\n * カスタム要素の state プロパティバインディング(`state[.sub]: path`)に対する\n * 適用のルート先(apply/applyChange.ts の resolveCustomElementApply)。\n *\n * v2 では state プロパティのバインディングは全てマウント(webComponent/mountScope.ts)で、\n * 配送は「翻訳されたバインディング+単一台帳+静的依存」が担う — 親→子の再読込\n * 通知チャネル(v1 の innerState への $postUpdate)はこの経路では何も運ぶものが無い。\n * 完了済みの (element, stateProp) への適用は意図的な no-op。\n *\n * 未完了(宣言前)の適用はここへ来ない(applyChangeToProperty の積み、または\n * skipPendingMountWrite — apply/applyChange.ts)。\n */\nexport function applyChangeToWebComponent(_binding: IBindingInfo, _context: IApplyContext, _newValue: unknown): void {\n // no-op(上記)\n return;\n}\n","import { getStateAddressByBindingInfo } from \"../binding/getStateAddressByBindingInfo\";\nimport { IBindingInfo } from \"../binding/types\";\nimport { INDEX_BY_INDEX_NAME } from \"../define\";\nimport { getIndexValueByLoopContext } from \"../list/getIndexValueByLoopContext\";\nimport { getLoopContextByNode } from \"../list/loopContextByNode\";\nimport { getByAddressSymbol } from \"../proxy/symbols\";\nimport { IStateProxy } from \"../proxy/types\";\nimport { raiseError } from \"../raiseError\";\n\nexport function getValue(state: IStateProxy, binding: IBindingInfo): any {\n const stateAddress = getStateAddressByBindingInfo(binding);\n if (stateAddress.pathInfo.path in INDEX_BY_INDEX_NAME) {\n const loopContext = getLoopContextByNode(binding.node);\n if (loopContext === null) {\n raiseError(`ListIndex not found for binding: ${binding.statePathName}`);\n }\n return getIndexValueByLoopContext(loopContext, stateAddress.pathInfo.path);\n } else {\n return state[getByAddressSymbol](stateAddress);\n }\n}\n","import { INDEX_BY_INDEX_NAME } from \"../define\";\nimport { wildcardScopeMessage } from \"../pathDiagnostics\";\nimport { raiseError } from \"../raiseError\";\nimport { ILoopContext } from \"./types\";\nimport { listIndexAtWildcard } from \"./wildcardLevel\";\n\n// indexName ... $1, $2, ...\nexport function getIndexValueByLoopContext(loopContext: ILoopContext, indexName: string): number | null {\n if (loopContext.listIndex === null) {\n raiseError(`ListIndex not found for loopContext:`);\n }\n const indexPos = INDEX_BY_INDEX_NAME[indexName];\n if (typeof indexPos === \"undefined\") {\n raiseError(`Invalid index name: ${indexName}`);\n }\n const listIndex = listIndexAtWildcard(loopContext.listIndex, indexPos, loopContext.pathInfo.wildcardCount);\n if (listIndex === null) {\n // 位置が範囲外 = `$2` を 1 段のループの中で読んだ、という取り違え。\n // 元の文面(`Index not found at position 1 for loopContext:`)は内部の言葉で、\n // 何段必要で何段あるのかが書かれていなかった。\n raiseError(wildcardScopeMessage(`\"${indexName}\"`, indexPos + 1, loopContext.pathInfo.wildcardCount));\n }\n return listIndex.index;\n}","import { getBindingSession } from \"../bindings/BindingSession.js\";\nimport { getDefinitionCoordinator } from \"../bindings/DefinitionCoordinator.js\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry.js\";\nimport { IBindingInfo } from \"../types.js\";\nimport { applyChangeFromBindings } from \"./applyChangeFromBindings.js\";\n\nconst scheduledBindings = new WeakSet<IBindingInfo>();\n\nfunction reportFailure(tagName: string, error: unknown): void {\n console.error(`[@wcstack/state] deferred apply failed for <${tagName}>.`, error);\n}\n\nexport function scheduleDeferredApply(binding: IBindingInfo, tagName: string): void {\n if (scheduledBindings.has(binding)) return;\n scheduledBindings.add(binding);\n\n const applyLatest = (): void => {\n scheduledBindings.delete(binding);\n const currentSession = getBindingSession(binding);\n if (currentSession !== null && !currentSession.shouldApplyState(binding)) {\n return;\n }\n applyChangeFromBindings([binding]);\n };\n const reject = (error: unknown): void => {\n scheduledBindings.delete(binding);\n reportFailure(tagName, error);\n };\n\n const session = getBindingSession(binding);\n if (session !== null) {\n const cancel = session.deferUntilDefined(binding.replaceNode, tagName, applyLatest, reject);\n if (!session.addTeardown(binding, () => {\n scheduledBindings.delete(binding);\n cancel();\n })) {\n scheduledBindings.delete(binding);\n cancel();\n }\n return;\n }\n\n // Compatibility fallback for direct applyChange() callers outside a session.\n const registry = getCustomElementRegistry(binding.replaceNode);\n if (registry === null) {\n scheduledBindings.delete(binding);\n reportFailure(tagName, new Error(\"CustomElementRegistry is unavailable.\"));\n return;\n }\n getDefinitionCoordinator(registry).wait(tagName, () => {\n if (!binding.replaceNode.isConnected) {\n scheduledBindings.delete(binding);\n return;\n }\n applyLatest();\n }, reject);\n}\n","import { getAbsoluteStateAddressByBinding } from \"../binding/getAbsoluteStateAddressByBinding.js\";\nimport { ATTR_NAMESPACE, CLASS_NAMESPACE, COMMAND_NAMESPACE, STYLE_NAMESPACE } from \"../define.js\";\nimport { getBindingSession } from \"../bindings/BindingSession.js\";\nimport { getCustomElement } from \"../getCustomElement.js\";\nimport { getCustomElementRegistry } from \"../platform/customElementRegistry.js\";\nimport { raiseError } from \"../raiseError.js\";\nimport { getStateElement } from \"../stateElementByName.js\";\nimport { IBindingInfo } from \"../types.js\";\nimport { componentApplyHooks } from \"../core/componentApplyHooks.js\";\nimport { applyChangeToAttribute } from \"./applyChangeToAttribute.js\";\nimport { applyChangeToCheckbox } from \"./applyChangeToCheckbox.js\";\nimport { applyChangeToClass } from \"./applyChangeToClass.js\";\nimport { applyChangeToCommand } from \"./applyChangeToCommand.js\";\nimport { applyChangeToFor } from \"./applyChangeToFor.js\";\nimport { applyChangeToIf } from \"./applyChangeToIf.js\";\nimport { applyChangeToProperty } from \"./applyChangeToProperty.js\";\nimport { applyChangeToRadio } from \"./applyChangeToRadio.js\";\nimport { applyChangeToStyle } from \"./applyChangeToStyle.js\";\nimport { applyChangeToText } from \"./applyChangeToText.js\";\nimport { applyChangeToWebComponent } from \"./applyChangeToWebComponent.js\";\nimport { getFilteredValue } from \"./getFilteredValue.js\";\nimport { getValue } from \"./getValue.js\";\nimport { getRootNodeByFragment } from \"./rootNodeByFragment.js\";\nimport { scheduleDeferredApply } from \"./scheduleDeferredApply.js\";\nimport { ApplyChangeFn, IApplyContext } from \"./types.js\";\n\n// キーは define.ts の namespace 語彙定数(manifest.syntax.bindingTypes.propNamespaces と\n// 同一の正本)。集合の一致は __tests__/manifest.test.ts の drift テストが強制するため\n// export する(manifest エントリは DOM 非依存でこのファイルを import できない)。\nexport const applyChangeByFirstSegment: { readonly [key: string]: ApplyChangeFn } = Object.freeze({\n [CLASS_NAMESPACE]: applyChangeToClass,\n [ATTR_NAMESPACE]: applyChangeToAttribute,\n [STYLE_NAMESPACE]: applyChangeToStyle,\n [COMMAND_NAMESPACE]: applyChangeToCommand,\n});\n\nconst applyChangeByBindingType: { [key: string]: ApplyChangeFn } = {\n \"text\": applyChangeToText,\n \"for\": applyChangeToFor,\n \"if\": applyChangeToIf,\n \"else\": applyChangeToIf,\n \"elseif\": applyChangeToIf,\n \"radio\": applyChangeToRadio,\n \"checkbox\": applyChangeToCheckbox,\n};\n\nconst fnByBinding: WeakMap<IBindingInfo, ApplyChangeFn> = new WeakMap();\nconst deferredSelectBindingByBinding: WeakMap<IBindingInfo, boolean> = new WeakMap();\n\n// 未 define カスタム要素チェックの確定メモ。customTag が無い、または define 済みを\n// 一度確認したら以後は不変(define は不可逆)なので apply 毎の getCustomElement /\n// registry 照会を省略できる。scoped registry を導入する場合はこの不可逆前提を再検討。\nconst definedApplyVerifiedByBinding: WeakMap<IBindingInfo, boolean> = new WeakMap();\n\n/**\n * 宣言済みマウントの完了前の初期適用は書かない。子が完了すればマウント経由で\n * ライブに読むので、ここで親の値を書く意味は無い(書くと害がある —\n * webComponent/completeWebComponent.ts の宣言台帳を参照 — core/componentApplyHooks.ts 越しに引く)。v2 では部分規則\n *(`state.name: user.name`)にも同じ原則を適用する: 積みの上書きが作者の既定値を\n * 汚すと、厳格 R1(作者の own data key は私有・D19)の privateSnapshot が親の値で\n * 汚染される。積みが要るのは**未宣言**(`<wcs-state bind-component>` がまだ来ていない\n * 非同期定義や、そもそも bind-component の無い素のプロパティパス配線)だけ。\n */\nfunction skipPendingMountWrite(): void {}\n\n/**\n * カスタム要素へのプロパティバインディングの適用関数を決める。\n *\n * - 完了済み(bindWebComponent が公開プロパティを差し替え終えた)→ 値を運ばない\n * 再読込通知(applyChangeToWebComponent)。1 セグメント(`state: user`)も含む —\n * 残余が空なら「子の登録済みパス全部を読み直せ」の意味(ルート規則。\n * docs/state-mount-design.md §3-2 / impl-plan P1-2)\n * - 未完了だが `<wcs-state bind-component>` が宣言済み → 今回は\n * 書かない(skipPendingMountWrite — 部分規則も含む、上記)\n * - それ以外(未宣言)→ 素のプロパティ書き込み(積み)\n *\n * 以前は 1 セグメントを通知チャネルから除いていた(残余が空だと applyChangeToWebComponent\n * が raiseError し、updater の drain が捕まえないので同じバッチの無関係な更新まで\n * 巻き添えにした)。残余空がルート規則の意味を持った今、その除外は要らない。\n */\nfunction resolveCustomElementApply(binding: IBindingInfo): ApplyChangeFn {\n // 完了・宣言の台帳は bind-component の機能が受け口に置く。置かれていなければ素の書き込み\n const hooks = componentApplyHooks;\n if (hooks !== null) {\n const element = binding.replaceNode as Element;\n const stateProp = binding.propSegments[0];\n if (hooks.isComplete(element, stateProp)) {\n return applyChangeToWebComponent;\n }\n if (hooks.isDeclared(element, stateProp)) {\n return skipPendingMountWrite;\n }\n }\n return applyChangeToProperty;\n}\n\nfunction _applyChange(binding: IBindingInfo, context: IApplyContext): void {\n applyValueToBinding(binding, context, getValue(context.state, binding));\n}\n\n/**\n * 値が既に手元にあるときの `_applyChange` の後半(フィルタ適用 → DOM 書き込み)。\n * プラン初期描画(structural/activateContent.ts、設計 R2)が、行オブジェクトから直に\n * 読んだ素の値を渡すために使う。値の出どころ以外は通常の適用と同じ経路。\n */\nexport function applyValueToBinding(binding: IBindingInfo, context: IApplyContext, value: unknown): void {\n const filteredValue = getFilteredValue(value, binding.outFilters);\n\n if (deferredSelectBindingByBinding.get(binding) === true) {\n context.deferredSelectBindings.push({ binding, value: filteredValue, stateElement: context.stateElement });\n return;\n }\n let fn = fnByBinding.get(binding);\n if (typeof fn !== 'undefined') {\n fn(binding, context, filteredValue);\n return;\n }\n if (fnByBinding.has(binding)) {\n fn = resolveCustomElementApply(binding);\n if (fn === applyChangeToWebComponent) {\n fnByBinding.set(binding, fn); // 確定したのでキャッシュ\n }\n fn(binding, context, filteredValue);\n return;\n }\n\n fn = applyChangeByBindingType[binding.bindingType];\n if (typeof fn === 'undefined') {\n const firstSegment = binding.propSegments[0];\n fn = applyChangeByFirstSegment[firstSegment];\n fnByBinding.set(binding, fn);\n if (typeof fn === 'undefined') {\n const customTag = getCustomElement(binding.replaceNode);\n if (customTag) {\n fn = resolveCustomElementApply(binding);\n if (fn === applyChangeToWebComponent) {\n fnByBinding.set(binding, fn); // 確定したのでキャッシュ\n }\n } else {\n fn = applyChangeToProperty;\n fnByBinding.set(binding, fn);\n }\n }\n }\n if (fn === applyChangeToProperty) {\n const element = binding.node as Element;\n if (element.tagName === 'SELECT') {\n const propName = binding.propSegments[0];\n if (propName === 'value' || propName === 'selectedIndex') {\n context.deferredSelectBindings.push({ binding, value: filteredValue, stateElement: context.stateElement });\n deferredSelectBindingByBinding.set(binding, true);\n return;\n }\n }\n }\n fn(binding, context, filteredValue);\n}\n\nexport function applyChange(binding: IBindingInfo, context: IApplyContext): void {\n if (context.appliedBindingSet.has(binding)) {\n return;\n }\n context.appliedBindingSet.add(binding);\n // $updatedCallback が定義されていない state では、更新アドレスの集計自体が\n // 不要(drain 終端の呼び出しごと省略される)。大量バインディング適用時の\n // Set 蓄積を避ける。undefined(テスト用モック等)は従来通り集計する。\n if (context.stateElement.hasUpdatedCallback !== false) {\n const absAddress = getAbsoluteStateAddressByBinding(binding);\n if (context.updatedAbsAddressSetByStateElement.has(context.stateElement)) {\n const addressSet = context.updatedAbsAddressSetByStateElement.get(context.stateElement)!;\n addressSet.add(absAddress);\n } else {\n context.updatedAbsAddressSetByStateElement.set(context.stateElement, new Set([\n absAddress\n ]));\n }\n }\n const bindingSession = getBindingSession(binding);\n if (bindingSession !== null && !bindingSession.shouldApplyState(binding)) {\n return;\n }\n if (binding.bindingType === \"event\") {\n return;\n }\n if (definedApplyVerifiedByBinding.get(binding) !== true) {\n const customTag = getCustomElement(binding.replaceNode);\n if (customTag) {\n if (getCustomElementRegistry(binding.replaceNode)?.get(customTag) === undefined) {\n // 未 define のカスタム要素へは今は適用できない(accessor 未確立の要素に\n // 素の own property を書くと upgrade 後に class accessor を隠してしまう)。\n // whenDefined 後に最新 state 値で再適用する(two-way attach / deferred\n // spread と対称。docs/state-binding-init-races.md §2)。\n scheduleDeferredApply(binding, customTag);\n return;\n }\n }\n // customTag 無し or define 済み確定 → 以後この検査を省略(不可逆)\n definedApplyVerifiedByBinding.set(binding, true);\n }\n // applyChangeFromBindings のグループ化ループが解決済みルートの一致を検証済みの\n // 場合、getRootNode の再解決(native 呼び出し)を省略できる。activateContent 経由\n // (フラグメント内の新規 content)も、フラグメントは setRootNodeByFragment で\n // context.rootNode に解決されるため同じ不変条件が成り立つ。\n if (context.sameRootVerified === true) {\n _applyChange(binding, context);\n return;\n }\n let rootNode: Node | null = binding.replaceNode.getRootNode() as Node;\n if (rootNode instanceof DocumentFragment && !(rootNode instanceof ShadowRoot)) {\n rootNode = getRootNodeByFragment(rootNode);\n if (rootNode === null) {\n raiseError(`Root node for fragment not found for binding.`);\n }\n }\n if (rootNode !== context.rootNode) {\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n stateElement.createState(\"readonly\", (targetState) => {\n const newContext = {\n rootNode: rootNode,\n stateElement: stateElement,\n state: targetState,\n appliedBindingSet: context.appliedBindingSet,\n newListValueByAbsAddress: context.newListValueByAbsAddress,\n updatedAbsAddressSetByStateElement: context.updatedAbsAddressSetByStateElement,\n deferredSelectBindings: context.deferredSelectBindings,\n }\n _applyChange(binding, newContext);\n });\n } else {\n _applyChange(binding, context);\n }\n}\n","import { raiseError } from \"../raiseError\";\nimport { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\n\nexport function applyChangeToClass(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n const element = binding.node as Element;\n const className = binding.propSegments[1];\n if (typeof newValue !== 'boolean') {\n raiseError(`Invalid value for class application: expected boolean, got ${typeof newValue}`);\n }\n element.classList.toggle(className, newValue as boolean);\n}","import { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\n\nexport function applyChangeToAttribute(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n const element = binding.node as Element;\n const attrName = binding.propSegments[1];\n // 値が無い(undefined / null)属性は削除する(要件 B8)。以前は文字列 \"undefined\" / \"null\" を書いていた\n if (newValue === undefined || newValue === null) {\n if (element.hasAttribute(attrName)) {\n element.removeAttribute(attrName);\n }\n return;\n }\n if (element.getAttribute(attrName) !== newValue) {\n element.setAttribute(attrName, newValue as string);\n }\n}\n","import { IBindingInfo } from \"../types\";\nimport { IApplyContext } from \"./types\";\n\nexport function applyChangeToStyle(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n const styleName = binding.propSegments[1];\n const style = (binding.node as HTMLElement).style;\n // 値が無い(undefined / null)スタイルは消す(要件 B8)\n if (newValue === undefined || newValue === null) {\n newValue = \"\";\n }\n const currentValue = (style as any)[styleName];\n if (currentValue !== newValue) {\n (style as any)[styleName] = newValue;\n }\n}\n","import { IBindingInfo } from \"../types\";\nimport { getFilteredValue } from \"./getFilteredValue\";\nimport { IApplyContext } from \"./types\";\n\nexport function applyChangeToRadio(binding: IBindingInfo, _context: IApplyContext, newValue: unknown): void {\n const element = binding.node as HTMLInputElement;\n const elementValue = element.value;\n const elementFilteredValue = getFilteredValue(elementValue, binding.inFilters);\n element.checked = newValue === elementFilteredValue;\n}\n","import { IAbsoluteStateAddress } from \"../address/types\";\nimport { IStateElement } from \"../components/types\";\nimport { config } from \"../config\";\nimport { devtoolsSink } from \"../platform/devtoolsSink\";\nimport { setLastListValueByAbsoluteStateAddress } from \"../list/lastListValueByAbsoluteStateAddress\";\nimport { setStateListBaseline } from \"../list/stateListBaseline\";\nimport { errorCallbackSymbol, updatedCallbackSymbol } from \"../proxy/symbols\";\nimport { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IPropagationContext } from \"../propagation/types\";\nimport { IBindingErrorInfo, IBindingInfo } from \"../types\";\nimport { applyChange } from \"./applyChange\";\nimport { applyChangeToProperty } from \"./applyChangeToProperty\";\nimport { getRootNodeByFragment } from \"./rootNodeByFragment\";\nimport { IApplyContext, IDeferredSelectBinding } from \"./types\";\n\n/** $errorCallback へ配送する失敗 1 件(drain 末尾でまとめて配送する) */\ninterface IBindingFailure {\n readonly error: unknown;\n readonly info: IBindingErrorInfo;\n}\n\n/**\n * バインディング 1 本の適用失敗を報告する(握り潰しではない)。\n *\n * `console.error` だけだと devtools からは「静かに握られた失敗」が見えないため、\n * 同じ地点から sink にも流す(`state:watch-error` と同じ位置づけ)。\n * 値と DOM は巻き戻さない — 伝播 hop 上限超過・watch 連鎖打ち切りと同じ姿勢。\n *\n * state が `$errorCallback` を宣言していれば、console.error の代わりにそこへ配送する\n * (作者が報告を引き取った。ページ内で受けるための口)。配送は batch の末尾 —\n * $updatedCallback と同じ位置 — にまとめる。devtools sink へは宣言の有無に関わらず流す。\n */\nfunction reportBindingApplyError(\n binding: IBindingInfo,\n error: unknown,\n stateElement: IStateElement | null,\n failuresByStateElement: Map<IStateElement, IBindingFailure[]>,\n): void {\n const handled = stateElement !== null && stateElement.hasErrorCallback === true;\n if (handled) {\n const info: IBindingErrorInfo = {\n path: binding.statePathName,\n bindingType: binding.bindingType,\n node: binding.node,\n };\n const failures = failuresByStateElement.get(stateElement);\n if (failures === undefined) {\n failuresByStateElement.set(stateElement, [{ error, info }]);\n } else {\n failures.push({ error, info });\n }\n } else {\n console.error(\n `[@wcstack/state] binding \"${binding.bindingType}: ${binding.statePathName}\" failed to apply; ` +\n `the rest of this batch continues.`,\n { node: binding.node, error },\n );\n }\n if (devtoolsSink !== null) {\n devtoolsSink({\n type: \"state:binding-apply-error\",\n path: binding.statePathName,\n bindingType: binding.bindingType,\n error,\n });\n }\n}\n\n/**\n * バインディング情報の配列を処理し、各バインディングに対して状態の変更を適用する。\n *\n * 2フェーズで処理:\n * Phase 1: 構造的更新(for/if) + 値更新(select以外) — select.value/selectedIndex は遅延収集\n * Phase 2: 遅延されたselect.value/selectedIndex を適用(option要素の生成後)\n *\n * 最適化のため、以下のグループ化を行う:\n * 同じ rootNode を持つバインディングをグループ化 → createState の呼び出しを削減\n *\n * `options.updatedCallback === false` は `$updatedCallback` を呼ばない。唯一の呼び手は再セットの\n * 再適用(apply/reapplyStateBindings.ts)で、再セットは書き込みではないため。`$errorCallback` は\n * 適用の失敗の報告なので、どの経路でも配送する。\n */\nexport function applyChangeFromBindings(\n bindings: IBindingInfo[],\n propagationContextByBinding?: ReadonlyMap<IBindingInfo, IPropagationContext | null>,\n options?: { readonly updatedCallback?: boolean },\n): void {\n let bindingIndex = 0;\n const appliedBindingSet: Set<IBindingInfo> = new Set();\n const newListValueByAbsAddress: Map<IAbsoluteStateAddress, readonly unknown[]> = new Map();\n const updatedAbsAddressSetByStateElement: Map<IStateElement, Set<IAbsoluteStateAddress>> = new Map();\n const deferredSelectBindings: IDeferredSelectBinding[] = [];\n const failuresByStateElement: Map<IStateElement, IBindingFailure[]> = new Map();\n\n // Phase 1: 構造的更新 + 値更新(select.value/selectedIndex は遅延)\n while(bindingIndex < bindings.length) {\n let binding = bindings[bindingIndex];\n if (binding.replaceNode.isConnected === false) {\n // 切断されているバインディングは無視、本来は事前に除去されているはず\n if (config.debug) {\n console.log(`applyChangeFromBindings: skip disconnected binding: ${binding.bindingType} ${binding.statePathName} on ${binding.node.nodeName}`, binding);\n }\n bindingIndex++;\n continue;\n }\n let rootNode: Node | null = binding.replaceNode.getRootNode() as Node;\n if (rootNode instanceof DocumentFragment && !(rootNode instanceof ShadowRoot)) {\n rootNode = getRootNodeByFragment(rootNode);\n if (rootNode === null) {\n raiseError(`Root node for fragment not found for binding.`);\n }\n }\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for binding.`);\n }\n\n stateElement.createState(\"readonly\", (state) => {\n const context: IApplyContext = {\n rootNode: rootNode,\n stateElement: stateElement,\n state: state,\n appliedBindingSet: appliedBindingSet,\n newListValueByAbsAddress: newListValueByAbsAddress,\n updatedAbsAddressSetByStateElement: updatedAbsAddressSetByStateElement,\n deferredSelectBindings: deferredSelectBindings,\n // グループ内の binding は下の do/while が「解決済みルート === rootNode」を\n // 検証してから applyChange に渡す(applyChange 側の getRootNode 省略の根拠)\n sameRootVerified: true,\n propagationContextByBinding: propagationContextByBinding,\n };\n\n do {\n // 1 本の失敗を 1 本に閉じ込める(§ エラー隔離)。隔離しないと、stale な\n // アドレスを読んだ 1 本の throw がバッチの残り・$updatedCallback・drain\n // リスナー($watch / $streams restart)まで道連れにし、「値は新しいのに\n // DOM は途中まで」という再現困難な半端状態を作る。\n try {\n applyChange(binding, context);\n } catch (error) {\n reportBindingApplyError(binding, error, stateElement, failuresByStateElement);\n }\n bindingIndex++;\n\n const nextBindingInfo: IBindingInfo | undefined = bindings[bindingIndex];\n if (!nextBindingInfo) break; // 終端に到達\n const nextRootNode = nextBindingInfo.replaceNode.getRootNode() as Node;\n if (nextRootNode !== context.rootNode) break; // ルートが変わった\n binding = nextBindingInfo;\n } while(true); // eslint-disable-line no-constant-condition\n });\n }\n // Phase 2: 遅延されたselect.value/selectedIndex を適用\n // applyChangeToProperty は propagationContextByBinding 以外の context を\n // 参照しないため、遅延分は最小 context を渡す\n for (const { binding, value, stateElement } of deferredSelectBindings) {\n try {\n applyChangeToProperty(binding, { propagationContextByBinding } as unknown as IApplyContext, value);\n } catch (error) {\n reportBindingApplyError(binding, error, stateElement ?? null, failuresByStateElement);\n }\n }\n\n for(const [ absAddress, newListValue ] of newListValueByAbsAddress.entries()) {\n setLastListValueByAbsoluteStateAddress(absAddress, newListValue);\n // 描画の基準とは別に、state 側の基準(読み・依存ウォークの共有正本)も進める。\n // 初回描画はどの書き込みも経ていないので、ここで観測しておかないと最初の構造\n // 書き込みで基準が空のまま ListIndex を鋳造してしまう(E1)。\n setStateListBaseline(absAddress, newListValue);\n }\n if (options?.updatedCallback !== false) {\n for(const [ stateElement, absAddressSet ] of updatedAbsAddressSetByStateElement.entries()) {\n stateElement.createState(\"writable\", (state) => {\n state[updatedCallbackSymbol](Array.from(absAddressSet));\n });\n }\n }\n // $errorCallback の配送。$updatedCallback の後・失敗した本数ぶん・this は writable proxy。\n // callback 自身の throw は隔離する — 1 件の報告失敗が残りの報告と drain を道連れにしない\n for (const [ stateElement, failures ] of failuresByStateElement.entries()) {\n stateElement.createState(\"writable\", (state) => {\n for (const { error, info } of failures) {\n try {\n state[errorCallbackSymbol](error, info);\n } catch (callbackError) {\n console.error(\n `[@wcstack/state] $errorCallback threw while handling the failure of binding \"${info.bindingType}: ${info.path}\".`,\n { error: callbackError, original: error, node: info.node },\n );\n }\n }\n });\n }\n}\n","import { isLightDomMappedStateElement } from \"./bindings/lightDomComponentScope\";\nimport { State } from \"./components/State\";\nimport { IStateElement } from \"./components/types\";\nimport { config } from \"./config\";\nimport { getCustomElementRegistry } from \"./platform/customElementRegistry\";\nimport { raiseError } from \"./raiseError\";\n\nexport async function waitForStateInitialize(root: Document | Element | DocumentFragment): Promise<void> {\n const elements = root.querySelectorAll(config.tagNames.state);\n const promises: Promise<void>[] = [];\n const registry = getCustomElementRegistry(root);\n if (registry === null) {\n // null レジストリのサブツリーでは <wcs-state> が upgrade されないので\n // initializePromise が生えず、待っても永久に初期化されない。\n raiseError(`CustomElementRegistry is unavailable for <${config.tagNames.state}>.`);\n }\n await registry.whenDefined(config.tagNames.state);\n for(const element of elements) {\n // Light DOM の mapped コンポーネントの state は待たない。それはこの root の\n // バインディングが張られてからでないと初期化できず(自分を束ねるホスト binding を\n // 待つ)、ここで待つと循環する(§1.13)。Shadow DOM 形では別 rootNode にいるので\n // そもそもこの集合に現れず、plain 形は循環しないので従来どおり待つ。\n if (isLightDomMappedStateElement(element)) {\n continue;\n }\n const stateElement = element as State as IStateElement;\n promises.push(stateElement.initializePromise);\n }\n await Promise.all(promises);\n}\n","import { waitInitializeBinding } from \"./bindings/initializeBindingPromiseByNode\";\nimport { initializeBindings } from \"./bindings/initializeBindings\";\nimport { config } from \"./config\";\nimport { convertMustacheToComments } from \"./mustache/convertMustacheToComments\";\nimport { collectStructuralFragments } from \"./structural/collectStructuralFragments\";\nimport { waitForStateInitialize } from \"./waitForStateInitialize\";\n\nexport async function buildBindings(root: Document | ShadowRoot): Promise<void> {\n if (root === document) {\n // document配下のwcs-stateの初期化(connectedCallbackの完了)を待機する\n await waitForStateInitialize(document);\n // baindingを取得して、初期値をセットする\n convertMustacheToComments(document);\n collectStructuralFragments(document, document);\n initializeBindings(document.body, null);\n } else {\n const shadowRoot = root as ShadowRoot;\n if (shadowRoot.host.hasAttribute(config.bindAttributeName)) {\n // data-wcsを持つWebComponentは、WebComponentのbindingが完了するまで待機する。\n await waitInitializeBinding(shadowRoot.host);\n }\n // shadowRoot配下のwcs-stateの初期化(connectedCallbackの完了)を待機する\n await waitForStateInitialize(shadowRoot);\n // baindingを取得して、初期値をセットする\n convertMustacheToComments(shadowRoot);\n collectStructuralFragments(shadowRoot, shadowRoot);\n initializeBindings(shadowRoot, null);\n }\n}\n","/**\n * core/featureEntries.ts — 受け口の機能名 → 利用者が入れるエントリ(設計案 §3 H5・§4)。\n *\n * barrier に当たったページが要るのは「どの import を足すか」であって内部の機能名ではない。\n * 内部では別々の機能(watch / scan / stream)が 1 つのエントリ(temporal)に載るので、\n * 対応表は 1 箇所に置き、3 つの barrier(addressHooks・lifecycleHooks・ssrHooks)が共有する。\n */\nconst ENTRY_BY_FEATURE: Record<string, string> = {\n watch: \"temporal\",\n scan: \"temporal\",\n stream: \"temporal\",\n scopes: \"scopes\",\n dcc: \"scopes\",\n bindComponent: \"scopes\",\n recursion: \"recursion\",\n ssr: \"ssr\",\n devtools: \"devtools\",\n};\n\n/** 未 install の機能を宣言が要求したときの文言(readiness barrier、H5 / D13) */\nexport function featureNotInstalledMessage(feature: string, declaration: string): string {\n const entry = ENTRY_BY_FEATURE[feature] ?? feature;\n return `[wcs/feature-not-installed] ${declaration} needs the \"${feature}\" feature: ` +\n `install it with installFeatures([...]) from \"@wcstack/state/features/${entry}\" before the state is defined.`;\n}\n","/**\n * core/ssrHooks.ts — SSR(サーバー描画とハイドレーション)の受け口(設計案 H8、S5)。\n *\n * core が持つのは SSR **モード**(config の `inSsr()` と apply 側が書く `@@wcs-*` コメント)と\n * `enable-ssr` 属性の判定だけ。`<wcs-ssr>` の読み書きとハイドレーションの実装は ssr 機能\n * (src/ssr/)が install で置く。core から機能への辺はこの 1 本の受け口に畳まれている。\n *\n * 受け口(core 側の呼び出し点):\n * hydrate ルート登録(stateElementByName)で、`enable-ssr` のクライアント側\n * loadState `_initialize` の冒頭で、`<wcs-ssr>` に載った state データを読む\n * emitSnapshot サーバー側の `connectedCallback` の末尾で `<wcs-ssr>` を書き出す\n */\nimport { raiseError } from \"../raiseError\";\nimport { featureNotInstalledMessage } from \"./featureEntries\";\n\nexport interface ISsrHooks {\n /** クライアント: SSR 出力からバインディングを起こす。偽なら core が通常の構築へ倒す */\n hydrate(root: Document): Promise<boolean>;\n /** クライアント: この要素の前に置かれた `<wcs-ssr>` の state データ(無ければ null) */\n loadState(element: Element): Record<string, any> | null;\n /** サーバー: バインディング完了後に `<wcs-ssr>` を書き出す */\n emitSnapshot(element: Element): Promise<void>;\n}\n\n/** 置かれていなければ null。`enable-ssr` の無いページはここを一度も見ない */\nexport let ssrHooks: ISsrHooks | null = null;\n\n/** 機能の install が呼ぶ(冪等 — 置き換え) */\nexport function setSsrHooks(hooks: ISsrHooks | null): void {\n ssrHooks = hooks;\n}\n\n/**\n * `enable-ssr` が SSR 機能を要求した: 未 install なら名指しで throw する(readiness barrier、H5 / D13)。\n * full / auto は `bootstrapState()` が install するので起きない。\n */\nexport function requireSsrHooks(declaration: string): ISsrHooks {\n if (ssrHooks === null) {\n raiseError(featureNotInstalledMessage(\"ssr\", declaration));\n }\n return ssrHooks;\n}\n","import { buildBindings } from \"./buildBindings\";\nimport { requireSsrHooks } from \"./core/ssrHooks\";\nimport { IStateElement } from \"./components/types\";\nimport { config, inSsr } from \"./config\";\nimport { raiseError } from \"./raiseError\";\nimport { devtoolsSink } from \"./platform/devtoolsSink\";\nimport { drainPendingBinds } from \"./bindings/binder\";\n\n// v2: 1 rootNode 1 ツリー(P3-6)。名前次元は無い — 追加の state はマウント(mount= / bind-component)で載る。\nconst stateElementByNode: WeakMap<Node, IStateElement> = new WeakMap();\nconst bindingsReadyByNode: WeakMap<Node, Promise<void>> = new WeakMap();\n\n// devtools 用の列挙可能な登録簿(protocol §4.1 — 唯一の常時 ON 台帳)。\n// サイズは <wcs-state> 要素数に拘束され、unregister(disconnectedCallback)で\n// 必ず削除されるためリークしない。\nconst liveStateElements: Set<IStateElement> = new Set();\n\n// ルートの登録を待つ機能(先に接続されたボリュームの引き取り — webComponent/volume.ts)の受け口。\n// 登録は 1 ルートにつき 1 回なので大域の listener 列で足りる(hot path には載らない)\ntype StateElementRegisteredListener = (rootNode: Node, element: IStateElement) => void;\nconst registeredListeners: StateElementRegisteredListener[] = [];\n\nexport function onStateElementRegistered(listener: StateElementRegisteredListener): void {\n if (!registeredListeners.includes(listener)) {\n registeredListeners.push(listener);\n }\n}\n\nexport function getLiveStateElements(): ReadonlySet<IStateElement> {\n return liveStateElements;\n}\n\nexport function getStateElement(rootNode: Node): IStateElement | null {\n return stateElementByNode.get(rootNode) ?? null;\n}\n\n/**\n * 指定された rootNode のバインディング初期化が完了するまで待機する Promise を返す。\n */\nexport function getBindingsReady(rootNode: Node): Promise<void> {\n return bindingsReadyByNode.get(rootNode) ?? Promise.resolve();\n}\n\n/**\n * この rootNode ではバインド構築が起きない、と確定する(#257)。\n *\n * ルートの state 要素が初期化に失敗すると `setStateElement` に到達しないので、\n * 台帳はエントリが無いまま残る。上の既定(未登録 = 即時解決)は「まだ登録されて\n * いない」と「バインドを張り終えた」を区別しないため、@wcstack/server の\n * `waitForReady` は**バインディングが 1 本も無いページ**を ready と報告してしまう。\n * 失敗した rootNode には reject 済みの ready を置き、待ち手へ同じ診断を届ける。\n *\n * 呼び手は State の `_failInitializeLoudly` ただ 1 つで、そちらが「この rootNode に\n * 生きたルートが居ない」ことを確かめてから呼ぶ(2 本目の `<wcs-state>` が落ちても\n * 1 本目の ready は壊さない)。\n */\nexport function markBindingsUnavailable(rootNode: Node, error: unknown): void {\n const failed = Promise.reject(error);\n // reject と同じティックで handled を立てる(getBindingsReady を誰も呼ばない\n // ページで unhandled rejection にしないため)。await した側は従来どおり受け取る\n failed.catch(() => undefined);\n bindingsReadyByNode.set(rootNode, failed);\n}\n\nconst bindingsBuiltRoots: WeakSet<Node> = new WeakSet();\n\n/**\n * マウントされたスコープ(コンポーネントの ShadowRoot)に、**親の** state element を\n * 別名として載せる(Phase 2・impl-plan §3-0 の 2)。\n *\n * `getRootNode()` で state element を解決する全てのサイト\n * (getAbsoluteStateAddressByBinding / applyChange / applyChangeFromBindings /\n * fragmentInfoByUUID)が、この 1 エントリで無改造のまま親ツリーに到達する。\n * `setStateElement` と違い、初回登録の副作用(buildBindings の起動・\n * liveStateElements・devtools イベント)は持たない — マウントスコープの構築は\n * webComponent/mountScope.ts が自前で行う。\n */\nexport function setStateElementAlias(rootNode: Node, element: IStateElement): void {\n const existing = stateElementByNode.get(rootNode);\n if (typeof existing !== \"undefined\") {\n // 再初期化(connectedCallback で shadow を張り直すコンポーネントの再接続)は\n // 同じ親を指し直すだけなので冪等。別要素への付け替えは設定ミス\n if (existing === element) {\n return;\n }\n raiseError(`A state tree is already registered on this root.`);\n }\n stateElementByNode.set(rootNode, element);\n}\n\n/**\n * マウントされたスコープの ready を登録する(`getBindingsReady(childShadow)` の互換面)。\n * 完了で binder の `areBindingsBuilt` も真にする。\n */\nexport function setBindingsReadyForScope(rootNode: Node, ready: Promise<void>): void {\n bindingsReadyByNode.set(rootNode, ready);\n ready.then(() => markBindingsBuilt(rootNode), () => undefined);\n}\n\n/**\n * この rootNode の初期バインド構築が完了しているか。\n *\n * binder プロトコル(`bind()`)が使う。router の `<wcs-head>` はクローンを\n * `connectedCallback` の中で head へ入れるので、**state が最初の走査を終える前**に\n * bind を求めてくる。そこで同期に束ねても state 要素の初期化が済んでおらず、\n * 結果は空のままになる。完了までは binder 側で保留する。\n *\n * 「まだ登録も済んでいない」と「もう構築が終わった」を取り違えないよう、判定は\n * 完了の側で持つ。<wcs-state> の登録は connectedCallback の await より後に起きるので、\n * 「エントリの有無」で進行中かを測ると読み込み順によって逆の答えを返す。\n */\nexport function areBindingsBuilt(rootNode: Node): boolean {\n return bindingsBuiltRoots.has(rootNode);\n}\n\nfunction markBindingsBuilt(rootNode: Node): void {\n bindingsBuiltRoots.add(rootNode);\n}\n\nexport function setStateElement(rootNode: Node, element: IStateElement | null): void {\n\n const existing = stateElementByNode.get(rootNode);\n\n if (element === null) {\n // 削除の場合、登録が無ければ何もしない\n if (existing === undefined) {\n return;\n }\n stateElementByNode.delete(rootNode);\n liveStateElements.delete(existing);\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:element-unregistered\", rootNode, element: existing });\n }\n if (config.debug) {\n console.debug(`State element unregistered`);\n }\n } else {\n // 登録の場合\n if (existing === element) {\n // 同じ要素の再登録は冪等(setStateElementAlias と同じ規範)。ロード完了前の\n // remove → append(DOM の移動・行プールの張り直し・shadow の組み直し)は\n // `_initialize` を 2 本同時に走らせるので、後から登録に来たほうが**自分自身**を\n // 「2 本目の <wcs-state>」と誤診する。DOM の移動は正常な操作であり、拒否すると\n // 健全なページの connectedCallbackPromise が reject される(#257)。\n // 切断時に登録を解除する案では直らない — 実測で、切断の時点ではまだ何も\n // 登録されていない(登録は進行中の `_initialize` の続きで起きる)。\n return;\n }\n if (existing === undefined) {\n // 初めてルートノードに登録する場合\n // enable-ssr 属性があり、サーバーサイドでない場合はハイドレーション\n const enableSsr = !inSsr() && (element as unknown as Element).hasAttribute?.('enable-ssr');\n // instanceof ではなく constructor.name で判定するのは意図的。SSR では\n // @wcstack/server の installGlobals が happy-dom の一部だけを globalThis に載せるが、\n // そのリスト(GLOBALS_KEYS)に `Document` は入っていない。Node にも `Document` は\n // 無いので `rootNode instanceof Document` は ReferenceError になる。\n // `ShadowRoot` はリストに含まれるため他所では instanceof を使っている\n // (docs/architecture-hardening/15-state-component-mechanism-consistency.md §3.3)。\n // reject を配管しないと、バインディング初期化中の例外は unhandled rejection として\n // 漏れるだけで ready が永久に未解決のまま残り、await getBindingsReady() の先が\n // 無言でハングする(docs/state-bind-component-nested-for-design.md §8.2)。\n if (rootNode.constructor.name === 'HTMLDocument' || rootNode.constructor.name === 'Document') {\n const ready = new Promise<void>((resolve, reject) => {\n queueMicrotask(async () => {\n try {\n if (enableSsr) {\n // ハイドレーションは SSR 機能(ssr/hydrateBindings.ts)。未 install なら名指しで落とす(H5 / D13)\n const success = await requireSsrHooks(`the \"enable-ssr\" attribute`).hydrate(rootNode as Document);\n if (!success) {\n await buildBindings(rootNode as Document);\n }\n } else {\n await buildBindings(rootNode as Document);\n }\n markBindingsBuilt(rootNode);\n // binder が居ない時点で差し出されたサブツリーを引き取る。ここが\n // 「state が確実に居る」最初の瞬間で、router の auto バンドルが\n // state のそれより先に走る順序を吸収できる唯一の場所である。\n drainPendingBinds();\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n });\n bindingsReadyByNode.set(rootNode, ready);\n } else if (rootNode.constructor.name === 'ShadowRoot') {\n const ready = new Promise<void>((resolve, reject) => {\n queueMicrotask(async () => {\n try {\n await buildBindings(rootNode as ShadowRoot);\n markBindingsBuilt(rootNode);\n // binder が居ない時点で差し出されたサブツリーを引き取る。ここが\n // 「state が確実に居る」最初の瞬間で、router の auto バンドルが\n // state のそれより先に走る順序を吸収できる唯一の場所である。\n drainPendingBinds();\n resolve();\n } catch (error) {\n reject(error);\n }\n });\n });\n bindingsReadyByNode.set(rootNode, ready);\n }\n }\n if (existing !== undefined) {\n // v2 は 1 rootNode 1 ツリー。2 つ目の <wcs-state> は設定エラー — 追加の状態は\n // マウント(mount= / ホスト配線の bind-component)でツリーに載せる\n // 文言は実測のゾンビの姿に合わせる(#257 第 3 ラウンド): 2 本目は state を\n // 組み上げたまま**登録されない**。データもトークンも $on の購読も生きているのに\n // 誰もバインドしておらず、_initialized が false なので切断時の後始末も走らない\n raiseError(\n `A state tree is already registered on this root — one <wcs-state> per root in v2. ` +\n `This second element stays unregistered: it keeps the state it loaded and its ` +\n `declarations stay live, but nothing binds to it and disconnecting it runs no ` +\n `cleanup — remove it. Mount additional states onto the tree instead: ` +\n `<wcs-state mount=\"...\">.`,\n );\n }\n stateElementByNode.set(rootNode, element);\n liveStateElements.add(element);\n // ルートの登録を待っていた機能へ(先に接続されて保留中のボリュームの引き取り — ロード順に依存しない、V5)\n for (let i = 0; i < registeredListeners.length; i++) {\n registeredListeners[i](rootNode, element);\n }\n if (devtoolsSink !== null) {\n devtoolsSink({ type: \"state:element-registered\", rootNode, element });\n }\n if (config.debug) {\n console.debug(`State element registered`, element);\n }\n }\n}\n","import { raiseError } from \"../raiseError\";\nimport { getStateElement } from \"../stateElementByName\";\nimport { IFragmentInfo } from \"./types\";\n\nconst fragmentInfoByUUID = new Map<string, IFragmentInfo>();\n\nexport function setFragmentInfoByUUID(uuid: string, rootNode: Node, fragmentInfo: IFragmentInfo | null): void {\n if (fragmentInfo === null) {\n fragmentInfoByUUID.delete(uuid);\n } else {\n fragmentInfoByUUID.set(uuid, fragmentInfo);\n // v2: ルートに 1 ツリーなので参照は 1 回でよい(名前ごとの再解決は名前次元と一緒に消えた)\n const stateElement = getStateElement(rootNode);\n if (stateElement === null) {\n raiseError(`No state tree found on this root for fragment info.`);\n }\n const bindingPartial = fragmentInfo.parseBindTextResult;\n stateElement.setPathInfo(bindingPartial.statePathName, bindingPartial.bindingType);\n for(const nodeInfo of fragmentInfo.nodeInfos) {\n for(const nodeBindingPartial of nodeInfo.parseBindTextResults) {\n stateElement.setPathInfo(nodeBindingPartial.statePathName, nodeBindingPartial.bindingType);\n }\n }\n }\n}\n\nexport function getFragmentInfoByUUID(uuid: string): IFragmentInfo | null {\n return fragmentInfoByUUID.get(uuid) || null;\n}\n\nexport function getAllFragmentUUIDs(): string[] {\n return Array.from(fragmentInfoByUUID.keys());\n}","import { config } from \"../config\";\nimport { raiseError } from \"../raiseError\";\nimport { parseBindTextsForElement } from \"../bindTextParser/parseBindTextsForElement\";\nimport { parseCommentNode } from \"./parseCommentNode\";\nimport { parseBindTextForEmbeddedNode } from \"../bindTextParser/parseBindTextForEmbeddedNode\";\nimport { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { getFragmentInfoByUUID } from \"../structural/fragmentInfoByUUID\";\n\nexport function getParseBindTextResults(node: Node): ParseBindTextResult[] {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n const bindText = element.getAttribute(config.bindAttributeName) || '';\n return parseBindTextsForElement(bindText);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n const bindTextOrUUID = parseCommentNode(node);\n if (bindTextOrUUID === null) {\n raiseError(`Comment node binding text not found.`);\n }\n const fragmentInfo = getFragmentInfoByUUID(bindTextOrUUID);\n let parseBindingTextResult = fragmentInfo?.parseBindTextResult ?? null;\n let uuid: string | null = null;\n if (parseBindingTextResult === null) {\n // It is not a structural fragment UUID, so treat it as bindText\n parseBindingTextResult = parseBindTextForEmbeddedNode(bindTextOrUUID);\n uuid = null;\n } else {\n uuid = bindTextOrUUID;\n }\n return [{\n ...parseBindingTextResult,\n uuid: uuid,\n }]\n }\n return [];\n}","import { IParsedFilter } from \"../types\";\n\n/**\n * `if` / `else` の反転として、エンジン自身がパース結果へ足すフィルタ(解析の段の形 —\n * 名前と引数だけ。要件 D16)。実関数は束縛計画の段で登録簿から引かれ、`not` は\n * `features/formats` の有無に関わらず core が答える(`core/filterRegistry.ts`)。\n */\nlet _notFilterInfo: IParsedFilter | undefined = undefined;\n\nexport function createNotFilter(): IParsedFilter {\n return _notFilterInfo ??= { filterName: \"not\", args: [] };\n}\n","import { config } from \"../config.js\";\nimport { DELIMITER, WILDCARD } from \"../define.js\";\n\nconst COMMENT_REGEX = /^(\\s*@@\\s*(?:.*?)\\s*:\\s*)(.+?)(\\s*)$/;\n\nfunction expandShorthandInStatePart(statePart: string, forPath: string): string {\n const prefix = forPath + DELIMITER + WILDCARD;\n const pipeIndex = statePart.indexOf('|');\n let pathPart: string;\n let suffix: string;\n if (pipeIndex !== -1) {\n pathPart = statePart.slice(0, pipeIndex).trim();\n suffix = statePart.slice(pipeIndex);\n } else {\n pathPart = statePart.trim();\n suffix = '';\n }\n if (pathPart === '.') {\n pathPart = prefix;\n } else if (pathPart.startsWith('.')) {\n pathPart = prefix + DELIMITER + pathPart.slice(1);\n } else {\n return statePart;\n }\n if (suffix.length > 0) {\n return pathPart + suffix;\n }\n return pathPart;\n}\n\nfunction expandCommentData(data: string, forPath: string): string {\n const match = COMMENT_REGEX.exec(data);\n if (match === null) {\n return data;\n }\n const commentPrefix = match[1];\n const bindText = match[2];\n const commentSuffix = match[3];\n const expanded = expandShorthandInStatePart(bindText, forPath);\n return commentPrefix + expanded + commentSuffix;\n}\n\nfunction expandBindAttribute(attrValue: string, forPath: string): string {\n const parts = attrValue.split(';');\n let changed = false;\n const result = parts.map(part => {\n const trimmed = part.trim();\n if (trimmed.length === 0) return part;\n const colonIndex = trimmed.indexOf(':');\n if (colonIndex === -1) return part;\n const propPart = trimmed.slice(0, colonIndex).trim();\n const statePart = trimmed.slice(colonIndex + 1).trim();\n const expanded = expandShorthandInStatePart(statePart, forPath);\n if (expanded !== statePart) {\n changed = true;\n return `${propPart}: ${expanded}`;\n }\n return part;\n });\n if (!changed) return attrValue;\n return result.join(';');\n}\n\nexport function expandShorthandInBindAttribute(attrValue: string, forPath: string): string {\n return expandBindAttribute(attrValue, forPath);\n}\n\nexport function expandShorthandPaths(root: DocumentFragment, forPath: string): void {\n const bindAttr = config.bindAttributeName;\n const walker = document.createTreeWalker(\n root,\n NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT,\n );\n\n while (walker.nextNode()) {\n const node = walker.currentNode;\n if (node.nodeType === Node.COMMENT_NODE) {\n const comment = node as Comment;\n comment.data = expandCommentData(comment.data, forPath);\n continue;\n }\n const element = node as Element;\n if (element instanceof HTMLTemplateElement) {\n continue;\n }\n const attr = element.getAttribute(bindAttr);\n if (attr !== null) {\n const expanded = expandBindAttribute(attr, forPath);\n if (expanded !== attr) {\n element.setAttribute(bindAttr, expanded);\n }\n }\n }\n}\n","\nexport function getNodePath(node: Node): number[] {\n let currentNode: Node | null = node;\n const path: number[] = [];\n while(currentNode.parentNode !== null) {\n const nodes: Node[] = Array.from(currentNode.parentNode.childNodes);\n const index = nodes.indexOf(currentNode);\n path.unshift(index);\n currentNode = currentNode.parentNode;\n }\n return path;\n}\n","import { getParseBindTextResults } from \"../bindings/getParseBindTextResults\";\nimport { getSubscriberNodes } from \"../bindings/getSubscriberNodes\";\nimport { getNodePath } from \"./getNodePath\";\nimport { IFragmentNodeInfo } from \"./types\";\n\nexport function getFragmentNodeInfos(fragment: DocumentFragment): IFragmentNodeInfo[] {\n const fragmnentNodeInfos: IFragmentNodeInfo[] = [];\n const subscriberNodes = getSubscriberNodes(fragment);\n for(const subscriberNode of subscriberNodes) {\n const parseBindingTextResults = getParseBindTextResults(subscriberNode);\n let node = subscriberNode;\n // テンプレート登録時の事前正規化: text 専用の wcs-text コメントは、この時点で\n // 空 Text に置き換えておく。行 clone は最初から Text を持ち、getBindingInfos が\n // その Text を replaceNode に使うため、行ごとの createTextNode と start() 時の\n // replaceChild(コメント→Text 差し替え)が丸ごと不要になる。\n // 置換は同じ位置なので nodePath は不変。wcs-for/if 等の構造コメントは\n // アンカーとしてコメントのまま維持する(bindingType で判別)。\n // 非フラグメント経路(実 DOM 上のコメント)は従来どおり実行時に差し替える。\n if (\n subscriberNode.nodeType === Node.COMMENT_NODE\n && parseBindingTextResults.length === 1\n && parseBindingTextResults[0].bindingType === \"text\"\n && subscriberNode.parentNode !== null\n ) {\n const textNode = document.createTextNode(\"\");\n subscriberNode.parentNode.replaceChild(textNode, subscriberNode);\n node = textNode;\n }\n fragmnentNodeInfos.push({\n nodePath: getNodePath(node),\n parseBindTextResults: parseBindingTextResults,\n });\n }\n return fragmnentNodeInfos;\n}","\nexport function optimizeFragment(fragment: DocumentFragment): void {\n const childNodes = Array.from(fragment.childNodes);\n for(const childNode of childNodes) {\n if (childNode.nodeType === Node.TEXT_NODE) {\n const textContent = childNode.textContent || '';\n if (textContent.trim() === '') {\n // Remove empty text nodes\n fragment.removeChild(childNode);\n }\n }\n }\n}\n","import { getParseBindTextResults } from \"../bindings/getParseBindTextResults\";\nimport { findNestedLightDomComponents } from \"../bindings/lightDomComponentScope\";\nimport { parseBindTextsForElement } from \"../bindTextParser/parseBindTextsForElement\";\nimport { ParseBindTextResult } from \"../bindTextParser/types\";\nimport { config } from \"../config\";\nimport { getUUID } from \"../getUUID\";\nimport { raiseError } from \"../raiseError\";\nimport { BindingType } from \"../types\";\nimport { createNotFilter } from \"./createNotFilter\";\nimport { expandShorthandInBindAttribute, expandShorthandPaths } from \"./expandShorthandPaths\";\nimport { setFragmentInfoByUUID } from \"./fragmentInfoByUUID\";\nimport { getFragmentNodeInfos } from \"./getFragmentNodeInfos\";\nimport { getNodePath } from \"./getNodePath\";\nimport { optimizeFragment } from \"./optimizeFragment\";\nimport { IFragmentInfo } from \"./types\";\n\nconst keywordByBindingType: Map<BindingType, string> = new Map<BindingType, string>([\n [\"for\", config.commentForPrefix],\n [\"if\", config.commentIfPrefix],\n [\"elseif\", config.commentElseIfPrefix],\n [\"else\", config.commentElsePrefix],\n]);\n\nconst notFilter = /*#__PURE__*/ createNotFilter();\n\nfunction cloneNotParseBindTextResult(\n bindingType: BindingType,\n parseBindTextResult: ParseBindTextResult\n): ParseBindTextResult {\n const filters = parseBindTextResult.outFilters;\n return {\n ...parseBindTextResult,\n outFilters: [...filters, notFilter],\n bindingType: bindingType,\n };\n}\n\n/**\n * パース結果の変換フック(Phase 2 のマウント — impl-plan §3-0 の 1)。\n *\n * マウントされたスコープでは、フラグメントのパース結果(テンプレート自身の for/if と\n * nodeInfos の中身)を**登録時にここで**親ツリーの絶対パスへ書き換える。行の実体化\n * (collectNodesAndBindingInfosByFragment)は変換済みの nodeInfos をそのまま使うので、\n * 行生成のホットパスに変換コストは載らない。\n *\n * shorthand 展開(`.name` → `<forPath>.*.name`)は**変換前の**内側パスで行う —\n * 変換後のパスを forPath に使うと、展開結果が絶対パスになり二重変換の判別が\n * つかなくなるため。したがって入れ子のフラグメントも常に「スコープ相対のパース結果 →\n * 変換」の順を保ち、変換は各レベルで一度だけ掛かる。\n *\n * `uuid` を持つ nodeInfo エントリ(入れ子フラグメントの参照 — 再帰で変換済み)には\n * 掛けない(collectNodesAndBindingInfos.applyTransform と同じ規則)。\n */\nexport type FragmentParseTransform = (parsed: ParseBindTextResult, forPath?: string) => ParseBindTextResult;\n\nfunction transformNodeInfos(\n nodeInfos: IFragmentInfo[\"nodeInfos\"],\n transform: FragmentParseTransform,\n forPath: string | undefined,\n): void {\n for (const nodeInfo of nodeInfos) {\n for (let i = 0; i < nodeInfo.parseBindTextResults.length; i++) {\n const parsed = nodeInfo.parseBindTextResults[i];\n if (parsed.uuid != null) continue;\n // forPath はこのフラグメントの中身を囲む for のスコープ相対パス(`$n` のシフト量の根拠)\n nodeInfo.parseBindTextResults[i] = transform(parsed, forPath);\n }\n }\n}\n\nfunction _getFragmentInfo(\n rootNode: Node,\n fragment: DocumentFragment,\n parseBindingTextResult: ParseBindTextResult,\n forPath?: string,\n transform?: FragmentParseTransform,\n // else 節はテンプレート自身の結果を if の**変換済み**結果から clone するため、\n // そこだけ再変換しない(nodeInfos は通常どおり変換する)\n transformOwnResult: boolean = true,\n): IFragmentInfo {\n optimizeFragment(fragment);\n if (typeof forPath === \"string\") {\n expandShorthandPaths(fragment, forPath);\n }\n collectStructuralFragments(rootNode, fragment, forPath, transform);\n // after replacing and collect node infos on child fragment\n const fragmentInfo = {\n fragment: fragment,\n // own result(テンプレート自身の for/if/elseif)にも forPath を渡す — `$n` の\n // シフト量は囲む for の翻訳が根拠(translateParsedForMount)で、渡し漏れると\n // record.delta に落ち、翻訳がワイルドカードを増やす部分マウント内の for の\n // `if: $n` / `elseif: $n` が誤った添字に解決される(transformNodeInfos と対称)。\n // if/elseif の forPath(呼び手の childForPath)は外側 forPath そのもの。\n // for テンプレートの own path は `$n` になり得ず、非 `$n` パスの変換は forPath を\n // 読まないため、for に自パスが渡っても無害\n parseBindTextResult: typeof transform === \"undefined\" || !transformOwnResult\n ? parseBindingTextResult\n : transform(parseBindingTextResult, forPath),\n nodeInfos: getFragmentNodeInfos(fragment),\n }\n if (typeof transform !== \"undefined\") {\n transformNodeInfos(fragmentInfo.nodeInfos, transform, forPath);\n }\n return fragmentInfo;\n}\n\n\nexport function collectStructuralFragments(rootNode: Node, walkRoot: Document | Element | DocumentFragment, forPath?: string, transform?: FragmentParseTransform): void {\n const elseKeyword = config.commentElsePrefix;\n // Light DOM の mapped コンポーネントの内側は、その子スコープが自分で処理する(§1.13)。\n // fragment info は rootNode + state 名で登録されるため、ホストのパスでここを拾うと\n // コンポーネント側の state がまだ名前登録を済ませておらず解決に失敗する。\n // コンポーネント要素自身は template ではないので、REJECT でサブツリーごと落として問題ない。\n const nestedComponents = findNestedLightDomComponents(walkRoot);\n const walker = document.createTreeWalker(\n walkRoot,\n NodeFilter.SHOW_ELEMENT,\n {\n acceptNode(node: Node) {\n const element = node as Element;\n if (nestedComponents.length > 0 && nestedComponents.indexOf(element) !== -1) {\n return NodeFilter.FILTER_REJECT;\n }\n if (element.tagName.toLowerCase() === 'template') {\n const bindText = element.getAttribute(config.bindAttributeName) || '';\n if (bindText.length > 0) {\n return NodeFilter.FILTER_ACCEPT;\n }\n }\n return NodeFilter.FILTER_SKIP;\n }\n }\n );\n let lastIfFragmentInfo: IFragmentInfo | null = null; // for elseif chaining\n const elseFragmentInfos: IFragmentInfo[] = []; // for elseif chaining\n const templates: HTMLTemplateElement[] = [];\n while (walker.nextNode()) {\n const template = walker.currentNode as HTMLTemplateElement;\n templates.push(template);\n }\n\n for(const template of templates) {\n let bindText = template.getAttribute(config.bindAttributeName) || '';\n if (typeof forPath === \"string\") {\n bindText = expandShorthandInBindAttribute(bindText, forPath);\n }\n const parseBindTextResults = parseBindTextsForElement(bindText);\n let parseBindTextResult = parseBindTextResults[0];\n const keyword = keywordByBindingType.get(parseBindTextResult.bindingType);\n if (typeof keyword === 'undefined') {\n continue;\n }\n\n const bindingType = parseBindTextResult.bindingType;\n const fragment = template.content;\n const uuid = getUUID();\n let fragmentInfo: IFragmentInfo | null = null;\n\n // Determine childForPath for shorthand expansion\n const childForPath = bindingType === \"for\"\n ? parseBindTextResult.statePathName\n : forPath;\n\n if (bindingType === \"else\") {\n // check last 'if' or 'elseif' fragment info\n if (lastIfFragmentInfo === null) {\n raiseError(`'else' binding found without preceding 'if' or 'elseif' binding.`);\n }\n // else condition(if の変換済み結果の clone なので自身の再変換はしない)\n parseBindTextResult = cloneNotParseBindTextResult(\"else\", lastIfFragmentInfo.parseBindTextResult);\n fragmentInfo = _getFragmentInfo(rootNode, fragment, parseBindTextResult, childForPath, transform, false);\n setFragmentInfoByUUID(uuid, rootNode, fragmentInfo);\n\n const lastElseFragmentInfo = elseFragmentInfos.at(-1);\n const placeHolder = document.createComment(`@@${keyword}:${uuid}`);\n if (typeof lastElseFragmentInfo !== \"undefined\") {\n template.remove();\n lastElseFragmentInfo.fragment.appendChild(placeHolder);\n lastElseFragmentInfo.nodeInfos.push({\n nodePath: getNodePath(placeHolder),\n parseBindTextResults: getParseBindTextResults(placeHolder),\n });\n } else {\n template.replaceWith(placeHolder);\n }\n } else if (bindingType === \"elseif\") {\n // check last 'if' or 'elseif' fragment info\n if (lastIfFragmentInfo === null) {\n raiseError(`'elseif' binding found without preceding 'if' or 'elseif' binding.`);\n }\n\n fragmentInfo = _getFragmentInfo(rootNode, fragment, parseBindTextResult, childForPath, transform);\n setFragmentInfoByUUID(uuid, rootNode, fragmentInfo);\n const placeHolder = document.createComment(`@@${keyword}:${uuid}`);\n\n // create else fragment\n const elseUUID = getUUID();\n const elseFragmentInfo: IFragmentInfo = {\n fragment: document.createDocumentFragment(),\n parseBindTextResult: cloneNotParseBindTextResult(\"else\", lastIfFragmentInfo.parseBindTextResult),\n nodeInfos: [],\n };\n elseFragmentInfo.fragment.appendChild(placeHolder);\n elseFragmentInfo.nodeInfos.push({\n nodePath: getNodePath(placeHolder),\n parseBindTextResults: getParseBindTextResults(placeHolder),\n });\n setFragmentInfoByUUID(elseUUID, rootNode, elseFragmentInfo);\n const lastElseFragmentInfo = elseFragmentInfos.at(-1);\n elseFragmentInfos.push(elseFragmentInfo);\n const elsePlaceHolder = document.createComment(`@@${elseKeyword}:${elseUUID}`);\n\n if (typeof lastElseFragmentInfo !== \"undefined\") {\n template.remove();\n lastElseFragmentInfo.fragment.appendChild(elsePlaceHolder);\n lastElseFragmentInfo.nodeInfos.push({\n nodePath: getNodePath(elsePlaceHolder),\n parseBindTextResults: getParseBindTextResults(elsePlaceHolder),\n });\n } else {\n template.replaceWith(elsePlaceHolder);\n }\n\n } else {\n fragmentInfo = _getFragmentInfo(rootNode, fragment, parseBindTextResult, childForPath, transform);\n setFragmentInfoByUUID(uuid, rootNode, fragmentInfo);\n const placeHolder = document.createComment(`@@${keyword}:${uuid}`);\n template.replaceWith(placeHolder);\n }\n\n // Update lastIfFragmentInfo for if/elseif/else chaining\n if (bindingType === \"if\") {\n elseFragmentInfos.length = 0; // start new if chain\n lastIfFragmentInfo = fragmentInfo;\n } else if (bindingType === \"elseif\") {\n lastIfFragmentInfo = fragmentInfo;\n } else if (bindingType === \"else\") {\n lastIfFragmentInfo = null;\n elseFragmentInfos.length = 0; // end if chain\n }\n }\n}\n","import { BINDER_KEY, IWcsBinder, flushPendingBinds } from \"../protocol/binder\";\nimport { config } from \"../config\";\nimport { convertMustacheToComments } from \"../mustache/convertMustacheToComments\";\nimport { collectStructuralFragments } from \"../structural/collectStructuralFragments\";\nimport { hasInterestedSession } from \"./BindingSession\";\nimport { areBindingsBuilt } from \"../stateElementByName\";\nimport { initializeBindings } from \"./initializeBindings\";\n\n/**\n * binder プロトコルの提供側(docs/binder-protocol-design.md)。\n *\n * `buildBindings` は起動時に `document.body` を 1 回走査するだけなので、そのとき\n * document に居なかったノードのバインドは存在しない。router が後から差し込む\n * ルート内容や `<wcs-head>` のクローンがこれに当たり、書いたバインドが黙って\n * 何もしない状態になっていた。`bind()` はその取りこぼしを 1 サブツリー分だけ\n * 埋める。\n *\n * **走査を勝手に広げない。** MutationObserver が見た全追加ノードを走査する形に\n * すると、バインドを 1 個も持たない挿入(大多数)にコストが乗り、さらに\n * `innerHTML` で入れた外部由来の DOM が `data-wcs` を発火させることになる。\n * ここで束ねるのは**明示的に渡されたものだけ**である。\n */\nconst BIND_ATTRIBUTE_SELECTOR = (): string => `[${config.bindAttributeName}]`;\n\n/**\n * このサブツリーは既にバインド済みか。\n *\n * ルート内容は「起動時に active だったので全部バインド済み」か「一度も走査されて\n * いないので全部未バインド」のどちらかで、途中の状態を取らない。したがって\n * **宣言を持つ最初のノード 1 個**を見れば足りる。全ノードを走査して判定するのは\n * 同じ結論により高いコストを払うだけになる。\n */\nfunction alreadyBound(subtree: Node): boolean {\n if (hasInterestedSession(subtree)) {\n return true;\n }\n if (!isElement(subtree)) {\n return false;\n }\n if (subtree.hasAttribute(config.bindAttributeName)) {\n // 属性を持つのに台帳に居ない = 未バインド\n return false;\n }\n const first = subtree.querySelector(BIND_ATTRIBUTE_SELECTOR());\n return first !== null && hasInterestedSession(first);\n}\n\nfunction isElement(node: Node): node is Element {\n return node.nodeType === 1;\n}\n\nfunction bindNow(subtree: Element): void {\n if (alreadyBound(subtree)) {\n return;\n }\n convertMustacheToComments(subtree);\n collectStructuralFragments(subtree.getRootNode(), subtree);\n // `getSubscriberNodes` の TreeWalker は**ルート自身を返さない**。`buildBindings` は\n // `document.body` を渡すので今まで問題にならなかったが、ここには宣言をルートに\n // 持つノードが来る(`<wcs-head>` が head へ入れる `<title data-wcs=\"…\">`)。\n // そのときだけ親から走査して、ルートを走査範囲に含める。兄弟の重複登録は\n // `registeredNodeSet` が弾くので、余計なバインドは生まれない。\n // 親は Element とは限らない(ShadowRoot 直下なら DocumentFragment、head 直下なら\n // Element)。`parentElement` だと前者で null になり、ルートを含められない。\n const declaresOnRoot = subtree.hasAttribute(config.bindAttributeName);\n const parent = subtree.parentNode;\n const canWalkFromParent = parent !== null\n && (parent.nodeType === 1 || parent.nodeType === 9 || parent.nodeType === 11);\n const walkRoot = declaresOnRoot && canWalkFromParent\n ? (parent as Element | Document | DocumentFragment)\n : subtree;\n initializeBindings(walkRoot, null);\n}\n\n/**\n * 初期バインド構築より前に差し出されたサブツリー。\n *\n * `<wcs-head>` は `connectedCallback` の中でクローンを head へ入れるので、\n * state / router のどちらを先に読み込んでも「まだ構築が終わっていない」時点で\n * bind を求めてくる。そこで同期に束ねても `<wcs-state>` の登録が済んでおらず、\n * バインドは state を見つけられない。**構築の完了を唯一の合図にする。**\n */\nconst beforeFirstBuild: Element[] = [];\n\nfunction bind(subtree: Node): void {\n if (!isElement(subtree) || alreadyBound(subtree)) {\n return;\n }\n if (!areBindingsBuilt(subtree.getRootNode())) {\n beforeFirstBuild.push(subtree);\n return;\n }\n bindNow(subtree);\n}\n\n/**\n * 初期バインド構築の完了時に呼ぶ(stateElementByName.ts)。binder が居ない時点で\n * 差し出された分(プロトコルの保留キュー)と、居たが早すぎた分をまとめて束ねる。\n */\nexport function drainPendingBinds(): void {\n const pending = beforeFirstBuild.splice(0, beforeFirstBuild.length);\n for (const subtree of pending) {\n bindNow(subtree);\n }\n flushPendingBinds();\n}\n\nconst binder: IWcsBinder = {\n protocol: \"wcs-binder\",\n version: 1,\n bind,\n};\n\n/**\n * グローバル symbol へ自分を載せる。`bootstrapState` から呼ぶ。\n *\n * 既に別のコピーが載っているなら譲る。1 ページに 2 つの state バンドルが載る構成\n * (CDN の取り違え)で、後から読まれた側が先客を追い出すと、先客がバインドした\n * ノードの台帳と食い違う。\n */\nexport function registerBinder(): void {\n const globals = globalThis as Record<symbol, unknown>;\n if (globals[BINDER_KEY] === undefined) {\n globals[BINDER_KEY] = binder;\n }\n // ここでは引き取らない。`<wcs-state>` の登録は connectedCallback の await より\n // 後なので、この時点ではまだ state が居ない。保留分は初期バインド構築の完了時に\n // 流す(stateElementByName.ts)。そこが「state が確実に居る」最初の瞬間である。\n}\n\n/** テスト用: 登録を外す */\nexport function _unregisterBinder(): void {\n const globals = globalThis as Record<symbol, unknown>;\n if (globals[BINDER_KEY] === binder) {\n delete globals[BINDER_KEY];\n }\n}\n"],"names":["BINDER_KEY","Symbol","for","PENDING_KEY","TAKEN_KEY","flushPendingBinds","binder","candidate","globalThis","protocol","version","bind","getBinder","queue","globals","undefined","pendingQueue","length","pending","splice","taken","WeakSet","takenSet","subtree","add","MUSTACHE_REGEX","SKIP_TAGS","Set","convertMustacheToComments","root","config","enableMustache","walker","document","createTreeWalker","NodeFilter","SHOW_TEXT","textNodes","nextNode","push","currentNode","textNode","parentElement","has","tagName","replaceTextNode","convertTextNodes","templates","Array","from","querySelectorAll","template","namespaceURI","SVG_NAMESPACE","newTemplate","createElement","childNodes","i","childNode","content","appendChild","attr","attributes","setAttribute","name","value","replaceWith","text","data","lastIndex","test","fragment","createDocumentFragment","match","exec","index","createTextNode","slice","bindText","createComment","parentNode","replaceChild","STRUCTURAL_BINDING_TYPE_SET","finalizeArg","firstQuoteStart","lastQuoteEnd","startLimit","start","endLimit","end","NUMBER_LITERAL","toLiteral","quoted","Number","parseFilterArgsWithLiterals","argsText","args","literals","current","inQuote","hasQuote","flush","arg","char","raiseError","LINT_HINT","last","parseFilters","filterTextList","_filterIOType","map","filterText","openParenIndex","indexOf","closeParenIndex","lastIndexOf","filterName","substring","trim","join","trimFn","s","isQuote","c","indexOfOutsideQuotes","quote","splitOutsideQuotes","separator","parts","cacheFilterInfos","Map","parsePropPart","propPart","pos","FILTER_SEPARATOR","propText","filterTexts","filtersText","filters","get","set","modifierParts","split","MODIFIER_SEPARATOR","propName","propModifiersText","propSegments","DELIMITER","propModifiers","inFilters","parseStatePart","statePart","stateAndPath","statePathName","statePathInfo","getPathInfo","outFilters","KEYWORDS_WITHOUT_MODIFIERS","ELSE_KEYWORD","SPREAD_PROP","parseBindTextsForElement","bindTexts","BINDING_SEPARATOR","splitBindTexts","filter","results","separatorIndex","PROP_VALUE_SEPARATOR","keyword","pathInfo","bindingType","stateResult","propResult","EVENT_TOKEN_NAMESPACE","startsWith","EVENT_PROP_PREFIX","some","r","bindTextByNode","WeakMap","bindingTypeKeywordSet","commentTextPrefix","commentForPrefix","commentIfPrefix","commentElseIfPrefix","commentElsePrefix","EMBEDDED_REGEX","RegExp","parseCommentNode","node","savedText","nodeType","Node","COMMENT_NODE","parseBindTextForEmbeddedNode","bindingPromiseByNode","resolvedNodes","id","async","waitInitializeBinding","bindingPromise","resolveFn","promise","Promise","resolve","getInitializeBindingPromiseByNode","resolveInitializedBinding","existing","cache","getCustomElement","cached","ELEMENT_NODE","element","toLowerCase","includes","hasAttribute","is","getAttribute","toAdapter","registry","whenDefined","getCustomElementRegistry","owner","customElementRegistry","scoped","customElements","owned","upgradeCustomElement","upgrade","readBindableDeclaration","target","addEventListener","removeEventListener","declaration","constructor","wcBindable","isInteger","knownProperties","readNamedList","properties","isValidPropertyDescriptor","declaredInputs","inputs","isValidInputDescriptor","declaredCommands","commands","isValidCommandDescriptor","liveDeclaration","descriptor","event","getter","attribute","isValidEntry","isArray","entries","entry","makeExpandedEntry","base","expandedPath","dedupKey","expandSpread","options","allowDeferred","expanded","spreadOrigin","result","bindable","targetBase","seen","keys","lastIndexByKey","key","final","debug","overrider","tagText","console","resolveNodePath","path","remaining","firstChild","nextSibling","planFilters","filterIOType","planned","filterFn","resolveFilterFn","bindingsByNode","getBindingsByNode","isLightDomMappedStateElement","stateElement","Element","bindAttributeName","findNestedLightDomComponents","components","stateElements","tagNames","state","component","isInsideAnyComponent","contains","getSubscriberNodes","subscriberNodes","nestedComponents","SHOW_ELEMENT","SHOW_COMMENT","acceptNode","FILTER_ACCEPT","FILTER_SKIP","registeredNodeSet","processParseResultsForNode","parseResults","transform","bindings","deferred","parseBindingTextResults","bindingInfos","parseBindingTextResult","replaceNode","TEXT_NODE","getBindingInfos","parsed","uuid","applyTransform","setBindingsByNode","collectNodesAndBindingInfos","allBindings","deferredSpreads","getParseBindTextResults","markNodeRegistered","processDeferredNode","delete","unregisterNode","loopContextByNode","mountedScopeHost","setMountedScopeHost","resolver","getLoopContextByNode","paramNode","loopContext","next","ShadowRoot","setLoopContextByNode","lastListValueByAbsoluteStateAddress","getLastListValueByAbsoluteStateAddress","address","setLastListValueByAbsoluteStateAddress","hasLastListValueByAbsoluteStateAddress","stateListBaselineByAbsoluteStateAddress","pendingBaselines","batchDepth","getStateListBaseline","setStateListBaseline","beginStateListBaselineBatch","endStateListBaselineBatch","hasStateListBaseline","setLoopContextSymbol","getByAddressSymbol","hasByAddressSymbol","setByAddressSymbol","connectedCallbackSymbol","disconnectedCallbackSymbol","updatedCallbackSymbol","errorCallbackSymbol","_cache","_cacheNullListIndex","AbsoluteStateAddress","absolutePathInfo","listIndex","this","createAbsoluteStateAddress","cacheByAbsolutePathInfo","treePathsByElement","getTreePath","table","treePath","Object","freeze","TreePath","liftAddress","absoluteAddressOf","rootNodeByFragment","setRootNodeByFragment","rootNode","getRootNodeByFragment","cacheCalcWildcardLen","calcWildcardLen","targetPathInfo","path1","path2","wildcardCount","wildcardPathSet","len","intersection","size","listIndexAtWildcard","wildcardPos","at","getScopedIndexes","indexes","listIndexByBindingInfoByLoopContext","getListIndexByBindingInfo","bindingInfo","listIndexByBindingInfo","wildcardLen","absoluteStateAddressByBinding","resolveBindingRootNode","binding","knownRootNode","getRootNode","isConnected","nodeName","getAbsoluteStateAddressByBinding","absoluteStateAddress","getStateElement","clearAbsoluteStateAddressByBinding","bindingsByAbsoluteStateAddress","addBindingByAbsoluteStateAddress","devtoolsSink","type","absoluteAddress","removeBindingByAbsoluteStateAddress","patternLedger","peekBindingsForAddress","StateAddress","_parentAddress","parentAddress","parentPathInfo","parentListIndex","segments","WILDCARD","createStateAddress","cacheByPathInfo","stateAddressByBindingInfo","getStateAddressByBindingInfo","stateAddress","clearStateAddressByBindingInfo","createHandlerBindingRegistry","attachedByKey","countByKey","attached","remove","countOf","keyCount","clear","handlerByHandlerKey","bindingRegistry","getHandlerKey","eventName","filterKey","f","getEventName","modifier","attachCheckboxEventHandler","MODIFIER_READONLY","checkboxEventHandler","warn","checked","filteredNewValue","createState","currentValue","concat","toSpliced","isThenable","then","captureHandlerRejection","describe","values","catch","error","Token","_name","_subscribers","subscribe","fn","unsubscribe","emit","EventToken","_stateElement","super","kind","tokenName","subscriberCount","registryByStateElement","getOrCreateEventToken","token","clearEventTokenRegistry","listenerByBinding","attachEventTokenHandler","customTagName","propertyName","getWcBindable","propDesc","didYouMean","modifiers","handler","MODIFIER_PREVENT","preventDefault","MODIFIER_STOP","stopPropagation","eventTokenNames","createStateAsync","CommandToken","isCommandToken","modifierKey","m","sort","stateEventHandlerFunction","handlerName","isCommand","STATE_COMMAND_NAMESPACE_NAME","scopedWildcardCount","hooks","addressHooks","scopes","handlerScope","Reflect","apply","attachEventHandler","stateEventHandler","detachEventHandler","attachRadioEventHandler","radioEventHandler","CHECK_TYPES","DEFAULT_VALUE_PROP_NAMES","isPossibleTwoWay","inputType","customClass","nextWireId","nextTransactionId","nextSynchronousScopeId","wireIdsByNode","getWireId","member","byKey","wireKey","wireId","getEdgeId","direction","EMPTY_EDGES","beginPropagationTransaction","originBindingId","transactionId","visitedEdges","hop","extendPropagationContext","context","edgeId","currentContext","getCurrentPropagationContext","runWithPropagationContext","callback","previous","receiptStack","consumeOccurrenceWrite","producerValueObserversByNode","DEFAULT_GETTER","e","detail","warnedDefaultGetter","hasGetter","isOccurrence","getValueGetter","isOccurrenceProperty","semantics","twowayEventHandlerFunction","valueGetter","newValue","propValue","reason","prototype","hasOwnProperty","call","props","warnDefaultGetterMismatch","producerObservers","observer","propagationContext","enablePropagationContext","receipt","active","matchWriteReceipt","writtenValue","coveredBySameValueGuard","sameValueGuard","toStateEdgeId","baseContext","commitToState","observerSkipNodes","markObserverSkipOnRemove","consumeObserverSkipOnRemove","skipRemovedChildrenByParent","consumeObserverSkipRemovedChildren","parent","count","observerSkipAddedNodes","markObserverSkipOnAdd","consumeObserverSkipOnAdd","pendingObservationCount","decrementPendingObservation","hasPendingObservation","DefinitionCoordinator","wait","reject","normalizedTagName","waiters","settle","waiter","pendingCount","coordinatorByRegistry","getDefinitionCoordinator","coordinator","readOption","MODIFIER_KEY_INIT","MODIFIER_KEY_SYNC","hasInitialSyncModifier","STATE_CALL_POLICY","authority","syncOn","observable","outputOnly","NONE_CALL_POLICY","statePolicy","resolveInitialSyncPolicy","enableDirectionalInitialSync","explicitAuthority","parseSyncOn","COMMAND_NAMESPACE","hasOutput","hasInput","resolveInitialAuthority","initialized","isBindingStateInitialized","nextRecordId","nextGeneration","SLOT_PHASE_NAMES","rowByBinding","recordByBinding","sessionByRoot","bindingKeyByBinding","interestedSessionsByNode","addInterestedSession","session","hasInterestedSession","forEachInterestedSession","forEachInclusive","child","isObservableRoot","BindingOwner","Observer","MutationObserver","mutations","handleMutations","observe","childList","removed","added","mutation","removedNodes","addedNodes","reconnected","handleRemovedNode","handleAddedNode","applyChangeFromBindings","ownerByRoot","getBindingOwner","bindingKey","registerPattern","knownRoot","rowMap","addBindingByPattern","registerAbsoluteAddress","unregisterFromLedger","removeBindingByPattern","addRecordTeardown","record","teardown","teardowns","BindingSession","records","rowPlan","rows","knownBindingsByNode","optionsByBinding","deferredByNode","initialize","registerAddress","resolvedOptions","registerPathInfo","applyOnReconnect","remember","rowRecord","rowOf","rowSlot","phases","row","addresses","patternPathInfos","registered","registerRowSlot","phase","anchor","patternListIndex","settleInitialRecord","settleConnectedSnapshot","shouldApplyState","activate","activatePlanRows","slot","planSlot","plan","slots","flags","policy","initialApplyDone","resolvedAuthority","outputOnlyMember","observationPending","getRecord","info","generation","addTeardown","isAlive","deferUntilDefined","task","cancel","tasks","finish","disposeBinding","disposeRowSlot","disposeRecord","isRowSession","currentRowPlan","disposeBindings","destroyRow","destroyRowRecord","destroyRecords","dispose","canWholesaleDestroy","pendingDefinitions","forEachActiveBindingNode","rebindAddresses","rebound","unregisterRowSlot","oldAbs","patternPathInfo","newAbs","observableRootFor","known","knownMapFor","remembered","rememberedOptions","initializeRow","n","fill","patternListIndexes","addKnownRowBinding","isEvent","revived","runRowSlotTeardowns","slotIndex","replaceToReplaceNode","recordOptions","initialPolicy","initialSettled","eventSequence","hasProducerValue","producerValue","eventAttached","twowayAttached","attachListeners","runTeardowns","detachRadioEventHandler","detachCheckboxEventHandler","attachAfterDefinition","removeObserver","byProperty","observers","addTwowayValueObserver","twowayEventHandler","attachTwowayEventHandler","listener","detachEventTokenHandler","attach","HTMLElement","readProducerSnapshot","eventWins","sequence","filteredValue","commitProducerValue","setPathInfo","detachTwowayEventHandler","reverse","getOrCreateBindingSession","getBindingSession","componentApplyHooks","setComponentApplyHooks","getFilteredValue","EMPTY_ARRAY","subscribedBindings","bindingsByContent","getBindingsByContent","setBindingsByContent","indexBindingsByContent","getIndexBindingsByContent","setIndexBindingsByContent","difference","other","elem","getUUID","toString","chainGeneration","NO_VALUE","ListIndex","position","_index","_version","_indexes","_listIndexes","_chainGeneration","_homeParentListIndex","_value","homeParentListIndex","dirty","listIndexes","WeakRef","varName","reparent","deref","createListIndex","reparentListIndex","getHomeParentListIndex","setListIndexValue","isSameListIndexValue","listIndexesByList","retiredListIndexes","isRetiredListIndex","getRepairTarget","first","home","oldParent","newParent","isRestoredHome","canReparent","getListIndexesByList","list","resolveListIndexesByList","setListIndexesByList","cacheEntryByAbsoluteStateAddress","getCacheEntryByAbsoluteStateAddress","setCacheEntryByAbsoluteStateAddress","cacheEntry","dirtyCacheEntryByAbsoluteStateAddress","TRANSITION_RUNNER_KEY","getTransitionRunner","source","run","accepts","runTransition","mutate","types","runner","updateBatchListeners","enqueueListeners","registerEnqueueListener","registerUpdateBatchListener","priority","findIndex","unregisterUpdateBatchListener","reportDeferredApplyFailure","queueMicrotask","Updater","_queueUpdateRecords","_queueRenderOnlyAddresses","enqueueAbsoluteAddress","requireStartProcess","_isQueueEmpty","_scheduleDrain","enqueueRenderOnlyAddress","updateRecords","renderOnlyAddresses","_applyChange","hasQueuedPath","testApplyChange","absoluteAddresses","contexts","contextByAbsoluteAddress","landedAddresses","droppedTransactionId","winnerTransactionId","processBindings","propagationContextByBinding","forEach","MAX_PROPAGATION_HOPS","maxHops","applyBindings","inSsr","batch","notifyUpdateBatchListeners","updater","getUpdater","ledgerByElement","keyByPathByAddress","entriesByListIndex","indexKeyedByListIndex","anyRegistered","watchersByElement","watchersByIndexes","descendantsByElement","EMPTY","recordAncestors","ledger","ledgerOf","recorded","cumulativePaths","byAncestor","descendants","byPath","lastValue","tracked","addToKey","keyMap","absAddress","removeFromKey","keyMapOf","oldKey","pushEntry","isNew","levelListIndex","registerKeyedDependency","registerIndexKeyedDependency","recordTrackedKeyedPath","getKeyedLedgerView","watchers","hasKeyedDependents","registerIndexWatcher","getterPathInfo","watcher","byList","find","w","getters","watchedRowsAt","out","collect","keyedDependents","hasOldKey","newKey","hasLast","newDiffers","lastDiffers","hasKeyedDescendants","valueAt","segment","keyedDescendantDependents","oldValue","depth","descendant","rest","allDependents","removeIndexEntry","dropKeyedSubscriptionsByListIndex","rekeyIndexSubscriptions","oldIndex","newIndex","listDiffByOldListByNewList","EMPTY_LIST","EMPTY_SET","createListDiff","rawOldList","rawNewList","diff","oldList","newList","cachedDiff","diffByNewList","getListDiff","oldIndexes","retValue","newIndexes","changeIndexSet","deleteIndexSet","addIndexSet","newListIndex","isSameList","newIndexSet","oldIndexSet","oldPosByIndex","calcDiffIndexes","indexByValue","val","existingIndexes","shift","existingListIndex","setListDiff","computeListDiff","syncListIndexes","retireListIndexes","retired","reviveListIndexes","before","after","moveIndexWatchers","computeStableIndexSet","reused","seq","prevPos","sorted","lis","tails","prev","lo","hi","mid","k","longestIncreasingSubsequence","stable","seqIndex","swapBaselineLists","markSwapBaselineList","bindingSessionByContent","getBindingSessionByContent","setBindingSessionByContent","nodesByContent","getNodesByContent","setNodesByContent","nodes","bindLoopContextToContent","planByContent","tailsByPlan","hasGetterOnPrefix","prefixes","getterPaths","applyPlanRow","rowPath","byRowPath","prefix","isIndexBinding","tail","accumulated","slotTails","rowValue","rowRead","slotTail","applyChange","appliedBindingSet","applyValueToBinding","activateContent","hasUpdatedCallback","hasRecursion","getPlanByContent","deactivateContent","mounted","unbindLoopContextToContent","createEmptySet","contentSetByNode","setContentByNode","contents","getContentSetByNode","deleteContentByNode","planBinding","recursiveBindingTypes","Content","_content","_childNodeArray","_firstNode","_lastNode","_mounted","_ranged","ranged","childNodeArray","firstNode","lastNode","appendTo","targetNode","_movableNodes","mountAfter","mover","moveBefore","insertBefore","tryDestroy","removeChild","unmount","unmountInPlace","_teardownBindings","resolveRanged","fragmentInfo","topLevelStructural","structural","hasTopLevelStructural","createContentFromNodes","createPlanContent","cloneFragment","importNode","nodeInfos","nodePath","indexBindings","nodeIndex","forNode","rowSessionByForNode","initializeRowBindings","setPlanByContent","createContent","getFragmentInfoByUUID","directional","nodeInfo","parseBindTextResults","namespace","INDEX_BY_INDEX_NAME","compileRowPlan","initialInfo","collectNodesAndBindingInfosByFragment","bindingSession","initializeBindingsByFragment","appendRowEndMarker","namedElements","NAMING_LEDGER_KEY","getAutoNaming","naming","limit","namingLimit","applyTransitionName","firstElementOf","style","counter","assigned","warned","getLedger","setProperty","lastNodeByNode","contentByListIndexByNode","pooledContentsByNode","isOnlyNodeInParentContentByNode","hydrateSetContent","contentByListIndex","setContent","hydrateSetLastNode","countsAsParentContent","textContent","isPhysicallyAfter","compareDocumentPosition","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_DISCONNECTED","collectInPlaceContents","contentMap","inPlace","byAddedIndex","STRUCTURAL_BINDING_TYPES","clearAppliedMarks","nested","dropNestedContents","dropped","bindingInfoText","applyChangeToIf","rawNewValue","Boolean","ssrMode","log","startComment","endComment","afterNode","autoNaming","store","getSsrProperties","getAllSsrPropertyNodes","trackedNodes","clearSsrPropertyStore","TRUSTED_TYPES_POLICY_SLOT","getTrustedTypesPolicy","setTrustedTypesPolicy","_enforced","_reported","reportTrustedTypesBlock","prop","innerHTML","isTrustedTypesEnforced","cause","createHTML","property","SSR_ATTR_PROPS","String","removeAttribute","selected","disabled","selectedIndex","idx","DISPLAY_PROPS","applyChangeToProperty","_context","firstSegment","rememberOverwrittenObject","isHtmlSink","performWrite","propertyWriteSucceeded","trustHtmlValue","mirrorAttr","input","getInputAttributeMirror","attributeName","formatted","JSON","stringify","applyMirrorAttribute","extendedContext","bindingId","bindingGeneration","synchronousScopeId","pop","runWithWriteReceipt","attrHandler","addSsrProperty","subObject","lastSegment","isFrozen","rememberOverwrittenValue","recordInjectedKey","ssrWrappedNodes","applyChangeToWebComponent","_binding","_newValue","getValue","indexName","indexPos","wildcardScopeMessage","getIndexValueByLoopContext","scheduledBindings","reportFailure","applyChangeByFirstSegment","CLASS_NAMESPACE","className","classList","toggle","ATTR_NAMESPACE","attrName","STYLE_NAMESPACE","styleName","methodName","elementRef","el","method","applyChangeByBindingType","nodeValue","listPathInfo","recordedLastValue","newListValueByAbsAddress","inPlaceContents","fullDelete","isOnlyNode","prevCheckNode","previousSibling","nextCheckNode","onlyNode","isOnlyNodeInParentContent","markObserverSkipRemovedChildren","poolBudget","getPooledContents","POSITIVE_INFINITY","deleteIndex","setPooledContent","elementPathInfo","loopContextStack","stableIndexSet","pooledContents","createLoopContext","rowReused","indexBinding","unmountedByAncestor","revivedContent","if","else","elseif","radio","elementFilteredValue","checkbox","normalizedNewValue","fnByBinding","deferredSelectBindingByBinding","definedApplyVerifiedByBinding","skipPendingMountWrite","resolveCustomElementApply","stateProp","isComplete","isDeclared","deferredSelectBindings","updatedAbsAddressSetByStateElement","customTag","applyLatest","currentSession","Error","scheduleDeferredApply","sameRootVerified","DocumentFragment","targetState","newContext","reportBindingApplyError","failuresByStateElement","hasErrorCallback","failures","bindingIndex","nextBindingInfo","newListValue","updatedCallback","absAddressSet","callbackError","original","initializeBindings","parentLoopContext","scheduleDeferredSpreads","waitForStateInitialize","elements","promises","initializePromise","all","buildBindings","collectStructuralFragments","body","shadowRoot","host","ENTRY_BY_FEATURE","watch","scan","stream","dcc","bindComponent","recursion","ssr","devtools","featureNotInstalledMessage","feature","ssrHooks","setSsrHooks","requireSsrHooks","stateElementByNode","bindingsReadyByNode","liveStateElements","registeredListeners","onStateElementRegistered","getLiveStateElements","getBindingsReady","markBindingsUnavailable","failed","bindingsBuiltRoots","setStateElementAlias","setBindingsReadyForScope","ready","markBindingsBuilt","setStateElement","enableSsr","hydrate","drainPendingBinds","fragmentInfoByUUID","setFragmentInfoByUUID","bindingPartial","parseBindTextResult","nodeBindingPartial","getAllFragmentUUIDs","bindTextOrUUID","_notFilterInfo","createNotFilter","COMMENT_REGEX","expandShorthandInStatePart","forPath","pipeIndex","pathPart","suffix","expandCommentData","commentPrefix","commentSuffix","expandBindAttribute","attrValue","changed","part","trimmed","colonIndex","expandShorthandInBindAttribute","expandShorthandPaths","bindAttr","comment","HTMLTemplateElement","getNodePath","unshift","getFragmentNodeInfos","fragmnentNodeInfos","subscriberNode","optimizeFragment","keywordByBindingType","notFilter","cloneNotParseBindTextResult","_getFragmentInfo","transformOwnResult","transformNodeInfos","walkRoot","elseKeyword","FILTER_REJECT","lastIfFragmentInfo","elseFragmentInfos","childForPath","lastElseFragmentInfo","placeHolder","elseUUID","elseFragmentInfo","elsePlaceHolder","BIND_ATTRIBUTE_SELECTOR","alreadyBound","isElement","querySelector","bindNow","declaresOnRoot","canWalkFromParent","beforeFirstBuild","registerBinder"],"mappings":"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"}