@pie-players/pie-assessment-toolkit 0.3.74 → 0.3.75
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.
- package/README.md +349 -313
- package/dist/attempt/TestSession.d.ts +1 -20
- package/dist/attempt/TestSession.js +8 -99
- package/dist/components/ItemScope.custom-element.d.ts +1 -0
- package/dist/components/ItemScope.custom-element.js +1 -0
- package/dist/components/ItemToolBar.custom-element.js +1 -1
- package/dist/components/PieAssessmentToolkit.custom-element.js +14 -14
- package/dist/components/SectionToolBar.custom-element.js +1 -1
- package/dist/components/chunks/ItemToolBar-7tt7v2xp.js +4 -0
- package/dist/components/chunks/{ItemToolBar-gmrryv2v.js → ItemToolBar-97hx60z4.js} +1 -1
- package/dist/components/chunks/ItemToolBar-bxwyhr5p.js +2 -0
- package/dist/components/chunks/ItemToolBar-jx38w99s.js +2 -0
- package/dist/components/chunks/ItemToolBar-rd2bb4p6.js +40 -0
- package/dist/components/chunks/ItemToolBar-vdkyn9f3.js +2 -0
- package/dist/components/chunks/sre-engine-jd8cc08x.js +1 -0
- package/dist/components/item-scope-element.d.ts +2 -0
- package/dist/components/item-scope-element.js +2 -0
- package/dist/context/assessment-toolkit-context.d.ts +27 -6
- package/dist/index.d.ts +22 -47
- package/dist/index.js +12 -36
- package/dist/policy/core/PolicySource.d.ts +1 -1
- package/dist/policy/core/ToolPolicyEngine.d.ts +77 -32
- package/dist/policy/core/ToolPolicyEngine.js +136 -46
- package/dist/policy/core/compose-decision.d.ts +28 -7
- package/dist/policy/core/compose-decision.js +75 -54
- package/dist/policy/core/decision-types.d.ts +65 -34
- package/dist/policy/core/feature-decision.d.ts +16 -9
- package/dist/policy/core/feature-decision.js +14 -8
- package/dist/policy/core/pnp-policy-inputs.d.ts +24 -33
- package/dist/policy/core/pnp-policy-inputs.js +28 -56
- package/dist/policy/core/provenance.d.ts +9 -4
- package/dist/policy/core/provenance.js +1 -1
- package/dist/policy/engine.d.ts +7 -23
- package/dist/policy/engine.js +5 -20
- package/dist/policy/sources/PnpPolicySource.d.ts +44 -61
- package/dist/policy/sources/PnpPolicySource.js +117 -118
- package/dist/runtime/SectionControllerBinding.d.ts +279 -0
- package/dist/runtime/SectionControllerBinding.js +450 -0
- package/dist/runtime/SectionRuntimeEngine.d.ts +26 -289
- package/dist/runtime/SectionRuntimeEngine.js +30 -372
- package/dist/runtime/adapter/SectionEngineAdapter.d.ts +19 -80
- package/dist/runtime/adapter/SectionEngineAdapter.js +19 -92
- package/dist/runtime/adapter/dom-event-bridge.d.ts +15 -30
- package/dist/runtime/adapter/dom-event-bridge.js +17 -44
- package/dist/runtime/adapter/subscriber-fanout.d.ts +1 -2
- package/dist/runtime/adapter/subscriber-fanout.js +1 -2
- package/dist/runtime/catalog-context.d.ts +19 -0
- package/dist/runtime/catalog-context.js +28 -0
- package/dist/runtime/composition-emit-scheduler.d.ts +9 -15
- package/dist/runtime/composition-emit-scheduler.js +9 -15
- package/dist/runtime/content-language.d.ts +32 -0
- package/dist/runtime/content-language.js +46 -0
- package/dist/runtime/content-region.d.ts +17 -0
- package/dist/runtime/content-region.js +29 -0
- package/dist/runtime/content-registration.d.ts +13 -0
- package/dist/runtime/content-registration.js +25 -0
- package/dist/runtime/core/SectionEngineCore.d.ts +2 -2
- package/dist/runtime/core/SectionEngineCore.js +2 -2
- package/dist/runtime/core/cohort.d.ts +1 -1
- package/dist/runtime/core/cohort.js +1 -1
- package/dist/runtime/core/engine-input.d.ts +18 -30
- package/dist/runtime/core/engine-input.js +11 -12
- package/dist/runtime/core/engine-output.d.ts +16 -40
- package/dist/runtime/core/engine-output.js +9 -21
- package/dist/runtime/core/engine-readiness.d.ts +5 -37
- package/dist/runtime/core/engine-readiness.js +8 -41
- package/dist/runtime/core/engine-resolver.d.ts +46 -74
- package/dist/runtime/core/engine-resolver.js +18 -43
- package/dist/runtime/core/engine-state.d.ts +28 -36
- package/dist/runtime/core/engine-state.js +18 -21
- package/dist/runtime/core/engine-transition.d.ts +14 -19
- package/dist/runtime/core/engine-transition.js +71 -51
- package/dist/runtime/engine.d.ts +16 -19
- package/dist/runtime/engine.js +12 -19
- package/dist/runtime/page-warnings.d.ts +13 -0
- package/dist/runtime/page-warnings.js +22 -0
- package/dist/runtime/policy-input-forwarding.d.ts +25 -0
- package/dist/runtime/policy-input-forwarding.js +25 -0
- package/dist/runtime/registration-events.d.ts +11 -0
- package/dist/runtime/runtime-event-claim.d.ts +8 -0
- package/dist/runtime/runtime-event-claim.js +15 -0
- package/dist/runtime/shell-event-bridge.d.ts +45 -0
- package/dist/runtime/shell-event-bridge.js +127 -0
- package/dist/runtime/shell-registration.d.ts +73 -0
- package/dist/runtime/shell-registration.js +95 -0
- package/dist/runtime/shell-scope.d.ts +68 -0
- package/dist/runtime/shell-scope.js +188 -0
- package/dist/runtime/tool-host-contract.d.ts +8 -10
- package/dist/runtime/tool-host-contract.js +11 -11
- package/dist/runtime/unclaimed-registration-watch.d.ts +7 -0
- package/dist/runtime/unclaimed-registration-watch.js +23 -0
- package/dist/services/ElementToolStateStore.d.ts +14 -10
- package/dist/services/ElementToolStateStore.js +37 -13
- package/dist/services/HighlightCoordinator.d.ts +21 -21
- package/dist/services/HighlightCoordinator.js +431 -325
- package/dist/services/RangeSerializer.d.ts +10 -1
- package/dist/services/RangeSerializer.js +87 -14
- package/dist/services/TTSService.d.ts +117 -70
- package/dist/services/TTSService.js +668 -578
- package/dist/services/ToolCoordinator.d.ts +43 -60
- package/dist/services/ToolCoordinator.js +164 -206
- package/dist/services/ToolRegistry.d.ts +74 -57
- package/dist/services/ToolRegistry.js +104 -114
- package/dist/services/ToolkitCoordinator.d.ts +183 -189
- package/dist/services/ToolkitCoordinator.js +477 -431
- package/dist/services/audio-handoff.d.ts +6 -7
- package/dist/services/audio-handoff.js +20 -14
- package/dist/services/catalog-owner.d.ts +0 -1
- package/dist/services/framework-error-bus.d.ts +3 -6
- package/dist/services/framework-error-bus.js +3 -6
- package/dist/services/framework-error.d.ts +22 -7
- package/dist/services/framework-error.js +9 -7
- package/dist/services/interfaces.d.ts +158 -129
- package/dist/services/section-session-assignment.d.ts +21 -0
- package/dist/services/section-session-assignment.js +82 -0
- package/dist/services/spoken-audio-cards.d.ts +0 -2
- package/dist/services/spoken-audio-cards.js +0 -2
- package/dist/services/tool-config-defaults.d.ts +3 -3
- package/dist/services/tool-config-defaults.js +3 -3
- package/dist/services/tool-config-validation.d.ts +4 -5
- package/dist/services/tool-config-validation.js +36 -61
- package/dist/services/tool-context.d.ts +0 -8
- package/dist/services/tool-context.js +0 -12
- package/dist/services/tool-icons.d.ts +4 -3
- package/dist/services/tool-icons.js +4 -3
- package/dist/services/tool-instance-id.d.ts +0 -1
- package/dist/services/tool-instance-id.js +0 -6
- package/dist/services/tool-providers/TTSToolProvider.d.ts +18 -19
- package/dist/services/tool-providers/TTSToolProvider.js +37 -34
- package/dist/services/tool-providers/ToolProviderApi.d.ts +10 -4
- package/dist/services/tool-providers/ToolProviderRegistry.d.ts +30 -26
- package/dist/services/tool-providers/ToolProviderRegistry.js +119 -93
- package/dist/services/tool-request.d.ts +27 -12
- package/dist/services/tool-request.js +24 -14
- package/dist/services/toolbar-decided-tools.d.ts +15 -0
- package/dist/services/toolbar-decided-tools.js +28 -0
- package/dist/services/tools-config-normalizer.d.ts +17 -22
- package/dist/services/tools-config-normalizer.js +2 -10
- package/dist/services/tts/browser-provider.d.ts +38 -2
- package/dist/services/tts/browser-provider.js +276 -140
- package/dist/services/tts/flat-tree.d.ts +71 -0
- package/dist/services/tts/flat-tree.js +269 -0
- package/dist/services/tts/generated-speech/assemble-plan.d.ts +3 -1
- package/dist/services/tts/generated-speech/assemble-plan.js +3 -1
- package/dist/services/tts/generated-speech/dom/build-dom-plan.d.ts +2 -0
- package/dist/services/tts/generated-speech/dom/build-dom-plan.js +1 -1
- package/dist/services/tts/generated-speech/math-speech-cache.d.ts +3 -1
- package/dist/services/tts/generated-speech/math-speech-cache.js +5 -1
- package/dist/services/tts/highlight-pipeline/create-highlight-plan.js +12 -4
- package/dist/services/tts/highlight-pipeline/prose-boundary-resolver.js +6 -4
- package/dist/services/tts/highlight-pipeline/readable-region.js +3 -2
- package/dist/services/tts/highlight-pipeline/types.d.ts +5 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.d.ts +12 -0
- package/dist/services/tts/highlight-pipeline/visible-map-range.js +73 -7
- package/dist/services/tts/math-aware-text-processing.d.ts +5 -1
- package/dist/services/tts/math-aware-text-processing.js +32 -18
- package/dist/services/tts/math-control-names.d.ts +21 -0
- package/dist/services/tts/math-control-names.js +142 -0
- package/dist/services/tts/math-speech.d.ts +11 -0
- package/dist/services/tts/math-speech.js +51 -18
- package/dist/services/tts/provider-options.d.ts +41 -0
- package/dist/services/tts/provider-options.js +1 -0
- package/dist/services/tts/ssml/spoken-text.d.ts +2 -26
- package/dist/services/tts/ssml/spoken-text.js +29 -0
- package/dist/services/tts/start-failure.d.ts +11 -0
- package/dist/services/tts/start-failure.js +19 -0
- package/dist/services/tts/text-processing.d.ts +9 -0
- package/dist/services/tts/text-processing.js +46 -33
- package/dist/services/tts/text-segmentation.d.ts +7 -0
- package/dist/services/tts/text-segmentation.js +47 -0
- package/dist/services/tts-runtime-config.d.ts +25 -17
- package/dist/services/tts-runtime-config.js +16 -95
- package/dist/tools/content-capability-resolution.d.ts +7 -9
- package/dist/tools/content-capability-resolution.js +8 -45
- package/dist/tools/registration.d.ts +58 -0
- package/dist/tools/registration.js +54 -0
- package/dist/tools/registrations/toolbar-registration-helpers.js +2 -2
- package/dist/tools/tool-surface-host.d.ts +6 -10
- package/dist/tools/tool-surface-host.js +44 -42
- package/dist/tools/tool-tag-map.d.ts +5 -15
- package/dist/tools/tool-tag-map.js +6 -20
- package/dist/utils/structural-equality.d.ts +11 -0
- package/dist/utils/structural-equality.js +47 -0
- package/package.json +13 -29
- package/dist/attempt/adapters/activity-to-test-attempt-session.d.ts +0 -49
- package/dist/attempt/adapters/activity-to-test-attempt-session.js +0 -138
- package/dist/components/chunks/ItemToolBar-b9dz5jvd.js +0 -40
- package/dist/components/chunks/ItemToolBar-h4xap0t0.js +0 -4
- package/dist/components/chunks/ItemToolBar-wr2myaah.js +0 -2
- package/dist/components/chunks/sre-engine-wf9s43gg.js +0 -1
- package/dist/context/runtime-context-consumer.d.ts +0 -13
- package/dist/context/runtime-context-consumer.js +0 -18
- package/dist/item-loader.d.ts +0 -44
- package/dist/item-loader.js +0 -61
- package/dist/policy/core/engine-context.d.ts +0 -29
- package/dist/policy/core/engine-context.js +0 -27
- package/dist/policy/core/policy-source-tag.d.ts +0 -31
- package/dist/policy/core/policy-source-tag.js +0 -28
- package/dist/policy/internal.d.ts +0 -25
- package/dist/policy/internal.js +0 -25
- package/dist/runtime/adapter/coordinator-bridge.d.ts +0 -92
- package/dist/runtime/adapter/coordinator-bridge.js +0 -126
- package/dist/runtime/adapter/framework-error-bridge.d.ts +0 -36
- package/dist/runtime/adapter/framework-error-bridge.js +0 -46
- package/dist/runtime/adapter/instrumentation-bridge.d.ts +0 -31
- package/dist/runtime/adapter/instrumentation-bridge.js +0 -38
- package/dist/runtime/core/engine-stage-derivation.d.ts +0 -18
- package/dist/runtime/core/engine-stage-derivation.js +0 -29
- package/dist/runtime/engine-context.d.ts +0 -39
- package/dist/runtime/engine-context.js +0 -31
- package/dist/runtime/internal.d.ts +0 -43
- package/dist/runtime/internal.js +0 -45
- package/dist/runtime/section-runtime-engine-host-context.d.ts +0 -74
- package/dist/runtime/section-runtime-engine-host-context.js +0 -57
- package/dist/runtime/stage-emit-gate.d.ts +0 -92
- package/dist/runtime/stage-emit-gate.js +0 -82
- package/dist/services/I18nService.d.ts +0 -47
- package/dist/services/I18nService.js +0 -84
- package/dist/services/ThemeProvider.d.ts +0 -95
- package/dist/services/ThemeProvider.js +0 -334
- package/dist/services/defaultPersonalNeedsProfile.d.ts +0 -21
- package/dist/services/defaultPersonalNeedsProfile.js +0 -26
- package/dist/services/pnp-standard-features.d.ts +0 -238
- package/dist/services/pnp-standard-features.js +0 -338
- package/dist/tools/client.d.ts +0 -10
- package/dist/tools/client.js +0 -10
- package/dist/tools/internal.d.ts +0 -44
- package/dist/tools/internal.js +0 -39
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{
|
|
2
|
-
- ${
|
|
3
|
-
- `)}`}var
|
|
4
|
-
`);throw Error(`[tool-config-validation:${
|
|
5
|
-
${J}`)}function A0(Q,Y={}){let J=d1(Q,Y.toolRegistry);return l1(J.diagnostics,Y),J}function d1(Q,Y){let J=H3(Y),G=b7(Q),X=[],j=Object.values(G.placement).some((K)=>K.length>0)||Object.keys(G.providers).length>0||(G.policy.allowed?.length??0)>0||(G.policy.blocked?.length??0)>0;if(J.size===0&&j)X.push(l({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated, and a coordinator without one registers no tool providers. Pass `toolRegistry` to the coordinator or the toolkit it is bound to — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let Z=Object.hasOwn(G.providers,"tts"),B={...G.providers||{}};for(let K of Object.keys(B).sort()){if(K==="tts"){delete B.tts;continue}let U=J.get(K);B[K]=D3(K,B[K],U,X),N3(K,B[K],U,X)}let W={...G,providers:B};return M3(W,J,X),z3(W,J,X),O3(W,J,Z,X),{config:W,diagnostics:X}}function l1(Q,Y={}){let J=c1(Y.strictness),G=Y.source??"tools",X=Q.filter((Z)=>Z.code==="tools.removedProviderKey");if(X.length>0)V0(X,G);if(J==="warn")U0(Q,G);let j=Q.filter((Z)=>Z.severity==="error");if(J==="error"&&j.length>0)V0(j,G);if(J==="error"&&j.length===0)U0(Q,G)}import{languageTagLookupSequence as E3,normalizeLanguageTag as D0}from"@pie-players/pie-players-shared/i18n/language-tags";var i1=(Q)=>Array.isArray(Q)&&Q.length>0;function s1(Q){if(Q.kind==="passage")return{ownerKind:"passage",assessmentId:Q.assessmentId,sectionId:Q.sectionId,passageId:Q.canonicalItemId||Q.itemId};return{ownerKind:"itemModel",assessmentId:Q.assessmentId,sectionId:Q.sectionId,itemId:Q.itemId,canonicalItemId:Q.canonicalItemId||Q.itemId}}function _0(Q,Y){if(!Q)return[];let J=s1(Y),G=[];if(i1(Q.accessibilityCatalogs))G.push({context:J,catalogs:Q.accessibilityCatalogs});if(i1(Q.config?.extractedCatalogs))G.push({context:J,catalogs:Q.config.extractedCatalogs});if(Y.kind==="passage")return G;if(J.ownerKind!=="itemModel")return G;for(let X of Q.config?.models??[]){if(!i1(X.accessibilityCatalogs))continue;G.push({context:{...J,modelId:X.id},catalogs:X.accessibilityCatalogs})}return G}var o1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),$0=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),F0=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),H0=new Set(["break","mark","lexicon"]);function P3(Q){let Y=Q;for(let J of H0){let G=new RegExp(`<${J}\\b([^>/]*?)\\s*/>`,"gi");Y=Y.replace(G,(X,j)=>{let Z=j?j.replace(/\s+$/,""):"";return`<${J}${Z}></${J}>`})}return Y}var L3=[/^localhost$/i,/^127(?:\.\d{1,3}){3}$/,/^0(?:\.\d{1,3}){3}$/,/^10(?:\.\d{1,3}){3}$/,/^192\.168(?:\.\d{1,3}){2}$/,/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,/^169\.254(?:\.\d{1,3}){2}$/,/^::1$/,/^fe80:/i,/^fc00:/i,/^fd[0-9a-f]{2}:/i,/^metadata\.google\.internal$/i,/^metadata\.azure\.internal$/i,/^metadata\.packet\.net$/i];function w3(Q){if(typeof Q!=="string"||Q.length===0)return!1;let Y;try{Y=new URL(Q)}catch{return!1}if(Y.protocol!=="http:"&&Y.protocol!=="https:")return!1;let J=Y.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!L3.some((G)=>G.test(J))}function n1(Q){let Y=Array.from(Q.children);for(let G of Y){let X=G.tagName.toLowerCase();if($0.has(X)){G.remove();continue}if(n1(G),!o1.has(X)){let j=Q.ownerDocument.createTextNode(G.textContent??"");G.replaceWith(j)}}let J=Array.from(Q.attributes).map((G)=>G.name);for(let G of J)if(!F0.has(G.toLowerCase()))Q.removeAttribute(G);if(Q.tagName.toLowerCase()==="audio"){let G=Q.getAttribute("src");if(G!==null&&!w3(G))Q.removeAttribute("src")}}function r1(Q){let Y=Q.tagName.toLowerCase(),J=Array.from(Q.attributes).filter((X)=>F0.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${R3(X.value)}"`).join("");if(H0.has(Y))return`<${Y}${J}/>`;let G=[];for(let X of Array.from(Q.childNodes))if(X.nodeType===3)G.push(q1(X.nodeValue??""));else if(X.nodeType===1){let j=X,Z=j.tagName.toLowerCase();if($0.has(Z))continue;if(o1.has(Z))G.push(r1(j));else G.push(q1(j.textContent??""))}return`<${Y}${J}>${G.join("")}</${Y}>`}function a1(Q){let Y=String(Q||"").trim();if(!Y||!Y.includes("<"))return Q;if(typeof DOMParser>"u")return Q;let G=new DOMParser().parseFromString(P3(Y),"text/html"),X=G.querySelector("speak");if(X)return n1(X),r1(X);let j=G.createElement("speak");for(let Z of Array.from(G.body.childNodes))j.appendChild(Z);return n1(j),Array.from(j.childNodes).map((Z)=>{if(Z.nodeType===3)return q1(Z.nodeValue??"");if(Z.nodeType===1){let B=Z;if(o1.has(B.tagName.toLowerCase()))return r1(B);return q1(B.textContent??"")}return""}).join("")}function q1(Q){return Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function R3(Q){return Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var P0=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),t1="ext:";function N0(Q){if(P0.has(Q))return!0;return Q.startsWith(t1)&&Q.length>t1.length}var M0=new Set;function e1(Q,Y=new Set){if(Q===null||typeof Q==="string"||typeof Q==="number"||typeof Q==="boolean"||typeof Q>"u")return Q;if(typeof Q!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Y.has(Q))throw TypeError("catalog cards must not contain cycles");Y.add(Q);try{if(Array.isArray(Q))return Object.freeze(Q.map((X)=>e1(X,Y)));let J=Object.getPrototypeOf(Q);if(J!==Object.prototype&&J!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let G={};for(let[X,j]of Object.entries(Q))G[X]=e1(j,Y);return Object.freeze(G)}finally{Y.delete(Q)}}function z0(Q,Y,J){let G=`${Y}|${Q}`;if(M0.has(G))return;M0.add(G);let X=`${Array.from(P0).join(", ")}, or an "${t1}" prefixed vendor extension`;if(Y==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${J}" has a card of unknown type "${Q}"; it is stored but no reader asks for that type, so the alternate will never be shown. Expected one of: ${X}.`);return}console.warn(`[AccessibilityCatalogResolver] lookup for unknown catalog type "${Q}" on "${J}" cannot match any card. Expected one of: ${X}.`)}var O0=(Q)=>Q.payload!==void 0?"payload":"content";class Q9{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Q,Y="en-US"){this.defaultLanguage=Y,this.indexCatalogs(Q??[],"assessment")}setDefaultLanguage(Q){this.defaultLanguage=Q}onCatalogsChange(Q){return this.catalogChangeListeners.add(Q),()=>{this.catalogChangeListeners.delete(Q)}}emitCatalogsChange(Q){for(let Y of Array.from(this.catalogChangeListeners))try{Y(Q)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Q,Y){let J=Y==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let G of this.sanitizeCatalogs(Q)){if(J.has(G.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Y} catalog "${G.identifier}" ignored`);continue}J.set(G.identifier,G)}}insertScopedCatalogs(Q,Y){if(!Y||Y.length===0)return null;let J=this.getOwnerKey(Q),G=this.scopedCatalogs.get(J),X=G?.catalogs??new Map,j=[];for(let Z of this.sanitizeCatalogs(Y)){if(X.has(Z.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${Z.identifier}" ignored for ${J}`);continue}X.set(Z.identifier,Z),j.push(Z.identifier)}if(!G&&j.length>0)this.scopedCatalogs.set(J,{context:{...Q},catalogs:X});return{key:J,context:{...Q},catalogs:X,insertedIds:j}}removeScopedInsertion(Q){let Y=this.scopedCatalogs.get(Q.key);if(Y?.catalogs!==Q.catalogs)return!1;let J=!1;for(let G of Q.insertedIds)J=Y.catalogs.delete(G)||J;if(Y.catalogs.size===0)this.scopedCatalogs.delete(Q.key);return J}registerCatalogs(Q,Y){let J=this.insertScopedCatalogs(Q,Y);if(J&&J.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Q});let G=!0;return()=>{if(!G)return;if(G=!1,J&&this.removeScopedInsertion(J))this.emitCatalogsChange({reason:"scoped-removed",context:Q})}}registerOwner(Q){let{owner:Y,entity:J}=Q,G=s1(Y),X=[],j=[];try{j=_0(J,Y)}catch(W){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",W)}for(let W of j)try{let K=this.insertScopedCatalogs(W.context,W.catalogs);if(K)X.push(K)}catch(K){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",K)}if(X.some((W)=>W.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:G});let B=!0;return()=>{if(!B)return;B=!1;let W=!1;for(let K of X)W=this.removeScopedInsertion(K)||W;if(W)this.emitCatalogsChange({reason:"scoped-removed",context:G})}}forOwner(Q){let Y={...Q};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Y),onChange:(J)=>this.onCatalogsChange((G)=>{if(this.catalogChangeAffectsOwner(G,Y))J()})})}addItemCatalogs(Q){if(!Q||Q.length===0)return;this.indexCatalogs(Q,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(Q){return this.itemCatalogs.has(Q)||this.assessmentCatalogs.has(Q)||Array.from(this.scopedCatalogs.values()).some((Y)=>Y.catalogs.has(Q))}getAlternative(Q,Y){if(!N0(Y.type))z0(Y.type,"lookup",Q);let J=Y.context?this.scopedCatalogs.get(this.getOwnerKey(Y.context))?.catalogs.get(Q):null;if(J){let j=this.findMatchingCard(J,Y);if(j)return this.resolveCard(Q,j,"item")}if(Y.context){let j=this.findScopedCandidates(Q,Y.context);if(j.length===1){let Z=this.findMatchingCard(j[0],Y);if(Z)return this.resolveCard(Q,Z,"item")}else if(j.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Q}" for owner context`,Y.context),null}let G=this.itemCatalogs.get(Q);if(G){let j=this.findMatchingCard(G,Y);if(j)return this.resolveCard(Q,j,"item")}let X=this.assessmentCatalogs.get(Q);if(X){let j=this.findMatchingCard(X,Y);if(j)return this.resolveCard(Q,j,"assessment")}return null}resolveCard(Q,Y,J){return{catalogId:Q,type:Y.catalog,language:Y.language,content:Y.catalog==="spoken"&&Y.content!==void 0?this.ensureSpokenSanitized(Y.content):Y.content,payload:Y.payload,source:J}}ensureSpokenSanitized(Q){let Y=this.sanitizedSpokenCache.get(Q);if(Y!==void 0)return Y;let J=a1(Q);return this.sanitizedSpokenCache.set(Q,J),J}getOwnerKey(Q){return[Q.ownerKind,Q.assessmentId||"",Q.sectionId||"",Q.canonicalItemId||"",Q.itemId||"",Q.passageId||"",Q.modelId||""].join("|")}scopedCatalogEntries(){let Q=[];for(let Y of this.scopedCatalogs.values())for(let J of Y.catalogs.entries())Q.push(J);return Q}findScopedCandidates(Q,Y){return Array.from(this.scopedCatalogs.values()).filter((J)=>this.isCompatibleOwnerContext(J.context,Y)).map((J)=>J.catalogs.get(Q)).filter((J)=>Boolean(J))}isCompatibleOwnerContext(Q,Y){if(Q.ownerKind!==Y.ownerKind)return!1;if(Y.assessmentId&&Q.assessmentId!==Y.assessmentId)return!1;if(Y.sectionId&&Q.sectionId!==Y.sectionId)return!1;if(Y.canonicalItemId&&Q.canonicalItemId!==Y.canonicalItemId)return!1;if(Y.itemId&&Q.itemId!==Y.itemId)return!1;if(Y.passageId&&Q.passageId!==Y.passageId)return!1;if(Y.modelId&&Q.modelId!==Y.modelId)return!1;return!0}ownerScopedCatalogEntries(Q){let Y=[],J=this.scopedCatalogs.get(this.getOwnerKey(Q));if(J)Y.push(...J.catalogs.entries());for(let G of this.scopedCatalogs.values()){if(G===J)continue;if(!this.isCompatibleOwnerContext(G.context,Q))continue;Y.push(...G.catalogs.entries())}return Y}createOwnerSnapshot(Q){let Y=[],J=this.ownerScopedCatalogEntries(Q);if(Q.ownerKind==="global")J.push(...this.assessmentCatalogs.entries());for(let[G,X]of J)for(let j of X.cards)try{Y.push(Object.freeze({catalogId:G,card:e1(j)}))}catch(Z){let B=`${this.getOwnerKey(Q)}\x00${G}`;if(!this.reportedSnapshotProblems.has(B))this.reportedSnapshotProblems.add(B),console.warn(`[AccessibilityCatalogResolver] Catalog "${G}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,Z)}return Object.freeze({cards:Object.freeze(Y)})}catalogChangeAffectsOwner(Q,Y){if(!Q.context)return!1;if(this.isCompatibleOwnerContext(Q.context,Y))return!0;if(Y.ownerKind==="itemModel"&&Y.modelId&&Q.context.ownerKind==="itemModel"&&!Q.context.modelId)return this.isCompatibleOwnerContext({...Q.context,modelId:Y.modelId},Y);return!1}sanitizeCatalogs(Q){return Q.map((Y)=>({...Y,cards:Y.cards.map((J)=>{if(!N0(J.catalog))z0(J.catalog,"card",Y.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?a1(J.content):J.content}})}))}findMatchingCard(Q,Y){let{type:J,language:G,useFallback:X=!0,form:j}=Y,Z=[],B=(W)=>{for(let K of E3(W))Z.push((U)=>D0(U.language)===K)};if(G)B(G);if(X)B(this.defaultLanguage),Z.push(()=>!0);for(let W of Z){let K=Q.cards.filter((U)=>U.catalog===J&&W(U));if(K.length===0)continue;if(j){let U=K.find((_)=>O0(_)===j);if(U)return U}return K[0]}return null}getAllAlternatives(Q){let Y=[],J=new Set,G=(Z,B)=>{let W=`${Z.catalog}|${D0(Z.language)}|${O0(Z)}`;if(J.has(W))return;J.add(W),Y.push(this.resolveCard(Q,Z,B))},X=this.itemCatalogs.get(Q);if(X)for(let Z of X.cards)G(Z,"item");let j=this.assessmentCatalogs.get(Q);if(j)for(let Z of j.cards)G(Z,"assessment");for(let[Z,B]of this.scopedCatalogEntries()){if(Z!==Q)continue;for(let W of B.cards)G(W,"item")}return Y}getAllCatalogIds(){let Q=this.scopedCatalogEntries().map(([Y])=>Y);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Q]))}getStatistics(){let Q=new Set,Y=new Set;for(let J of this.assessmentCatalogs.values())for(let G of J.cards)if(Q.add(G.catalog),G.language)Y.add(G.language);for(let J of this.itemCatalogs.values())for(let G of J.cards)if(Q.add(G.catalog),G.language)Y.add(G.language);for(let J of this.scopedCatalogs.values())for(let G of J.catalogs.values())for(let X of G.cards)if(Q.add(X.catalog),X.language)Y.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,G)=>J+G.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,G)=>J+G.catalogs.size,0),availableTypes:Q,availableLanguages:Y}}hasAlternativeType(Q,Y){return this.getAllAlternatives(Q).some((G)=>G.type===Y)}getCatalogsByType(Q){let Y=new Set;for(let[J,G]of this.assessmentCatalogs.entries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);for(let[J,G]of this.itemCatalogs.entries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);for(let[J,G]of this.scopedCatalogEntries())if(G.cards.some((X)=>X.catalog===Q))Y.add(J);return Array.from(Y)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}class Y9{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Q,Y,J,G){return`${Q}:${Y}:${J}:${G}`}parseGlobalElementId(Q){let Y=Q.split(":");if(Y.length!==4)return null;return{assessmentId:Y[0],sectionId:Y[1],itemId:Y[2],elementId:Y[3]}}setState(Q,Y,J){let G=this.elementStates.get(Q);if(!G)G=new Map,this.elementStates.set(Q,G);G.set(Y,J),this._notifyListeners(),this._notifyStateChange()}getState(Q,Y){return this.elementStates.get(Q)?.get(Y)}getElementState(Q){let Y=this.elementStates.get(Q);if(!Y)return{};return Object.fromEntries(Y.entries())}getAllState(){let Q={};for(let[Y,J]of this.elementStates.entries())Q[Y]=Object.fromEntries(J.entries());return Q}subscribe(Q){return this.listeners.add(Q),()=>this.listeners.delete(Q)}_notifyListeners(){for(let Q of this.listeners)Q(this.elementStates)}setOnStateChange(Q){this.onStateChange=Q}_notifyStateChange(){if(this.onStateChange)this.onStateChange(this.getAllState())}loadState(Q){this.elementStates.clear();for(let[Y,J]of Object.entries(Q)){let G=new Map(Object.entries(J));this.elementStates.set(Y,G)}this._notifyListeners()}clearElement(Q){this.elementStates.delete(Q),this._notifyListeners(),this._notifyStateChange()}clearTool(Q){for(let Y of this.elementStates.values())Y.delete(Q);this._notifyListeners(),this._notifyStateChange()}clearSection(Q,Y){let J=`${Q}:${Y}:`,G=[];for(let X of this.elementStates.keys())if(X.startsWith(J))G.push(X);for(let X of G)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class u7{listeners=new Set;subscribeFrameworkErrors(Q){this.listeners.add(Q);let Y=!0;return()=>{if(!Y)return;Y=!1,this.listeners.delete(Q)}}reportFrameworkError(Q){let Y=Array.from(this.listeners);for(let J of Y)try{J(Q)}catch(G){console.warn("[FrameworkErrorBus] listener failed:",G)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}class J9{serialize(Q,Y){return{startContainer:this.getNodePath(Q.startContainer,Y),startOffset:Q.startOffset,endContainer:this.getNodePath(Q.endContainer,Y),endOffset:Q.endOffset,text:Q.toString()}}deserialize(Q,Y){let J=this.findNodeByPath(Q.startContainer,Y),G=this.findNodeByPath(Q.endContainer,Y);if(!J||!G)return null;try{let X=new Range;if(X.setStart(J,Q.startOffset),X.setEnd(G,Q.endOffset),X.toString()===Q.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(Q,Y){if(Q===Y)return"";if(Q.nodeType===Node.TEXT_NODE){let J=Q.parentElement;if(!J)throw Error("Text node has no parent");let X=Array.from(J.childNodes).filter((Z)=>Z.nodeType===Node.TEXT_NODE).indexOf(Q);return`${this.getElementPath(J,Y)}::text[${X}]`}if(Q.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Q,Y);throw Error(`Unsupported node type: ${Q.nodeType}`)}getElementPath(Q,Y){if(Q===Y)return"";let J=[],G=Q;while(G&&G!==Y){if(G.id){J.unshift(`#${G.id}`);break}let X=G.parentElement;if(!X)break;let j=Array.from(X.children).filter((W)=>W.tagName===G.tagName),Z=j.indexOf(G),B=j.length>1?`${G.tagName.toLowerCase()}:nth-of-type(${Z+1})`:G.tagName.toLowerCase();J.unshift(B),G=X}return J.join(" > ")}findNodeByPath(Q,Y){if(Q==="")return Y;if(Q.includes("::text[")){let[J,G]=Q.split("::text["),X=Number.parseInt(G.replace("]",""),10),j=J?Y.querySelector(J):Y;if(!j)return null;return Array.from(j.childNodes).filter((B)=>B.nodeType===Node.TEXT_NODE)[X]||null}try{return Y.querySelector(Q)}catch(J){return console.warn("Invalid selector path:",Q,J),null}}serializeMany(Q,Y){return Q.map((J)=>this.serialize(J,Y))}deserializeMany(Q,Y){return Q.map((J)=>this.deserialize(J,Y))}}var u;(function(Q){Q.TTS_WORD="tts-word",Q.TTS_SENTENCE="tts-sentence",Q.ANNOTATION="annotation"})(u||(u={}));var _7;(function(Q){Q.YELLOW="yellow",Q.GREEN="green",Q.BLUE="blue",Q.PINK="pink",Q.ORANGE="orange",Q.UNDERLINE="underline"})(_7||(_7={}));class p7{ttsWordHighlight=null;ttsSentenceHighlight=null;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;colorHighlights=new Map;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;explicitTTSColorOverride=null;constructor(){if(this.rangeSerializer=new J9,typeof CSS>"u"||!("highlights"in CSS)){console.warn("CSS Custom Highlight API not supported (SSR or unsupported browser)");return}this.supported=!0,this.initializeHighlights(),this.registerStyles(),this.applyAdaptiveTTSStyle(),this.setupThemeObservation()}setupThemeObservation(){if(typeof document>"u")return;if(typeof MutationObserver>"u")return;let Q=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(Q),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Y of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Y,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(Q){if(!Q)return null;let Y=Q.trim();if(!Y)return null;let J=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Y);if(J){let X=J[1];if(X.length===3)return[parseInt(X[0]+X[0],16),parseInt(X[1]+X[1],16),parseInt(X[2]+X[2],16)];return[parseInt(X.slice(0,2),16),parseInt(X.slice(2,4),16),parseInt(X.slice(4,6),16)]}let G=/^rgba?\((.+)\)$/i.exec(Y);if(G){let j=G[1].replace(/\//g,",").split(/[,\s]+/).map((K)=>K.trim()).filter(Boolean),Z=Number(j[0]),B=Number(j[1]),W=Number(j[2]);if(Number.isFinite(Z)&&Number.isFinite(B)&&Number.isFinite(W))return[Z,B,W]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=Y,typeof X.style.color==="string"&&X.style.color){document.body?.appendChild(X);let j=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let Z=j.trim();if(Z&&Z!==Y)return this.parseColor(j)}}return null}relativeLuminance([Q,Y,J]){let G=(B)=>{let W=B/255;return W<=0.03928?W/12.92:((W+0.055)/1.055)**2.4},X=G(Q),j=G(Y),Z=G(J);return 0.2126*X+0.7152*j+0.0722*Z}contrastRatio(Q,Y){let J=this.relativeLuminance(Q),G=this.relativeLuminance(Y),X=Math.max(J,G),j=Math.min(J,G);return(X+0.05)/(j+0.05)}blend(Q,Y,J){return[Math.round(Q[0]*J+Y[0]*(1-J)),Math.round(Q[1]*J+Y[1]*(1-J)),Math.round(Q[2]*J+Y[2]*(1-J))]}resolveAdaptiveTTSStyle(Q){let Y=[255,235,59],J=[17,24,39],G=[255,255,255],X=Q||(typeof document<"u"?document.documentElement:null),j=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,Z=this.parseColor(j?.getPropertyValue("--pie-background")||j?.backgroundColor)||G,B=this.parseColor(j?.getPropertyValue("--pie-text"))||J,W=this.explicitTTSColorOverride?this.parseColor(this.explicitTTSColorOverride.color)||Y:this.parseColor(j?.getPropertyValue("--pie-missing"))||Y,K=this.explicitTTSColorOverride?[Math.max(0.3,Math.min(0.95,this.explicitTTSColorOverride.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],U=K[K.length-1],_=-1/0;for(let g of K){let B7=this.blend(W,Z,g),q7=this.contrastRatio(B7,Z),W7=this.contrastRatio(B7,B),w7=q7*1.2+W7*0.8;if(q7>=1.25&&W7>=2.4){U=g;break}if(w7>_)_=w7,U=g}let $=Math.max(0.24,Math.min(0.85,U*0.55)),N=Math.max(0.55,Math.min(0.95,U+0.2)),D=Math.max(0.22,Math.min(0.6,U*0.45)),O=B,P=this.blend(O,Z,N),F=this.contrastRatio(P,Z),L=this.relativeLuminance(Z)>0.45?[0,0,0]:[255,255,255],C=F>=1.35?O:L,v=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${U})`,k=`rgba(${W[0]}, ${W[1]}, ${W[2]}, ${$})`,p=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${N})`,R=`rgba(${C[0]}, ${C[1]}, ${C[2]}, ${D})`;return{wordHighlight:v,sentenceHighlight:k,wordUnderline:p,wordShadow:R}}applyAdaptiveTTSStyle(Q){if(typeof document>"u")return;let Y=this.resolveAdaptiveTTSStyle(Q);document.documentElement.style.setProperty("--pie-tts-word-highlight",Y.wordHighlight),document.documentElement.style.setProperty("--pie-tts-sentence-highlight",Y.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-line-highlight",Y.sentenceHighlight),document.documentElement.style.setProperty("--pie-tts-word-underline",Y.wordUnderline),document.documentElement.style.setProperty("--pie-tts-word-shadow",Y.wordShadow)}initializeHighlights(){if(!this.supported)return;this.ttsWordHighlight=new Highlight,this.ttsSentenceHighlight=new Highlight,CSS.highlights.set("tts-word",this.ttsWordHighlight),CSS.highlights.set("tts-sentence",this.ttsSentenceHighlight);for(let Q of Object.values(_7)){let Y=new Highlight;this.colorHighlights.set(Q,Y),CSS.highlights.set(`annotation-${Q}`,Y)}}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let Q=document.createElement("style");Q.id="pie-highlight-styles",Q.textContent=`
|
|
1
|
+
import{a as i0,b as N5,c as w5,e as P5,f as R5,g as E5,h as C5,i as GZ,j as jZ}from"./chunks/ItemToolBar-vdkyn9f3.js";import{o as g3,p as $8,q as h9,r as O5,s as c9}from"./chunks/ItemToolBar-bxwyhr5p.js";import{$ as _5,A as V5,B as q5,C as z8,D as s0,E as n0,F as T,G as $5,H as A,I,L as _8,M as A5,N as r0,O as o0,P as D5,T as F5,U as z5,Z as H5,_ as k,aa as M5,ba as a0,ea as H8,ha as L5,ja as e3,ka as t9,t as W5,u as U5,v as K5,w as s,x,y as n,z as v}from"./chunks/ItemToolBar-7tt7v2xp.js";import{la as oZ,ma as aZ}from"./chunks/ItemToolBar-jx38w99s.js";import{oa as s7}from"./chunks/ItemToolBar-97hx60z4.js";import{coerceBooleanAttributes as $2}from"@pie-players/pie-players-shared/ui/attribute-coercion";import{ContextProvider as j5,requestContext as B5}from"@pie-players/pie-context";import{attachInstrumentationEventBridge as A2,resolveInstrumentationProvider as D2,TOOLKIT_INSTRUMENTATION_EVENT_MAP as F2}from"@pie-players/pie-players-shared/pie";import{commitPendingSessions as z2,createPieLogger as H2,isGlobalDebugEnabled as _2,isInstrumentationProvider as M2}from"@pie-players/pie-players-shared";import{createPieI18n as L2,DEFAULT_LOCALE as O2}from"@pie-players/pie-players-shared/i18n";function E0(Z){return{kind:Z.kind,severity:Z.severity??"error",source:Z.source,message:Z.message,details:[...Z.details||[]],recoverable:Z.recoverable===!0,scope:Z.scope??"runtime",cause:Z.cause}}function A1(Z){let Q=Z.error instanceof Error&&Z.error.message.trim().length>0?Z.error.message:String(Z.error||"Unknown framework error");return E0({kind:Z.kind,source:Z.source,message:Q,recoverable:Z.recoverable,scope:Z.scope,cause:Z.error})}var O6={"coordinator-ready":"coordinator-init","state-load":"tool-state-load","state-save":"tool-state-save","provider-register":"provider-register","provider-init":"provider-init","tts-init":"tts-init","section-controller-init":"section-controller-init","section-controller-dispose":"section-controller-dispose","tool-module-load":"tool-module-load"};function s8(Z){let Q=O6[Z.context.phase],J=Z.context.toolId?`pie-toolkit-coordinator/${Z.context.toolId}`:`pie-toolkit-coordinator:${Z.context.phase}`;return A1({kind:Q,source:J,error:Z.error,recoverable:Z.recoverable,scope:Z.scope})}function n8(Z){let Q=`[pie-framework:${Z.kind}:${Z.source}]`;if(Z.details.length===0)return`${Q} ${Z.message}`;return`${Q} ${Z.message}
|
|
2
|
+
- ${Z.details.join(`
|
|
3
|
+
- `)}`}var N6="error";function D1(Z){if(Z==="off"||Z==="warn"||Z==="error")return Z;return N6}function o(Z){return Z}function w6(Z){if(!Z)return new Map;return new Map(Z.getAllTools().slice().sort((Q,J)=>Q.toolId.localeCompare(J.toolId)).map((Q)=>[Q.toolId,Q]))}function P6(Z,Q,J,Y){if(!Q||!J?.sanitizeConfig)return Q;try{let X=J.sanitizeConfig(Q);if(!X||typeof X!=="object"||Array.isArray(X))return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" must return an object.`,toolId:Z})),Q;return X}catch(X){return Y.push(o({code:"tools.providerSanitizeFailed",severity:"error",path:`providers.${Z}`,message:`Config sanitizer of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z})),Q}}function R6(Z,Q,J,Y){if(!Q||!J?.validateConfig)return;try{let X=J.validateConfig(Q);if(!Array.isArray(X)){Y.push(o({code:"tools.invalidProviderValidation",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" must return an array.`,toolId:Z}));return}for(let G of X)Y.push({...G,path:G.path||`providers.${Z}`,toolId:G.toolId||Z})}catch(X){Y.push(o({code:"tools.providerValidateFailed",severity:"error",path:`providers.${Z}`,message:`Config validator of tool "${Z}" failed: ${X instanceof Error?X.message:String(X)}`,toolId:Z}))}}function E6(Z,Q,J){if(Q.size===0)return;let Y=["section","item","passage"];for(let X of Y)for(let G of Z.placement[X]){let j=Q.get(G);if(!j){J.push(o({code:"tools.unknownToolId",severity:"error",path:`placement.${X}`,message:`Unknown tool id "${G}" in placement.${X}.`,toolId:G}));continue}if(j.activation==="region"){J.push(o({code:"tools.unplaceableActivation",severity:"error",path:`placement.${X}`,message:`Tool "${G}" renders into a host surface (activation "region") and cannot be placed on the ${X} toolbar. Remove it from placement.${X}; its availability comes from policy plus its content dependency.`,toolId:G}));continue}let B=j.supportedLevels.includes(X),U=X==="item"&&j.supportedLevels.includes("section");if(!B&&!U)J.push(o({code:"tools.unsupportedLevel",severity:"error",path:`placement.${X}`,message:`Tool "${G}" does not support level "${X}".`,toolId:G}))}}function C6(Z,Q,J){if(Q.size===0)return;for(let Y of Z.policy.allowed||[]){if(Q.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.allowed",message:`Unknown tool id "${Y}" in policy.allowed.`,toolId:Y}))}for(let Y of Z.policy.blocked||[]){if(Q.has(Y))continue;J.push(o({code:"tools.unknownToolId",severity:"error",path:"policy.blocked",message:`Unknown tool id "${Y}" in policy.blocked.`,toolId:Y}))}}function b6(Z,Q,J){for(let Y of Object.keys(Z.providers).sort()){if(Q.size===0||Q.has(Y))continue;J.push(o({code:"tools.unknownProviderKey",severity:"error",path:`providers.${Y}`,message:`Unknown provider key "${Y}".`,toolId:Y}))}}function r8(Z,Q){if(Z.length===0)return;for(let J of Z){let Y=`[tool-config-validation:${Q}]`;console.warn(`${Y} ${J.path} - ${J.message}`)}}function S6(Z,Q){let J=Z.map((Y)=>`- ${Y.path}: ${Y.message}`).join(`
|
|
4
|
+
`);throw Error(`[tool-config-validation:${Q}] Invalid tools config:
|
|
5
|
+
${J}`)}function o8(Z,Q={}){let J=F1(Z,Q.toolRegistry);return z1(J.diagnostics,Q),J}function F1(Z,Q){let J=w6(Q),Y=c9(Z),X=[],G=Object.values(Y.placement).some((U)=>U.length>0)||Object.keys(Y.providers).length>0||(Y.policy.allowed?.length??0)>0||(Y.policy.blocked?.length??0)>0;if(J.size===0&&G)X.push(o({code:"tools.registryUnavailable",severity:"warning",path:"tools",message:'No tool registry was supplied, so tool ids, placement levels and provider config were not validated, and a coordinator without one registers no tool providers. Pass `toolRegistry` to the coordinator or the toolkit it is bound to — for the packaged capability set, `createPackagedToolRegistry()` from "@pie-players/pie-default-tool-loaders".'}));let j={...Y.providers||{}};for(let U of Object.keys(j).sort()){let q=J.get(U);j[U]=P6(U,j[U],q,X),R6(U,j[U],q,X)}let B={...Y,providers:j};return E6(B,J,X),C6(B,J,X),b6(B,J,X),{config:B,diagnostics:X}}function z1(Z,Q={}){let J=D1(Q.strictness),Y=Q.source??"tools";if(J==="warn")r8(Z,Y);let X=Z.filter((G)=>G.severity==="error");if(J==="error"&&X.length>0)S6(X,Y);if(J==="error"&&X.length===0)r8(Z,Y)}import{languageTagLookupSequence as f6,normalizeLanguageTag as ZZ}from"@pie-players/pie-players-shared/i18n/language-tags";var M1=new Set(["speak","break","prosody","emphasis","say-as","sub","mark","phoneme","lang","p","s","voice","audio","lexicon"]),a8=new Set(["script","style","iframe","object","embed","foreignobject","noscript","template"]),t8=new Set(["alphabet","ph","time","strength","rate","pitch","volume","name","interpret-as","format","detail","language","xml:lang","lang","gender","src"]),e8=new Set(["break","mark","lexicon"]);function T6(Z){let Q=Z;for(let J of e8){let Y=new RegExp(`<${J}\\b([^>/]*?)\\s*/>`,"gi");Q=Q.replace(Y,(X,G)=>{let j=G?G.replace(/\s+$/,""):"";return`<${J}${j}></${J}>`})}return Q}var y6=[/^localhost$/i,/^127(?:\.\d{1,3}){3}$/,/^0(?:\.\d{1,3}){3}$/,/^10(?:\.\d{1,3}){3}$/,/^192\.168(?:\.\d{1,3}){2}$/,/^172\.(?:1[6-9]|2\d|3[01])(?:\.\d{1,3}){2}$/,/^169\.254(?:\.\d{1,3}){2}$/,/^::1$/,/^fe80:/i,/^fc00:/i,/^fd[0-9a-f]{2}:/i,/^metadata\.google\.internal$/i,/^metadata\.azure\.internal$/i,/^metadata\.packet\.net$/i];function x6(Z){if(typeof Z!=="string"||Z.length===0)return!1;let Q;try{Q=new URL(Z)}catch{return!1}if(Q.protocol!=="http:"&&Q.protocol!=="https:")return!1;let J=Q.hostname.replace(/^\[|\]$/g,"").replace(/\.$/,"");return!y6.some((Y)=>Y.test(J))}function H1(Z){let Q=Array.from(Z.children);for(let Y of Q){let X=Y.tagName.toLowerCase();if(a8.has(X)){Y.remove();continue}if(H1(Y),!M1.has(X)){let G=Z.ownerDocument.createTextNode(Y.textContent??"");Y.replaceWith(G)}}let J=Array.from(Z.attributes).map((Y)=>Y.name);for(let Y of J)if(!t8.has(Y.toLowerCase()))Z.removeAttribute(Y);if(Z.tagName.toLowerCase()==="audio"){let Y=Z.getAttribute("src");if(Y!==null&&!x6(Y))Z.removeAttribute("src")}}function _1(Z){let Q=Z.tagName.toLowerCase(),J=Array.from(Z.attributes).filter((X)=>t8.has(X.name.toLowerCase())).map((X)=>` ${X.name}="${k6(X.value)}"`).join("");if(e8.has(Q))return`<${Q}${J}/>`;let Y=[];for(let X of Array.from(Z.childNodes))if(X.nodeType===3)Y.push(C0(X.nodeValue??""));else if(X.nodeType===1){let G=X,j=G.tagName.toLowerCase();if(a8.has(j))continue;if(M1.has(j))Y.push(_1(G));else Y.push(C0(G.textContent??""))}return`<${Q}${J}>${Y.join("")}</${Q}>`}function L1(Z){let Q=String(Z||"").trim();if(!Q||!Q.includes("<"))return Z;if(typeof DOMParser>"u")return Z;let Y=new DOMParser().parseFromString(T6(Q),"text/html"),X=Y.querySelector("speak");if(X)return H1(X),_1(X);let G=Y.createElement("speak");for(let j of Array.from(Y.body.childNodes))G.appendChild(j);return H1(G),Array.from(G.childNodes).map((j)=>{if(j.nodeType===3)return C0(j.nodeValue??"");if(j.nodeType===1){let B=j;if(M1.has(B.tagName.toLowerCase()))return _1(B);return C0(B.textContent??"")}return""}).join("")}function C0(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function k6(Z){return Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}var BZ=new Set(["spoken","sign-language","transcript","braille","tactile","simplified-language","audio-description","extended-description"]),O1="ext:";function QZ(Z){if(BZ.has(Z))return!0;return Z.startsWith(O1)&&Z.length>O1.length}var JZ=new Set;function N1(Z,Q=new Set){if(Z===null||typeof Z==="string"||typeof Z==="number"||typeof Z==="boolean"||typeof Z>"u")return Z;if(typeof Z!=="object")throw TypeError("catalog cards must contain JSON-compatible values");if(Q.has(Z))throw TypeError("catalog cards must not contain cycles");Q.add(Z);try{if(Array.isArray(Z))return Object.freeze(Z.map((X)=>N1(X,Q)));let J=Object.getPrototypeOf(Z);if(J!==Object.prototype&&J!==null)throw TypeError("catalog cards must contain only plain objects and arrays");let Y={};for(let[X,G]of Object.entries(Z))Y[X]=N1(G,Q);return Object.freeze(Y)}finally{Q.delete(Z)}}function YZ(Z,Q,J){let Y=`${Q}|${Z}`;if(JZ.has(Y))return;JZ.add(Y);let X=`${Array.from(BZ).join(", ")}, or an "${O1}" prefixed vendor extension`;if(Q==="card"){console.warn(`[AccessibilityCatalogResolver] catalog "${J}" has a card of unknown type "${Z}"; it is stored but no reader asks for that type, so the alternate will never be shown. Expected one of: ${X}.`);return}console.warn(`[AccessibilityCatalogResolver] lookup for unknown catalog type "${Z}" on "${J}" cannot match any card. Expected one of: ${X}.`)}var XZ=(Z)=>Z.payload!==void 0?"payload":"content";class w1{assessmentCatalogs=new Map;itemCatalogs=new Map;scopedCatalogs=new Map;defaultLanguage="en-US";sanitizedSpokenCache=new Map;catalogChangeListeners=new Set;reportedSnapshotProblems=new Set;constructor(Z,Q="en-US"){this.defaultLanguage=Q,this.indexCatalogs(Z??[],"assessment")}setDefaultLanguage(Z){this.defaultLanguage=Z}onCatalogsChange(Z){return this.catalogChangeListeners.add(Z),()=>{this.catalogChangeListeners.delete(Z)}}emitCatalogsChange(Z){for(let Q of Array.from(this.catalogChangeListeners))try{Q(Z)}catch{}}getDefaultLanguage(){return this.defaultLanguage}indexCatalogs(Z,Q){let J=Q==="assessment"?this.assessmentCatalogs:this.itemCatalogs;for(let Y of this.sanitizeCatalogs(Z)){if(J.has(Y.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate ${Q} catalog "${Y.identifier}" ignored`);continue}J.set(Y.identifier,Y)}}insertScopedCatalogs(Z,Q){if(!Q||Q.length===0)return null;let J=this.getOwnerKey(Z),Y=this.scopedCatalogs.get(J),X=Y?.catalogs??new Map,G=[];for(let j of this.sanitizeCatalogs(Q)){if(X.has(j.identifier)){console.warn(`[AccessibilityCatalogResolver] Duplicate scoped catalog "${j.identifier}" ignored for ${J}`);continue}X.set(j.identifier,j),G.push(j.identifier)}if(!Y&&G.length>0)this.scopedCatalogs.set(J,{context:{...Z},catalogs:X});return{key:J,context:{...Z},catalogs:X,insertedIds:G}}removeScopedInsertion(Z){let Q=this.scopedCatalogs.get(Z.key);if(Q?.catalogs!==Z.catalogs)return!1;let J=!1;for(let Y of Z.insertedIds)J=Q.catalogs.delete(Y)||J;if(Q.catalogs.size===0)this.scopedCatalogs.delete(Z.key);return J}registerCatalogs(Z,Q){let J=this.insertScopedCatalogs(Z,Q);if(J&&J.insertedIds.length>0)this.emitCatalogsChange({reason:"scoped-registered",context:Z});let Y=!0;return()=>{if(!Y)return;if(Y=!1,J&&this.removeScopedInsertion(J))this.emitCatalogsChange({reason:"scoped-removed",context:Z})}}registerOwner(Z){let{owner:Q,entity:J}=Z,Y=GZ(Q),X=[],G=[];try{G=jZ(J,Q)}catch(U){console.warn("[AccessibilityCatalogResolver] A mounted content owner could not be traversed for catalogs; the primary content remains available.",U)}for(let U of G)try{let q=this.insertScopedCatalogs(U.context,U.catalogs);if(q)X.push(q)}catch(q){console.warn("[AccessibilityCatalogResolver] Invalid catalogs on a mounted content owner were ignored; the primary content and other valid catalogs remain available.",q)}if(X.some((U)=>U.insertedIds.length>0))this.emitCatalogsChange({reason:"scoped-registered",context:Y});let B=!0;return()=>{if(!B)return;B=!1;let U=!1;for(let q of X)U=this.removeScopedInsertion(q)||U;if(U)this.emitCatalogsChange({reason:"scoped-removed",context:Y})}}forOwner(Z){let Q={...Z};return Object.freeze({snapshot:()=>this.createOwnerSnapshot(Q),onChange:(J)=>this.onCatalogsChange((Y)=>{if(this.catalogChangeAffectsOwner(Y,Q))J()})})}addItemCatalogs(Z){if(!Z||Z.length===0)return;this.indexCatalogs(Z,"item"),this.emitCatalogsChange({reason:"item-added"})}clearItemCatalogs(){if(this.itemCatalogs.size===0)return;this.itemCatalogs.clear(),this.emitCatalogsChange({reason:"item-cleared"})}hasCatalog(Z){return this.itemCatalogs.has(Z)||this.assessmentCatalogs.has(Z)||Array.from(this.scopedCatalogs.values()).some((Q)=>Q.catalogs.has(Z))}getAlternative(Z,Q){if(!QZ(Q.type))YZ(Q.type,"lookup",Z);let J=Q.context?this.scopedCatalogs.get(this.getOwnerKey(Q.context))?.catalogs.get(Z):null;if(J){let G=this.findMatchingCard(J,Q);if(G)return this.resolveCard(Z,G,"item")}if(Q.context){let G=this.findScopedCandidates(Z,Q.context);if(G.length===1){let j=this.findMatchingCard(G[0],Q);if(j)return this.resolveCard(Z,j,"item")}else if(G.length>1)return console.warn(`[AccessibilityCatalogResolver] Ambiguous scoped catalog "${Z}" for owner context`,Q.context),null}let Y=this.itemCatalogs.get(Z);if(Y){let G=this.findMatchingCard(Y,Q);if(G)return this.resolveCard(Z,G,"item")}let X=this.assessmentCatalogs.get(Z);if(X){let G=this.findMatchingCard(X,Q);if(G)return this.resolveCard(Z,G,"assessment")}return null}resolveCard(Z,Q,J){return{catalogId:Z,type:Q.catalog,language:Q.language,content:Q.catalog==="spoken"&&Q.content!==void 0?this.ensureSpokenSanitized(Q.content):Q.content,payload:Q.payload,source:J}}ensureSpokenSanitized(Z){let Q=this.sanitizedSpokenCache.get(Z);if(Q!==void 0)return Q;let J=L1(Z);return this.sanitizedSpokenCache.set(Z,J),J}getOwnerKey(Z){return[Z.ownerKind,Z.assessmentId||"",Z.sectionId||"",Z.canonicalItemId||"",Z.itemId||"",Z.passageId||"",Z.modelId||""].join("|")}scopedCatalogEntries(){let Z=[];for(let Q of this.scopedCatalogs.values())for(let J of Q.catalogs.entries())Z.push(J);return Z}findScopedCandidates(Z,Q){return Array.from(this.scopedCatalogs.values()).filter((J)=>this.isCompatibleOwnerContext(J.context,Q)).map((J)=>J.catalogs.get(Z)).filter((J)=>Boolean(J))}isCompatibleOwnerContext(Z,Q){if(Z.ownerKind!==Q.ownerKind)return!1;if(Q.assessmentId&&Z.assessmentId!==Q.assessmentId)return!1;if(Q.sectionId&&Z.sectionId!==Q.sectionId)return!1;if(Q.canonicalItemId&&Z.canonicalItemId!==Q.canonicalItemId)return!1;if(Q.itemId&&Z.itemId!==Q.itemId)return!1;if(Q.passageId&&Z.passageId!==Q.passageId)return!1;if(Q.modelId&&Z.modelId!==Q.modelId)return!1;return!0}ownerScopedCatalogEntries(Z){let Q=[],J=this.scopedCatalogs.get(this.getOwnerKey(Z));if(J)Q.push(...J.catalogs.entries());for(let Y of this.scopedCatalogs.values()){if(Y===J)continue;if(!this.isCompatibleOwnerContext(Y.context,Z))continue;Q.push(...Y.catalogs.entries())}return Q}createOwnerSnapshot(Z){let Q=[],J=this.ownerScopedCatalogEntries(Z);if(Z.ownerKind==="global")J.push(...this.assessmentCatalogs.entries());for(let[Y,X]of J)for(let G of X.cards)try{Q.push(Object.freeze({catalogId:Y,card:N1(G)}))}catch(j){let B=`${this.getOwnerKey(Z)}\x00${Y}`;if(!this.reportedSnapshotProblems.has(B))this.reportedSnapshotProblems.add(B),console.warn(`[AccessibilityCatalogResolver] Catalog "${Y}" contains a card that cannot be exposed in an owner snapshot; that card was ignored.`,j)}return Object.freeze({cards:Object.freeze(Q)})}catalogChangeAffectsOwner(Z,Q){if(!Z.context)return!1;if(this.isCompatibleOwnerContext(Z.context,Q))return!0;if(Q.ownerKind==="itemModel"&&Q.modelId&&Z.context.ownerKind==="itemModel"&&!Z.context.modelId)return this.isCompatibleOwnerContext({...Z.context,modelId:Q.modelId},Q);return!1}sanitizeCatalogs(Z){return Z.map((Q)=>({...Q,cards:Q.cards.map((J)=>{if(!QZ(J.catalog))YZ(J.catalog,"card",Q.identifier);return{...J,content:J.catalog==="spoken"&&J.content!==void 0?L1(J.content):J.content}})}))}findMatchingCard(Z,Q){let{type:J,language:Y,useFallback:X=!0,form:G}=Q,j=[],B=(U)=>{for(let q of f6(U))j.push((K)=>ZZ(K.language)===q)};if(Y)B(Y);if(X)B(this.defaultLanguage),j.push(()=>!0);for(let U of j){let q=Z.cards.filter((K)=>K.catalog===J&&U(K));if(q.length===0)continue;if(G){let K=q.find(($)=>XZ($)===G);if(K)return K}return q[0]}return null}getAllAlternatives(Z){let Q=[],J=new Set,Y=(j,B)=>{let U=`${j.catalog}|${ZZ(j.language)}|${XZ(j)}`;if(J.has(U))return;J.add(U),Q.push(this.resolveCard(Z,j,B))},X=this.itemCatalogs.get(Z);if(X)for(let j of X.cards)Y(j,"item");let G=this.assessmentCatalogs.get(Z);if(G)for(let j of G.cards)Y(j,"assessment");for(let[j,B]of this.scopedCatalogEntries()){if(j!==Z)continue;for(let U of B.cards)Y(U,"item")}return Q}getAllCatalogIds(){let Z=this.scopedCatalogEntries().map(([Q])=>Q);return Array.from(new Set([...this.itemCatalogs.keys(),...this.assessmentCatalogs.keys(),...Z]))}getStatistics(){let Z=new Set,Q=new Set;for(let J of this.assessmentCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.itemCatalogs.values())for(let Y of J.cards)if(Z.add(Y.catalog),Y.language)Q.add(Y.language);for(let J of this.scopedCatalogs.values())for(let Y of J.catalogs.values())for(let X of Y.cards)if(Z.add(X.catalog),X.language)Q.add(X.language);return{totalCatalogs:this.assessmentCatalogs.size+this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),assessmentCatalogs:this.assessmentCatalogs.size,itemCatalogs:this.itemCatalogs.size+Array.from(this.scopedCatalogs.values()).reduce((J,Y)=>J+Y.catalogs.size,0),availableTypes:Z,availableLanguages:Q}}hasAlternativeType(Z,Q){return this.getAllAlternatives(Z).some((Y)=>Y.type===Q)}getCatalogsByType(Z){let Q=new Set;for(let[J,Y]of this.assessmentCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.itemCatalogs.entries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);for(let[J,Y]of this.scopedCatalogEntries())if(Y.cards.some((X)=>X.catalog===Z))Q.add(J);return Array.from(Q)}reset(){this.assessmentCatalogs.clear(),this.itemCatalogs.clear(),this.scopedCatalogs.clear(),this.sanitizedSpokenCache.clear(),this.reportedSnapshotProblems.clear()}destroy(){this.reset()}}function P1(Z){return Z.replace(/%/g,"%25").replace(/:/g,"%3A")}function I6(Z){return Z.replace(/%(25|3A)/g,(Q,J)=>J==="25"?"%":":")}class R1{elementStates=new Map;listeners=new Set;onStateChange=null;getGlobalElementId(Z,Q,J,Y){return[Z,Q,J,Y].map(P1).join(":")}parseGlobalElementId(Z){let Q=Z.split(":");if(Q.length!==4)return null;let[J,Y,X,G]=Q.map(I6);return{assessmentId:J,sectionId:Y,itemId:X,elementId:G}}setState(Z,Q,J){let Y=this.elementStates.get(Z);if(!Y)Y=new Map,this.elementStates.set(Z,Y);Y.set(Q,J),this._notifyListeners(),this._notifyStateChange()}getState(Z,Q){return this.elementStates.get(Z)?.get(Q)}getElementState(Z){let Q=this.elementStates.get(Z);if(!Q)return{};return Object.fromEntries(Q.entries())}getAllState(){let Z={};for(let[Q,J]of this.elementStates.entries())Z[Q]=Object.fromEntries(J.entries());return Z}subscribe(Z){return this.listeners.add(Z),()=>this.listeners.delete(Z)}_notifyListeners(){if(this.listeners.size===0)return;let Z=new Map([...this.elementStates].map(([Q,J])=>[Q,new Map(J)]));for(let Q of this.listeners)try{Q(Z)}catch(J){console.warn("[ElementToolStateStore] listener failed:",J)}}setOnStateChange(Z){this.onStateChange=Z}_notifyStateChange(){if(!this.onStateChange)return;try{this.onStateChange(this.getAllState())}catch(Z){console.warn("[ElementToolStateStore] state-change callback failed:",Z)}}loadState(Z){this.elementStates.clear();for(let[Q,J]of Object.entries(Z)){let Y=new Map(Object.entries(J));this.elementStates.set(Q,Y)}this._notifyListeners()}clearElement(Z){this.elementStates.delete(Z),this._notifyListeners(),this._notifyStateChange()}clearTool(Z){for(let Q of this.elementStates.values())Q.delete(Z);this._notifyListeners(),this._notifyStateChange()}clearSection(Z,Q){let J=`${P1(Z)}:${P1(Q)}:`,Y=[];for(let X of this.elementStates.keys())if(X.startsWith(J))Y.push(X);for(let X of Y)this.elementStates.delete(X);this._notifyListeners(),this._notifyStateChange()}clearAll(){this.elementStates.clear(),this._notifyListeners(),this._notifyStateChange()}}class B0{listeners=new Set;subscribeFrameworkErrors(Z){this.listeners.add(Z);let Q=!0;return()=>{if(!Q)return;Q=!1,this.listeners.delete(Z)}}reportFrameworkError(Z){let Q=Array.from(this.listeners);for(let J of Q)try{J(Z)}catch(Y){console.warn("[FrameworkErrorBus] listener failed:",Y)}}dispose(){this.listeners.clear()}getListenerCount(){return this.listeners.size}}var v6=new Set(["pie-item-toolbar","pie-section-toolbar","pie-item-player-session-debugger"]),h6=["pie-tool-","pie-section-player-tools-"],m6=new Set(["style","script","noscript","template"]),m=(Z)=>!!Z&&Z.nodeType===11&&Z.host?.nodeType===1,u6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(v6.has(Q))return!0;return h6.some((J)=>Q.startsWith(J))},p6=(Z)=>{let Q=Z.localName?.toLowerCase()||"";if(m6.has(Q))return!0;if(u6(Z))return!0;return m(Z.parentNode)&&Z.getAttribute("aria-hidden")==="true"},g6=(Z)=>{if(!m(Z.getRootNode?.()))return null;let Q=Z.assignedNodes;if(typeof Q!=="function")return null;try{return Q.call(Z,{flatten:!0})}catch{return null}},$9=(Z)=>{let Q=Z.childNodes;if(Z.nodeType===1){let Y=Z,X=Y.shadowRoot;if(X)Q=X.childNodes;else if(Y.localName?.toLowerCase()==="slot")Q=g6(Y)??Y.childNodes}let J=[];for(let Y of Array.from(Q||[])){if(Y.nodeType===1&&p6(Y))continue;J.push(Y)}return J},W0=(Z,Q)=>{let J=(Y)=>{for(let X of $9(Y)){let G=Q(X);if(G==="stop")return!1;if(G==="skip")continue;if(!J(X))return!1}return!0};J(Z)},R9=(Z)=>{let Q=[];return W0(Z,(J)=>{if(J.nodeType===3)Q.push(J);return}),Q},UZ=(Z)=>R9(Z).map((Q)=>Q.data).join(""),KZ=(Z,Q)=>{let J=[];return W0(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))J.push(Y);return}),J},E9=(Z,Q)=>{let J=null;return W0(Z,(Y)=>{if(Y.nodeType===1&&Y.matches(Q))return J=Y,"stop";return}),J},WZ=(Z)=>{let Q=Z.assignedSlot;if(Q)return Q;let J=Z.parentNode;if(m(J))return J.host;return J},c=(Z)=>{let Q=WZ(Z);while(Q&&Q.nodeType!==1)Q=WZ(Q);return Q},E1=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(J.matches(Q))return J;J=c(J)}return null},d=(Z)=>{if(Z.parentElement)return Z.parentElement;let Q=Z.parentNode;return m(Q)?Q.host:null},b0=(Z,Q,J)=>{let Y=Z.nodeType===1?Z:d(Z);while(Y){if(Y.matches(Q))return Y;if(J&&Y===J)return null;Y=d(Y)}return null},t=(Z,Q)=>{if(!Z||!Q)return!1;let J=Q;while(J){if(J===Z||Z.contains(J))return!0;let Y=J.getRootNode?.();J=m(Y)?Y.host:null}return!1},VZ=(Z,Q)=>{let J=Z;while(J){let Y=J.getRootNode?.();if(Y===Q)return J;J=m(Y)?Y.host:null}return null},U0=(Z,Q,J)=>{try{let Y=Z.startContainer.getRootNode?.();if(!Y||Q.getRootNode?.()===Y)return Z.comparePoint(Q,J)===0&&Z.comparePoint(Q,Math.min(J+1,Q.length))===0;return qZ(Z,VZ(Q,Y))}catch{return!1}},X9=(Z,Q)=>{try{let J=Z.startContainer.getRootNode?.();if(!J||Q.getRootNode?.()===J)return Z.intersectsNode(Q);return qZ(Z,VZ(Q,J))}catch{return!1}},qZ=(Z,Q)=>{let J=Q?.parentNode;if(!Q||!J)return!1;let Y=Array.prototype.indexOf.call(J.childNodes,Q);if(Y<0)return!1;return Z.comparePoint(J,Y)===0&&Z.comparePoint(J,Y+1)===0};var C1=" >>> ";class b1{serialize(Z,Q){return{startContainer:this.getNodePath(Z.startContainer,Q),startOffset:Z.startOffset,endContainer:this.getNodePath(Z.endContainer,Q),endOffset:Z.endOffset,text:Z.toString()}}deserialize(Z,Q){let J=this.findNodeByPath(Z.startContainer,Q),Y=this.findNodeByPath(Z.endContainer,Q);if(!J||!Y)return null;try{let X=new Range;if(X.setStart(J,Z.startOffset),X.setEnd(Y,Z.endOffset),X.toString()===Z.text)return X;return null}catch(X){return console.warn("Failed to deserialize range:",X),null}}getNodePath(Z,Q){if(Z===Q)return"";if(Z.nodeType===Node.TEXT_NODE){let J=Z.parentNode;if(!J)throw Error("Text node has no parent");let X=Array.from(J.childNodes).filter((j)=>j.nodeType===Node.TEXT_NODE).indexOf(Z);return`${m(J)?this.getShadowRootPath(J,Q):this.getElementPath(J,Q)}::text[${X}]`}if(Z.nodeType===Node.ELEMENT_NODE)return this.getElementPath(Z,Q);if(m(Z))return this.getShadowRootPath(Z,Q);throw Error(`Unsupported node type: ${Z.nodeType}`)}getElementPath(Z,Q){if(Z===Q)return"";let J=Q.getRootNode?.(),Y=[],X=[],G=Z,j=(B)=>{Y.unshift(X.join(" > ")),X=[],G=B.host};while(G&&G!==Q){if(G.id){X.unshift(`#${G.id}`);let M=G.getRootNode?.();if(m(M)&&M!==J){j(M);continue}break}let{parentElement:B,parentNode:U}=G,q=B??(m(U)?U:null);if(!q)break;let K=G.tagName,$=Array.from(q.children).filter((M)=>M.tagName===K),D=$.indexOf(G),z=$.length>1?`${K.toLowerCase()}:nth-of-type(${D+1})`:K.toLowerCase();if(X.unshift(z),B)G=B;else j(q)}return Y.unshift(X.join(" > ")),Y.join(C1)}getShadowRootPath(Z,Q){return`${this.getElementPath(Z.host,Q)}${C1}`}resolveElementPath(Z,Q){let J=Q,Y=Z.split(C1);for(let X=0;X<Y.length;X++){if(X>0){let B=m(J)?null:J.shadowRoot;if(!B)return null;J=B}let G=Y[X].trim();if(!G)continue;let j=J.querySelector(G);if(!j)return null;J=j}return J}findNodeByPath(Z,Q){if(Z==="")return Q;if(Z.includes("::text[")){let J=Z.lastIndexOf("::text["),Y=Z.slice(0,J),X=Z.slice(J+7),G=Number.parseInt(X.replace("]",""),10),j;try{j=this.resolveElementPath(Y,Q)}catch(U){return console.warn("Invalid selector path:",Z,U),null}if(!j)return null;return Array.from(j.childNodes).filter((U)=>U.nodeType===Node.TEXT_NODE)[G]||null}try{return this.resolveElementPath(Z,Q)}catch(J){return console.warn("Invalid selector path:",Z,J),null}}serializeMany(Z,Q){return Z.map((J)=>this.serialize(J,Q))}deserializeMany(Z,Q){return Z.map((J)=>this.deserialize(J,Q))}}var i;(function(Z){Z.TTS_WORD="tts-word",Z.TTS_SENTENCE="tts-sentence",Z.ANNOTATION="annotation"})(i||(i={}));var q0;(function(Z){Z.YELLOW="yellow",Z.GREEN="green",Z.BLUE="blue",Z.PINK="pink",Z.ORANGE="orange",Z.UNDERLINE="underline"})(q0||(q0={}));var zZ=`
|
|
6
6
|
/* TTS highlights - temporary */
|
|
7
7
|
::highlight(tts-word) {
|
|
8
8
|
background-color: var(--pie-tts-word-highlight, color-mix(in srgb, var(--pie-missing, #ffeb3b) 68%, transparent));
|
|
@@ -212,14 +212,14 @@ ${J}`)}function A0(Q,Y={}){let J=d1(Q,Y.toolRegistry);return l1(J.diagnostics,Y)
|
|
|
212
212
|
text-shadow: none;
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
`,document.head.appendChild(Q)}highlightTTSWord(Q,Y,J){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(Q.parentElement),this.clearTTSWord();let G=document.createRange();G.setStart(Q,Y),G.setEnd(Q,J),this.ttsWordHighlight.add(G)}highlightTTSWordElement(Q){if(!this.ttsWordHighlight)return;this.applyAdaptiveTTSStyle(Q),this.clearTTSWord(),Q.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Q)}highlightTTSSentence(Q){if(!this.ttsSentenceHighlight)return;let Y=Q[0]?.startContainer,J=Y?.nodeType===Node.ELEMENT_NODE?Y:Y?.parentElement;this.applyAdaptiveTTSStyle(J),this.clearTTSSentence();for(let G of Q)this.ttsSentenceHighlight.add(G);this.highlightTTSElementFallbacks(Q)}highlightTTSSentenceElements(Q){if(!this.ttsSentenceHighlight)return;this.applyAdaptiveTTSStyle(Q[0]||null),this.clearTTSSentence();for(let Y of Q)Y.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(Y)}static SENTENCE_FALLBACK_SELECTOR="math, mjx-container, svg, img, canvas, [role='img']";static WORD_FALLBACK_SELECTOR="svg, img, canvas, [role='img']";highlightTTSElementFallbacks(Q){if(typeof Element>"u")return;this.highlightElementFallbacks(Q,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,p7.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Q){if(typeof Element>"u")return;this.highlightElementFallbacks(Q,"data-pie-tts-word-element",this.ttsWordElementHighlights,p7.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Q,Y,J,G){for(let X of Q){let j=X.commonAncestorContainer.nodeType===Node.ELEMENT_NODE?X.commonAncestorContainer:X.commonAncestorContainer.parentElement;if(!j)continue;let Z=[],B=X.startContainer.nodeType===Node.ELEMENT_NODE?X.startContainer:X.startContainer.parentElement,W=X.endContainer.nodeType===Node.ELEMENT_NODE?X.endContainer:X.endContainer.parentElement;for(let K of[B,W]){let U=K;while(U){if(U.matches?.(G))Z.push(U);U=U.parentElement}}if(j.matches?.(G))Z.push(j);Z.push(...Array.from(j.querySelectorAll(G)));for(let K of new Set(Z)){try{if(!X.intersectsNode(K)&&!K.contains(B)&&!K.contains(W))continue}catch{continue}K.setAttribute(Y,"true"),J.add(K)}}}clearTTSWord(){if(!this.ttsWordHighlight)return;this.ttsWordHighlight.clear();for(let Q of this.ttsWordElementHighlights)Q.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.ttsSentenceHighlight)return;this.ttsSentenceHighlight.clear();for(let Q of this.ttsSentenceElementHighlights)Q.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){this.clearTTSWord(),this.clearTTSSentence()}addAnnotation(Q,Y=_7.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,G=Q.cloneRange(),X={id:J,range:G,type:u.ANNOTATION,color:Y,timestamp:Date.now()};this.annotations.set(J,X);let j=this.colorHighlights.get(Y);if(j)j.add(G);return J}removeAnnotation(Q){let Y=this.annotations.get(Q);if(!Y){console.warn(`[HighlightCoordinator] Annotation ${Q} not found`);return}console.log(`[HighlightCoordinator] Removing annotation ${Q} (color: ${Y.color})`);let J=this.colorHighlights.get(Y.color);if(J){let G=J.delete(Y.range);console.log("[HighlightCoordinator] Highlight.delete() returned:",G)}this.annotations.delete(Q),console.log(`[HighlightCoordinator] Annotation ${Q} removed from map. Remaining:`,this.annotations.size)}clearAnnotations(){for(let Q of this.colorHighlights.values())Q.clear();this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(Q){return this.annotations.get(Q)??null}changeAnnotationColor(Q,Y){let J=this.annotations.get(Q);if(!J)return;let G=J.color;if(G===Y)return;let X=this.colorHighlights.get(G);if(X)X.delete(J.range);J.color=Y;let j=this.colorHighlights.get(Y);if(j)j.add(J.range)}exportAnnotations(Q=document.body){return this.getAnnotations().map((Y)=>({...this.rangeSerializer.serialize(Y.range,Q),id:Y.id,color:Y.color,timestamp:Y.timestamp}))}importAnnotations(Q,Y=document.body){let J=0;for(let G of Q){let X=this.rangeSerializer.deserialize(G,Y);if(X)this.addAnnotation(X,G.color),J++}return J}highlightRange(Q,Y,J=_7.YELLOW){if(!this.supported)return;switch(Y){case u.TTS_WORD:case u.TTS_SENTENCE:{let G=Y===u.TTS_WORD?this.ttsWordHighlight:this.ttsSentenceHighlight;if(G){if(G.clear(),G.add(Q),Y===u.TTS_WORD){for(let X of this.ttsWordElementHighlights)X.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear(),this.highlightTTSWordElementFallbacks([Q])}}break}case u.ANNOTATION:this.addAnnotation(Q,J);break}}clearHighlights(Q){if(!this.supported)return;switch(Q){case u.TTS_WORD:this.clearTTSWord();break;case u.TTS_SENTENCE:this.clearTTSSentence();break;case u.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}updateTTSHighlightStyle(Q,Y){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((j)=>{let Z=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(j);return Z?{r:parseInt(Z[1],16),g:parseInt(Z[2],16),b:parseInt(Z[3],16)}:null})(Q);if(!X)return;this.explicitTTSColorOverride={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Y))},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations(),this.themeObserver?.disconnect(),this.themeObserver=null}}function L0(Q){return(...Y)=>{console.debug(`[${Q}]`,...Y)}}var a=L0("ToolCoordinator"),Z7;(function(Q){Q[Q.BASE=0]="BASE",Q[Q.TOOL=1000]="TOOL",Q[Q.MODAL=2000]="MODAL",Q[Q.CONTROL=3000]="CONTROL",Q[Q.HIGHLIGHT=4000]="HIGHLIGHT"})(Z7||(Z7={}));class G9{tools=new Map;layerCounters=new Map;listeners=new Set;visibilityState=new Map;constructor(){this.layerCounters.set(Z7.BASE,0),this.layerCounters.set(Z7.TOOL,0),this.layerCounters.set(Z7.MODAL,0),this.layerCounters.set(Z7.CONTROL,0),this.layerCounters.set(Z7.HIGHLIGHT,0)}subscribe(Q){return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}notifyListeners(){this.listeners.forEach((Q)=>Q())}registerTool(Q,Y,J,G=Z7.MODAL){if(a("registerTool called:",{id:Q,name:Y,hasElement:!!J,layer:G}),this.tools.has(Q)){a(`Tool ${Q} is already registered`);return}let X=this.visibilityState.get(Q)??!1;if(!J){this.tools.set(Q,{id:Q,name:Y,element:null,layer:G,isVisible:X,baseZIndex:G}),a("Tool registered without element:",Q);return}let j=G+this.getNextLayerOffset(G);J.style.zIndex=String(j),J.style.display=X?"":"none";let Z=()=>this.bringToFront(J);if(J.addEventListener("mousedown",Z),this.tools.set(Q,{id:Q,name:Y,element:J,layer:G,isVisible:X,baseZIndex:j,mouseDownHandler:Z}),X)this.bringToFront(J);a("Tool registered with element:",Q)}unregisterTool(Q){let Y=this.tools.get(Q);if(!Y)return;if(Y.element&&Y.mouseDownHandler)Y.element.removeEventListener("mousedown",Y.mouseDownHandler);this.tools.delete(Q)}releaseTool(Q){this.unregisterTool(Q),this.visibilityState.delete(Q)}showTool(Q){let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found`);return}if(Y.element)Y.element.style.display="",this.bringToFront(Y.element);Y.isVisible=!0,this.visibilityState.set(Q,!0),this.notifyListeners()}hideTool(Q){let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found`);return}if(Y.element)Y.element.style.display="none";Y.isVisible=!1,this.visibilityState.set(Q,!1),this.notifyListeners()}toggleTool(Q){a("toggleTool called for:",Q);let Y=this.tools.get(Q);if(!Y){a(`Tool ${Q} not found. Registered tools:`,Array.from(this.tools.keys()));return}if(a("Tool found, current visibility:",Y.isVisible),Y.isVisible)this.hideTool(Q);else this.showTool(Q)}isToolVisible(Q){let Y=this.tools.get(Q);if(Y)return Y.isVisible;return this.visibilityState.get(Q)??!1}bringToFront(Q){let Y=Array.from(this.tools.values()).find((X)=>X.element===Q);if(!Y)return;let J=this.getMaxZIndexInLayer(Y.layer),G=Math.max(J+1,Y.layer+1);Q.style.zIndex=String(G),Y.baseZIndex=G}getRegisteredTools(){return Array.from(this.tools.keys())}getToolElement(Q){return this.tools.get(Q)?.element??null}getNextLayerOffset(Q){let Y=this.layerCounters.get(Q)??0;return this.layerCounters.set(Q,Y+1),Y}getMaxZIndexInLayer(Q){let Y=Q;for(let J of this.tools.values())if(J.layer===Q)Y=Math.max(Y,J.baseZIndex);return Y}resetZIndices(){for(let Q of this.tools.values())if(Q.element)Q.element.style.zIndex=String(Q.baseZIndex)}updateToolElement(Q,Y){let J=this.tools.get(Q);if(!J){a(`Tool ${Q} not found`);return}if(J.element&&J.mouseDownHandler)J.element.removeEventListener("mousedown",J.mouseDownHandler);let G=()=>this.bringToFront(Y);if(Y.addEventListener("mousedown",G),J.element=Y,J.mouseDownHandler=G,Y.style.zIndex=String(J.baseZIndex),J.isVisible)Y.style.display="";else Y.style.display="none"}hideAllTools(){for(let Q of this.tools.keys())this.hideTool(Q);this.notifyListeners()}getToolState(Q){let Y=this.tools.get(Q);if(!Y)return;return{id:Y.id,name:Y.name,isVisible:Y.isVisible,element:Y.element??null,layer:Y.layer}}getVisibleTools(){return Array.from(this.tools.values()).filter((Q)=>Q.isVisible).map((Q)=>({id:Q.id,name:Q.name,isVisible:Q.isVisible,element:Q.element??null,layer:Q.layer}))}}import{applyMediaFragment as q2,enforceMediaFragment as W2}from"@pie-players/pie-players-shared/media";import{isUnsupportedMediaAssetVersion as b3,normalizeMediaFragment as S3,normalizeMediaSources as C3,trimmedOrUndefined as T3}from"@pie-players/pie-players-shared/media";function w0(Q){if(!Q)return null;let Y=Q.payload;if(!Y||typeof Y!=="object")return null;let J=Y.media;if(!J||typeof J!=="object")return console.warn("[spoken-audio] card carries a `payload` with no `media`; recorded speech needs `media.sources`, so this card is ignored and read-aloud falls back to the script or generated speech"),null;if(b3(J.version))return console.warn(`[spoken-audio] card's media declares version ${String(J.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(J.kind!==void 0&&J.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${J.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let G=C3(J.sources);if(G.length===0)return console.warn("[spoken-audio] card's `media.sources` yielded no usable URL; read-aloud falls back to the script or generated speech"),null;return{sources:G,fragment:S3(Y.fragment),label:T3(J.label)}}var S7=(Q,Y)=>{let J=Y?.useSentenceSegmenter!==!1;try{if(!J)throw Error("Segmenter disabled by policy");let B=globalThis.Intl?.Segmenter;if(typeof B==="function"){let W=new B(Y?.locale,{granularity:"sentence"}),K=Array.from(W.segment(Q)).map((U)=>({text:U.segment,offset:U.index})).filter((U)=>U.text.trim().length>0);if(K.length>0)return K}}catch{}let G=/[^.!?]+(?:[.!?]+|$)/g,X=Q.match(G)||[Q],j=[],Z=0;for(let B of X){let W=Q.indexOf(B,Z);if(W===-1)continue;j.push({text:B,offset:W}),Z=W+B.length}return j.length>0?j:[{text:Q,offset:0}]};var R0=5000,E0=2000,b0=(Q)=>String(Q||"").trim().toLowerCase(),y3=()=>{let Q=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return b0(Q||"en-US")},f3=(Q,Y)=>{if(Y)return Q.find((Z)=>Z.voiceURI===Y)||Q.find((Z)=>Z.name===Y)||null;let J=y3(),G=J.split("-")[0]||"en",X=(Z)=>{let B=b0(Z.lang);return B===J||B.startsWith(`${G}-`)},j=[(Z)=>Z.localService&&X(Z),(Z)=>Z.default&&X(Z),(Z)=>X(Z),(Z)=>Z.localService,(Z)=>Z.default];for(let Z of j){let B=Q.find(Z);if(B)return B}return Q[0]||null},x3=(Q)=>!Q.default;class g7{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(Q){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");return new S0(Q)}supportsFeature(Q){return!0}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class S0{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;settlePendingVoiceWait=null;settlePendingChunk=null;onPlaybackStart=void 0;constructor(Q){this.config=Q}waitForBrowserVoices(Q,Y){return new Promise((J,G)=>{let X=speechSynthesis,j=typeof X.addEventListener==="function"&&typeof X.removeEventListener==="function",Z=j?null:X.onvoiceschanged,B=!1,W=null,K=null,U=()=>{if(W!==null)clearTimeout(W),W=null;if(j)X.removeEventListener("voiceschanged",N);else if(X.onvoiceschanged===D)X.onvoiceschanged=Z;if(K&&this.settlePendingVoiceWait===K)this.settlePendingVoiceWait=null},_=(O,P)=>{if(B)return;if(B=!0,U(),P)G(P);else J(O)},$=()=>{if(Q!==this.speakRunId){_(!1);return}if(X.getVoices().length>0)_(!0)},N=()=>$(),D=(O)=>{try{Z?.call(X,O)}finally{$()}};if(K=()=>_(!1),this.settlePendingVoiceWait=K,W=setTimeout(()=>_(!1,Error(`Configured browser voice "${Y}" could not be resolved because the browser did not publish its voice inventory within ${E0/1000} seconds.`)),E0),j)X.addEventListener("voiceschanged",N);else X.onvoiceschanged=D;$()})}async resolveBrowserVoice(Q){let Y=typeof this.config?.voice==="string"?this.config.voice.trim():"",J=speechSynthesis.getVoices();if(Y&&J.length===0){if(!await this.waitForBrowserVoices(Q,Y)||Q!==this.speakRunId)return{shouldContinue:!1,voice:null};J=speechSynthesis.getVoices()}if(Q!==this.speakRunId)return{shouldContinue:!1,voice:null};let G=f3(J,Y||void 0);if(Y&&!G)throw Error(`Configured browser voice "${Y}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return{shouldContinue:!0,voice:G}}async speak(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let Y=this.speakRunId,J=await this.resolveBrowserVoice(Y);if(!J.shouldContinue)return;let G=this.splitIntoChunks(Q);for(let X of G){if(Y!==this.speakRunId)break;if(!await this.speakChunk(X.text,X.offset,Y,J.voice))break}}async speakSegments(Q){if(!this.config)throw Error("TTS not initialized");this.stop();let Y=this.speakRunId,J=await this.resolveBrowserVoice(Y);if(!J.shouldContinue)return;for(let G of Q){if(Y!==this.speakRunId)break;let X=this.splitIntoChunks(G.text);for(let Z of X){if(Y!==this.speakRunId)break;if(!await this.speakChunk(Z.text,G.startOffset+Z.offset,Y,J.voice))break}let j=Math.max(0,Number(G.pauseMsAfter||0));if(j>0&&Y===this.speakRunId){if(!await this.waitForPause(j,Y))break}}}async waitForPause(Q,Y){return await new Promise((J)=>setTimeout(J,Q)),Y===this.speakRunId}splitIntoChunks(Q){if(Q.length<=260)return[{text:Q,offset:0}];let J=this.segmentSentences(Q),G=[],X="",j=0;for(let Z of J){let B=Z.text.trim();if(!B)continue;let W=Z.text.search(/\S/),K=Z.offset+(W===-1?0:W);if(!X){X=B,j=K;continue}let U=`${X} ${B}`;if(U.length<=260)X=U;else G.push({text:X,offset:j}),X=B,j=K}if(X)G.push({text:X,offset:j});return G.length?G:[{text:Q,offset:0}]}getHighlightMode(){return(this.config?.providerOptions||{}).highlightMode==="word"?"word":"sentence"}getSegmentationPolicy(){let Q=this.config?.providerOptions||{},Y=Q.segmenter||{},G=Y.mode!=="regexOnly",X=typeof Y.locale==="string"&&Y.locale.trim().length>0?Y.locale:typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:void 0;return{useSentenceSegmenter:G,useWordSegmenter:G,locale:X}}segmentSentences(Q){let Y=this.getSegmentationPolicy();return S7(Q,{locale:Y.locale,useSentenceSegmenter:Y.useSentenceSegmenter})}inferWordLength(Q,Y){let J=Math.max(0,Math.min(Y,Math.max(0,Q.length-1)));return Q.slice(J).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Q,Y,J,G){return new Promise((X,j)=>{if(J!==this.speakRunId){X(!1);return}let Z=new SpeechSynthesisUtterance(Q);if(this.utterance=Z,G&&x3(G))Z.voice=G;if(this.config?.rate)Z.rate=this.config.rate;if(this.config?.pitch)Z.pitch=this.config.pitch;let B=!1,W=!1,K=null,U=null,_=()=>{if(this.utterance===Z)this.utterance=null},$=()=>{if(K!==null)clearTimeout(K),K=null},N=()=>{Z.onstart=null,Z.onend=null,Z.onerror=null,Z.onpause=null,Z.onresume=null,Z.onboundary=null},D=(P,F)=>{if(W)return;if(W=!0,$(),N(),_(),U&&this.settlePendingChunk===U)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1,this._isPaused=!1;if(F)j(F);else X(P)},O=(P)=>Error(P==="ended"?"Browser speech synthesis ended before audio started. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.":`Browser speech synthesis did not start within ${R0/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);U=()=>D(!1),this.settlePendingChunk=U,Z.onstart=()=>{if(J!==this.speakRunId){D(!1);return}B=!0,$(),this._isPlaying=!0,this._isPaused=!1;try{this.onPlaybackStart?.()}catch(P){console.error("Browser TTS playback-start callback failed",P)}},Z.onend=()=>{if(J!==this.speakRunId){D(!1);return}if(!B){D(!1,O("ended"));return}D(!0)},Z.onerror=(P)=>{if(J!==this.speakRunId){D(!1);return}if(P.error==="interrupted"||P.error==="canceled"){D(!1);return}D(!1,Error(`Speech synthesis error: ${P.error}`))},Z.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},Z.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},Z.onboundary=(P)=>{if(J!==this.speakRunId)return;if(console.log("[BrowserProvider] Boundary event:",P.name,"charIndex:",P.charIndex,"charLength:",P.charLength),P.name!=="word"||!this.onWordBoundary)return;if(this.getHighlightMode()==="sentence")return;let F=Math.max(0,Math.min(P.charIndex,Math.max(0,Q.length-1))),L=Number(P.charLength||0),C=this.inferWordLength(Q,F),v=Number.isFinite(L)&&L>0&&L<=80&&F+L<=Q.length?L:C,k=Q.substring(F,Math.min(Q.length,F+v)).trim(),p=Y+F;console.log("[BrowserProvider] Calling onWordBoundary with word:",k,"at position:",p),this.onWordBoundary(k,p,v)},K=setTimeout(()=>{if(W||B||J!==this.speakRunId)return;D(!1,O("timedOut")),speechSynthesis.cancel()},R0);try{speechSynthesis.speak(Z)}catch(P){D(!1,P instanceof Error?P:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPlaying&&!this._isPaused)speechSynthesis.pause()}resume(){if(this._isPlaying&&this._isPaused)speechSynthesis.resume()}stop(){let Q=this.utterance,Y=this._isPlaying||Q!==null;if(this.speakRunId+=1,this.settlePendingVoiceWait?.(),this.settlePendingChunk?.(),Y)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(Q){if(!this.config)this.config={};if(Q.rate!==void 0)this.config.rate=Q.rate;if(Q.pitch!==void 0)this.config.pitch=Q.pitch;if(Q.voice!==void 0)this.config.voice=Q.voice;if(Q.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Q.providerOptions||{}}}onWordBoundary}var T=(Q)=>Q.trim().replace(/\s+/g," "),y0=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,X9=(Q)=>{if(Q.hidden)return!0;if(Q.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(Q.getAttribute("aria-hidden")==="true")return!0;if(Q.hasAttribute("inert"))return!0;let Y=Q.classList;if(Y?.contains("sr-only")||Y?.contains("pie-sr-only")||Y?.contains("visually-hidden"))return!0;if(typeof window<"u"){let J=window.getComputedStyle(Q);if(J.display==="none"||J.visibility==="hidden")return!0;let G=Number.parseFloat(J.width||"0"),X=Number.parseFloat(J.height||"0"),j=Number.isFinite(G)&&Number.isFinite(X)&&G<=1&&X<=1,Z=J.clipPath.includes("inset(50%")||J.clipPath.includes("inset(100%")||J.clip.includes("rect(0px, 0px, 0px, 0px)")||J.clip.includes("rect(0 0 0 0)");if((J.position==="absolute"||J.position==="fixed")&&j&&(J.overflow==="hidden"||Z))return!0;if(J.opacity==="0"&&j)return!0}return!1},C7=(Q,Y)=>{let J=Q.nodeType===1?Q:Q.parentElement;while(J){if(X9(J))return!0;if(Y&&J===Y)break;J=J.parentElement}return!1};var f0=new Set(["computer-read-aloud","all"]),C0=new Set([...f0,"screen-reader"]),T0=new Set,k3=(Q)=>{let Y=Q.getAttribute?.("data-tts-suppress");if(Y===null||Y===void 0)return!1;let J=Y.trim().toLowerCase();if(f0.has(J))return!0;if(C0.has(J))return!1;if(!T0.has(J))T0.add(J),console.warn(`[tts] data-tts-suppress="${Y}" is not one of ${Array.from(C0).join(", ")}; suppressing read-aloud for this content anyway, because a suppression attribute that fails open would leak the answer to items where reading is the construct. Correct the value to silence this.`);return!0},W1=(Q,Y)=>{let J=Q.nodeType===1?Q:Q.parentElement;while(J){if(k3(J))return!0;if(Y&&J===Y)break;J=J.parentElement}return!1},$7=(Q,Y)=>C7(Q,Y)||W1(Q),Z9=(Q,Y)=>{if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u"||typeof Q.intersectsNode!=="function")return{text:Q.toString(),filtered:!1};let J=[],G=!1,X=document.createTreeWalker(Y,NodeFilter.SHOW_TEXT),j=X.nextNode();while(j){let Z=j;if(Q.intersectsNode(Z))if($7(Z,Y))G=!0;else{let B=Z.textContent||"",W=Z===Q.startContainer?Q.startOffset:0,K=Z===Q.endContainer?Q.endOffset:B.length;J.push(B.slice(W,K))}j=X.nextNode()}return{text:J.join(""),filtered:G}},j9=(Q,Y,J)=>{if(!Q||!Y)return!1;if(/\s/.test(Q)||/\s/.test(Y))return!1;let G=J?.boundarySpacingMode??"segmenterPreferred";if(G==="none")return!1;if(G==="segmenterPreferred")try{let Z=globalThis.Intl?.Segmenter;if(typeof Z==="function"){let B=new Z(J?.locale,{granularity:"word"});if(Array.from(B.segment(`${Q}${Y}`)).filter((U)=>U.isWordLike!==!1&&U.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(Q),j=/[A-Za-z0-9]/.test(Y);return X&&j},F7=(Q,Y)=>{let J=new Map;if(typeof document>"u"||typeof document.createTreeWalker!=="function"||typeof NodeFilter>"u")return{text:"",map:J};let G=[],X=0,j=!0,Z=!1,B=null,W=null,K=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),U=K.nextNode();while(U){let $=U;if($.parentElement&&!$7($,Q)){let D=$.textContent||"",O=D.match(/\S/),P=O?O[0]:null;if(!j&&!Z&&j9(W,P,Y)){if(G.push(" "),B)J.set(X,B);X++,Z=!0}for(let F=0;F<D.length;F++){let L=D[F],C=/\s/.test(L);if(j){if(!C)j=!1,G.push(L),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++,Z=!1,W=L}else if(C){if(!Z)G.push(" "),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++;Z=!0}else G.push(L),J.set(X,{node:$,offset:F}),B={node:$,offset:F},X++,Z=!1,W=L}}U=K.nextNode()}let _=G.join("").trimEnd();while(J.has(_.length))J.delete(_.length);return{text:_,map:J}};var I3=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),x0=new Set(["audio","phoneme"]),I0=(Q)=>Q.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),K1=(Q,Y,J)=>{for(let G=0;G<Y.length;G++)Q.push({char:Y[G],rawOffset:J===null?null:J+G})},v3=(Q,Y,J)=>{let G=Y.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!G)return 0;return K1(Q,I0(G[0]),J),G[0].length},k0=(Q)=>{Q.push({char:" ",rawOffset:null})},h3=(Q)=>{let Y=new Map,J=[],G=!0;for(let X of Q){if(/\s/.test(X.char)){if(!G&&J.length>0){if(J.push(" "),X.rawOffset!==null)Y.set(X.rawOffset,J.length-1)}G=!0;continue}if(J.push(X.char),X.rawOffset!==null)Y.set(X.rawOffset,J.length-1);G=!1}while(J.length>0&&J[J.length-1]===" ")J.pop();for(let[X,j]of Y)if(j>=J.length)Y.delete(X);return{text:J.join(""),rawToSpokenOffsetMap:Y}},m3=(Q)=>{return Q.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},u3=(Q,Y)=>{let J=new RegExp(`${Y}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),G=Q.match(J);return I0(G?.[2]??G?.[3]??"")||null},v0=(Q)=>{let Y=[],J=!1,G=!1,X=0;while(X<Q.length){let Z=Q[X];if(Z!=="<"){if(Z==="&"){let $=v3(Y,Q,X);if($>0){X+=$;continue}}K1(Y,Z,X),X++;continue}let B=Q.indexOf(">",X+1);if(B<0){K1(Y,Z,X),X++;continue}G=!0;let W=Q.slice(X,B+1),K=m3(W),U=/^<\s*\//.test(W),_=/\/\s*>$/.test(W);if(!U&&K==="sub"){let $=u3(W,"alias");if(!$){J=!0,X=B+1;continue}K1(Y,$,null);let N=Q.toLowerCase().indexOf("</sub>",B+1);X=N>=0?N+6:B+1;continue}if(!U&&K==="break"){k0(Y),X=B+1;continue}if(!U&&x0.has(K)){if(J=!0,_){X=B+1;continue}}if(K&&!I3.has(K)&&!x0.has(K)&&K!=="break"&&K!=="sub")J=!0;if(!U&&(K==="p"||K==="s"))k0(Y);X=B+1}let j=h3(Y);return{spokenText:T(j.text),rawToSpokenOffsetMap:j.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:G}};var p3=y0(),g3=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),c3=(Q)=>{let Y=Q.toLowerCase();return g3.get(Y)||Y},W9=(Q)=>{let Y=[];for(let J of Q.matchAll(p3)){let G=J[0],X=J.index??0;Y.push({text:G,normalized:c3(G),start:X,end:X+G.length})}return Y},d3=(Q)=>W9(Q).map((Y,J)=>({...Y,id:`speech-token-${J}`,sourceStart:Y.start,sourceEnd:Y.end,coordinateSystem:"normalized-speech"})),H7=(Q)=>{let Y=v0(Q.speechText);return{speechText:Q.speechText,spokenText:Y.spokenText,tokens:d3(Y.spokenText),rawToSpokenOffsetMap:Y.rawToSpokenOffsetMap,boundaryOffsetSpace:Y.unsupportedSemantic?"unsupported":Y.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Y.unsupportedSemantic,hasMarkup:Y.hasMarkup}},K9=(Q)=>Boolean(Q&&/^<[^>]+>$/.test(Q.trim())),T7=(Q)=>{if(!Q||K9(Q))return null;return H7({speechText:Q}).tokens[0]?.normalized??null},l3=(Q,Y)=>Q.find((J)=>J.start<=Y&&Y<J.end)||null,i3=(Q,Y)=>{let J=Q.rawToSpokenOffsetMap.get(Y);if(J!==void 0)return J;for(let G=Y;G<Q.speechText.length;G++){let X=Q.rawToSpokenOffsetMap.get(G);if(X!==void 0)return X;if(Q.speechText[G]===">")break}return null},B9=(Q,Y,J)=>{if(Y===null)return null;let G=l3(Q.tokens,Y);if(!G)return null;return{token:G,start:Y,length:Math.max(1,Math.min(J,G.end-Y)),confidence:0.75}},q9=(Q,Y)=>Boolean(Q&&Y&&Q.token.normalized===Y),U9=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||K9(Q.boundaryWord))return null;let Y=Math.max(1,Number.isFinite(Q.length)?Q.length:1),J=T7(Q.boundaryWord),G=B9(Q.tokenization,i3(Q.tokenization,Q.position),Y),X=B9(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,Y);if(q9(G,J))return{...G,confidence:1};if(q9(X,J))return{...X,confidence:1};if(J)return null;return Q.tokenization.boundaryOffsetSpace==="raw-ssml"?G||X:X||G},h0=(Q)=>{if(Q.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Q.position)||K9(Q.boundaryWord))return null;let Y=Math.max(1,Number.isFinite(Q.length)?Q.length:1),J=T7(Q.boundaryWord),G=B9(Q.tokenization,Q.position>=0&&Q.position<Q.tokenization.spokenText.length?Q.position:null,Y);if(q9(G,J))return{...G,confidence:1};if(J)return null;return G};var s3=[{phrase:["plus","or","minus"],visible:"±",score:8},{phrase:["square","root"],visible:"√",score:8},{phrase:["divided","by"],visible:"/",score:7},{phrase:["all","over"],visible:"/",score:7},{phrase:["equals"],visible:"=",score:7},{phrase:["equal"],visible:"=",score:7},{phrase:["times"],visible:"",score:7},{phrase:["multiplied","by"],visible:"",score:7},{phrase:["over"],visible:"/",score:6},{phrase:["squared"],visible:"²",score:6},{phrase:["squared"],visible:"2",score:4},{phrase:["negative"],visible:"-",score:5},{phrase:["minus"],visible:"-",score:5},{phrase:["plus"],visible:"+",score:5}],n3=(Q,Y)=>{let J=[];for(let G=0;G<Q.length;G++){for(let X=0;X<Y.length;X++)if(Q[G].normalized===Y[X].normalized)J.push({spokenStartToken:G,spokenEndToken:G+1,visibleToken:X,score:10});for(let X of s3){let j=Q.slice(G,G+X.phrase.length);if(j.length!==X.phrase.length)continue;if(!j.every((Z,B)=>Z.normalized===X.phrase[B]))continue;for(let Z=0;Z<Y.length;Z++){if(Y[Z].text!==X.visible)continue;J.push({spokenStartToken:G,spokenEndToken:G+X.phrase.length,visibleToken:Z,score:X.score})}}}return J},r3=(Q,Y)=>{let J=n3(Q,Y).sort((W,K)=>Q[W.spokenStartToken].start-Q[K.spokenStartToken].start||Y[W.visibleToken].start-Y[K.visibleToken].start),G=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let W=0;W<J.length;W++){let K=J[W];G[W]=K.score;for(let U=0;U<W;U++){let _=J[U];if(_.spokenEndToken<=K.spokenStartToken&&_.visibleToken<K.visibleToken){let $=K.spokenStartToken-_.spokenEndToken,N=K.visibleToken-_.visibleToken-1,D=Math.max(0,Math.abs($-N)-2),O=G[U]+K.score-D;if(O>G[W])G[W]=O,X[W]=U}}}let j=-1;for(let W=0;W<G.length;W++)if(j<0||G[W]>G[j])j=W;if(j<0)return[];let Z=[],B=j;while(B>=0)Z.unshift(J[B]),B=X[B];return Z.map((W)=>{let K=Q[W.spokenStartToken],U=Q[W.spokenEndToken-1],_=Y[W.visibleToken];return{spokenStart:K.start,spokenEnd:U.end,visibleStart:_.start,visibleEnd:_.end,score:W.score}})},o3=(Q,Y,J)=>{if(Q.length===0)return 0;let G=Q.length/Math.max(1,Math.min(Y.length,J.length)),X=Q.reduce((j,Z)=>j+Z.score,0)/Q.length/10;return Math.min(1,G*X)},U1=(Q)=>{let Y=H7({speechText:Q.speechText}),J=T(Q.visibleText),G=Y.tokens,X=W9(J),j=Y.unsupportedSemantic?[]:r3(G,X),Z=o3(j,G,X),B=Y.spokenText===J&&Y.spokenText.length>0,W=j.length===1&&j[0].score===10&&G.length<=2&&X.length<=2,K=Y.unsupportedSemantic?"region-fallback":B?"exact-word":j.length>=2||W?Z>=0.12?"anchor-span":"region-fallback":"region-fallback";return{speech:Y,visibleText:J,playbackMode:K,anchors:j,confidence:Z}},m0=(Q,Y)=>{if(Q.playbackMode==="region-fallback")return null;let J=Q.anchors.find((j)=>j.spokenStart<=Y&&Y<j.spokenEnd);if(J)return{start:J.visibleStart,end:J.visibleEnd};let G=null,X=null;for(let j of Q.anchors){if(j.spokenEnd<=Y){G=j;continue}if(j.spokenStart>Y){X=j;break}}if(G&&X)return{start:Math.min(G.visibleStart,X.visibleStart),end:Math.max(G.visibleEnd,X.visibleEnd)};return null};var a3=new Map([["+",["plus"]],["-",["minus","negative"]],["−",["minus","negative"]],["×",["times","multiplied by"]],["÷",["divided by"]],["=",["equals","equal to"]],["≠",["is not equal to","not equal to"]],["≈",["approximately equals"]],["≤",["less than or equal to"]],["≥",["greater than or equal to"]],["<",["less than"]],[">",["greater than"]],["∠",["angle"]],["△",["triangle"]],["□",["box"]],["○",["circle"]],["°",["degrees","degree"]],["%",["percent"]],["'",["prime"]],["′",["prime"]],["•",["times"]],["·",["times"]],["",["times","multiplied by"]]]),t3=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),u0=new Map([["2",["squared"]],["3",["cubed"]]]),e3=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),Q5=(Q)=>Q.replace(/\s+/g," ").trim(),D7=(Q)=>(Q.localName||Q.tagName||"").toLowerCase(),Y5=(Q)=>Q.nodeType===Node.ELEMENT_NODE,y7=(Q)=>Array.from(Q.childNodes).filter(Y5),V9=(Q)=>Q5(Q.textContent||""),Y7=(Q,Y)=>({type:"element-range",quality:Y,element:Q}),J5=(Q)=>{switch(Q){case"mi":return"identifier";case"mn":return"number";case"mo":return"operator";case"mtext":case"ms":return"text";case"mspace":return"space";default:return"unknown"}},G5=(Q,Y)=>{if(Y==="operator"){if(Q==="−")return"-";return Q}return Q.toLowerCase()},X5=(Q,Y,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return u0.get(Q)??[];if(Q==="|")return["absolute value"];if(Y==="operator")return a3.get(Q)||[];return[]},N7=(Q)=>{let Y=Q.normalized??G5(Q.text,Q.kind||"unknown");return{id:`math-token-${Q.state.nextId++}`,kind:Q.kind,role:Q.role,text:Q.text,normalized:Y,spokenAliases:X5(Q.text,Q.kind,Q.role),sourceElement:Q.sourceElement,path:Q.path,target:Q.target||Y7(Q.sourceElement,"element-range"),optional:Q.optional}},M7=(Q,Y,J="tokens")=>{Q[J].push(Y)},p0=(Q,Y,J)=>{y7(Q).forEach((G,X)=>J7(G,Y,`${J}/${D7(G)}[${X}]`))},Z5=(Q,Y,J)=>{let G=y7(Q);if(G[0])J7(G[0],Y,`${J}/numerator`);if(M7(Y,N7({state:Y,kind:"structure",role:"fraction",text:"/",sourceElement:Q,path:J,target:Y7(Q,"element-range")})),G[1])J7(G[1],Y,`${J}/denominator`)},j5=(Q,Y,J)=>{let G=Q.getAttribute("open")||"(",X=Q.getAttribute("close")||")";M7(Y,N7({state:Y,kind:"operator",role:G==="|"?"absolute-value-fence":"open-fence",text:G,sourceElement:Q,path:`${J}/open`,target:Y7(Q,"element-range")})),p0(Q,Y,J),M7(Y,N7({state:Y,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Q,path:`${J}/close`,target:Y7(Q,"element-range")}))},B5=(Q,Y,J)=>{let G=y7(Q);if(G[0])J7(G[0],Y,`${J}/base`);let X=G[1];if(!X)return;let j=V9(X);if(u0.has(j)){M7(Y,N7({state:Y,kind:"structure",role:"superscript",text:j,normalized:j,sourceElement:X,path:`${J}/exponent`,target:Y7(Q,"element-range")}));return}J7(X,Y,`${J}/exponent`)},q5=(Q,Y,J,G)=>{M7(Y,N7({state:Y,kind:"structure",role:G,text:V9(Q)||G,normalized:`\x00${G}`,sourceElement:Q,path:J,target:Y7(Q,"element-range")}))},W5=(Q,Y,J)=>{let G=0;for(let X of y7(Q)){if(D7(X)==="mtr"||D7(X)==="mlabeledtr")G++,M7(Y,N7({state:Y,kind:"layout",role:"table-row",text:`row-${G}`,normalized:`row-${G}`,sourceElement:X,path:`${J}/row[${G}]`,target:Y7(X,"region-fallback")}),"layoutTargets");J7(X,Y,`${J}/${D7(X)}[${G}]`)}},K5=(Q,Y,J)=>{let G=V9(Q);if(!G)return;let X=J5(D7(Q)),j=X==="operator"?t3.get(G):void 0,Z=j??(X==="operator"&&(G==="("||G===")")?"grouping-fence":X);M7(Y,N7({state:Y,kind:X,role:Z,text:G,sourceElement:Q,path:J,target:j&&Q.parentElement?Y7(Q.parentElement,"region-fallback"):void 0,optional:Boolean(j)||Z==="grouping-fence"}))},J7=(Q,Y,J)=>{let G=D7(Q);switch(G){case"annotation":case"annotation-xml":return;case"semantics":{let X=y7(Q).find((j)=>{let Z=D7(j);return Z!=="annotation"&&Z!=="annotation-xml"});if(X)J7(X,Y,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":K5(Q,Y,J);return;case"mfrac":Z5(Q,Y,J);return;case"msup":B5(Q,Y,J);return;case"mfenced":j5(Q,Y,J);return;case"mtable":W5(Q,Y,J);return;case"mphantom":return;case"maction":{let X=y7(Q)[0];if(X)J7(X,Y,`${J}/action`);return}default:{let X=e3.get(G);if(X){q5(Q,Y,J,X);return}p0(Q,Y,J)}}},g0=(Q)=>{let Y={tokens:[],layoutTargets:[],nextId:0};return J7(Q,Y,"/math"),{tokens:Y.tokens,layoutTargets:Y.layoutTargets,expressionTarget:Y7(Q,"region-fallback")}};var c0=(Q)=>{if(!Q.boundary)return null;return Q.alignment.segments.find((J)=>J.speechTokenIds.includes(Q.boundary.token.id))?.target||null};var U5=(Q)=>{let Y=[],J=new Set,G=(X)=>{let j=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(j.length===0)return;let Z=j.join(" ");if(J.has(Z))return;J.add(Z),Y.push(j)};G(Q.normalized);for(let X of Q.spokenAliases)G(X);return Y},d0=(Q,Y,J)=>{let G=0;for(let X of J){if(X.length<=G)continue;let j=!0;for(let Z=0;Z<X.length;Z++){let B=Q[Y+Z];if(!B||B.normalized.toLowerCase()!==X[Z]){j=!1;break}}if(j)G=X.length}return G},V5=(Q,Y)=>{let J=[],G=0;for(let X of Y){let j=U5(X);if(X.optional){let Z=d0(Q,G,j);if(Z>0)J.push({speechTokens:Q.slice(G,G+Z),math:X}),G+=Z;continue}while(G<Q.length){let Z=d0(Q,G,j);if(Z>0){J.push({speechTokens:Q.slice(G,G+Z),math:X}),G+=Z;break}G++}}return J},A5=(Q,Y,J)=>{let G=J.filter((Z)=>!Z.optional).length,X=Q.filter((Z)=>!Z.math.optional).length,j=Q.reduce((Z,B)=>Z+B.speechTokens.length,0);return G>0&&X===G&&j===Y.length},_5=(Q)=>Q.map(({speechTokens:Y,math:J})=>({speechTokenIds:Y.map((G)=>G.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),l0=(Q)=>{let Y=Q.minExactWordConfidence??0.95,J=V5(Q.speech.tokens,Q.math.tokens),G=A5(J,Q.speech.tokens,Q.math.tokens)?1:0;return{segments:G>=Y?_5(J):[],confidence:G,fallbackTarget:Q.math.expressionTarget}};var f7=(Q)=>{let Y=H7({speechText:Q.speechText}),J=g0(Q.mathElement);return{speech:Y,math:J,result:l0({speech:Y,math:J})}};var i0=(Q,Y)=>{let J=h0({tokenization:Q.speech,position:Y.position,length:Y.length,boundaryWord:Y.boundaryWord});return c0({alignment:Q.result,boundary:J})},s0=(Q,Y)=>{let J=T7(Y.boundaryWord);if(!J)return null;let G=Q.math.tokens.filter((X)=>X.normalized.toLowerCase()===J||X.spokenAliases.some((j)=>j.toLowerCase()===J));return G.length===1?G[0].target:null};var $5=new Set(["math","maction","menclose","merror","mfenced","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","none","semantics","annotation","annotation-xml"]),F5=new Set(["accent","accentunder","align","bevelled","class","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","encoding","fence","height","href","id","largeop","length","linethickness","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","width","xmlns","xml:lang"]),n0=(Q)=>Q.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),H5=(Q)=>n0(Q).replace(/"/g,"""),D5=(Q,Y)=>{let J=Q.toLowerCase(),G=Y.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!F5.has(J))return!0;if(G.includes("javascript:"))return!0;if(G.includes("data:text/html"))return!0;return!1},N5=(Q)=>{let Y=Q.localName.toLowerCase();if(!$5.has(Y))return!1;let J=Q.namespaceURI;return!J||J==="http://www.w3.org/1998/Math/MathML"||J==="http://www.w3.org/1999/xhtml"},r0=(Q)=>{if(Q.nodeType===Node.TEXT_NODE)return n0(Q.textContent||"");if(Q.nodeType===Node.COMMENT_NODE)return"";if(Q.nodeType!==Node.ELEMENT_NODE)return null;let Y=Q;if(!N5(Y))return null;let J=Y.localName.toLowerCase(),G=[];for(let Z of Array.from(Y.attributes)){let B=Z.name.toLowerCase();if(D5(B,Z.value))continue;if(B==="xmlns"&&Z.value!=="http://www.w3.org/1998/Math/MathML")return null;G.push(`${B}="${H5(Z.value)}"`)}if(J==="math"&&!G.some((Z)=>Z.startsWith("xmlns=")))G.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let Z of Array.from(Y.childNodes)){let B=r0(Z);if(B===null)return null;X.push(B)}let j=G.length>0?` ${G.join(" ")}`:"";return`<${J}${j}>${X.join("")}</${J}>`},M5=(Q)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Q,"application/xml");return null},V1=(Q)=>{let Y=String(Q||"").trim();if(!Y)return null;let J=M5(Y);if(!J)return null;if(J.getElementsByTagName("parsererror").length>0)return null;let G=J.documentElement;if(!G||G.localName.toLowerCase()!=="math")return null;return r0(G)};var o0=(Q)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Q}),A9=(Q)=>Q.classList?.contains("MathJax")||Q.tagName?.toLowerCase()==="mjx-container",a0=(Q)=>Q.tagName?.toLowerCase()==="mjx-assistive-mml",_9=(Q)=>{let Y=Q.tagName?.toLowerCase();return Y==="annotation"||Y==="annotation-xml"},z5=(Q)=>{let Y=Q.getAttribute("data-mathml");return Y&&Y.trim()?Y:null},O5=(Q)=>{return Q.querySelector("mjx-assistive-mml math")?.outerHTML||null},P5=(Q)=>{if(Q.tagName.toLowerCase()==="math")return V1(Q.outerHTML);let Y=z5(Q);if(Y){let J=V1(Y);if(J)return J}if(A9(Q)){let J=O5(Q);if(J){let G=V1(J);if(G)return G}}return null},L5=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),w5=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),R5=(Q,Y)=>{let J=Q.parentElement,G=null;while(J&&J!==Y){let X=(J.getAttribute("role")||"").toLowerCase(),j=J.tagName.toUpperCase();if(L5.has(j)||w5.has(X)){G=J;break}J=J.parentElement}return G||Y},E5=(Q)=>Boolean(typeof Q.querySelector==="function"&&Q.querySelector("math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Q.tagName?.toLowerCase()==="math"||Q.hasAttribute?.("data-mathml")||A9(Q),z7=(Q,Y,J)=>{if(/[.,;:!?]/.test(Y)&&Q.chars.length>0&&Q.chars[Q.chars.length-1]===" ")Q.chars.pop(),Q.position--,Q.map.delete(Q.position);if(Q.chars.push(Y),J)Q.map.set(Q.position,J),Q.lastMapped=J;else if(Q.lastMapped)Q.map.set(Q.position,Q.lastMapped);Q.position++},t0=(Q,Y)=>{if(Q.inLeadingWhitespace||Q.lastCharWasWhitespace||Q.chars.length===0)return!1;let J=Q.chars[Q.chars.length-1];return j9(J,Y,Q.options)},e0=(Q,Y)=>{let J=Y.textContent||"",G=!1;for(let X=0;X<J.length;X++){let j=J[X],Z=/\s/.test(j);if(Q.inLeadingWhitespace){if(!Z)Q.inLeadingWhitespace=!1,z7(Q,j,{node:Y,offset:X}),G=!0,Q.lastCharWasWhitespace=!1;continue}if(Z){if(!Q.lastCharWasWhitespace)z7(Q," ",{node:Y,offset:X});Q.lastCharWasWhitespace=!0;continue}if(!G&&t0(Q,j))z7(Q," ",{node:Y,offset:X});z7(Q,j,{node:Y,offset:X}),G=!0,Q.lastCharWasWhitespace=!1}},b5=(Q,Y)=>{for(let J=0;J<Y.text.length;J++){let G=Y.text[J],X=/\s/.test(G),j=Y.map.get(J)||null,Z=j?.node||Q.lastMapped?.node||null,B=j?.offset??Q.lastMapped?.offset??0,W=j?{node:j.node,offset:j.offset}:Z?{node:Z,offset:B}:null;if(Q.inLeadingWhitespace){if(X)continue;Q.inLeadingWhitespace=!1}if(X){if(!Q.lastCharWasWhitespace)z7(Q," ",W);Q.lastCharWasWhitespace=!0;continue}if(J===0&&t0(Q,G))z7(Q," ",W);if(z7(Q,G,W),Q.lastCharWasWhitespace=!1,j)Q.map.set(Q.position-1,{node:j.node,offset:j.offset}),Q.lastMapped={node:j.node,offset:j.offset};else if(Z)Q.map.set(Q.position-1,{node:Z,offset:B})}},S5=(Q)=>{if(typeof DOMParser>"u")return"";let Y=new DOMParser().parseFromString(Q,"application/xml");if(Y.getElementsByTagName("parsererror").length>0)return"";let J=[],G=(X)=>{if(X.nodeType===3){let Z=X.textContent||"";if(Z.trim())J.push(Z);return}if(X.nodeType!==1)return;let j=X;if(_9(j))return;for(let Z of Array.from(j.childNodes))G(Z)};return G(Y.documentElement),T(J.join(" "))},C5=(Q,Y)=>{let J=new Map,G=A9(Q)?Q.querySelector("mjx-assistive-mml math"):null;if(!G)return J;let X=[],j=(B)=>{if(B.nodeType===3){let W=B.textContent||"";for(let K=0;K<W.length;K++)if(!/\s/.test(W[K]))X.push({node:B,offset:K});return}if(B.nodeType!==1||_9(B))return;for(let W of Array.from(B.childNodes))j(W)};j(G);let Z=0;for(let B=0;B<Y.length;B++){if(/\s/.test(Y[B]))continue;let W=X[Z];if(W?.node.textContent?.[W.offset]!==Y[B])return new Map;J.set(B,W),Z++}return Z===X.length?J:new Map},T5=(Q,Y,J)=>{let G=o0(J),X=(B)=>{if($7(B,Q))return;if(B.nodeType===3){e0(G,B);return}if(B.nodeType!==1)return;let W=B;if(a0(W)||_9(W))return;for(let K of Array.from(W.childNodes))X(K)};X(Q),Q8(G);let j=T(G.chars.join(""));if(j)return{text:j,map:G.map};let Z=S5(Y);if(!Z)return F7(Q,J);return{text:Z,map:C5(Q,Z)}},Q8=(Q)=>{while(Q.chars.length>0&&/\s/.test(Q.chars[Q.chars.length-1]))Q.chars.pop(),Q.position--,Q.map.delete(Q.position)},y5=(Q,Y)=>{let J=o0(Y),G=[],X=0,j,Z=!1,B=()=>{let U=T(J.chars.slice(X,J.chars.length).join(""));if(U)G.push({type:"text",text:U,sourceElement:j});X=J.chars.length,j=void 0},W=(U)=>{if($7(U,Q))return;if(U.nodeType===Node.TEXT_NODE){let N=R5(U,Q);if(j&&N!==j)B();j=N,e0(J,U);return}if(U.nodeType!==Node.ELEMENT_NODE)return;let _=U;if(a0(_))return;let $=P5(_);if($){B();let N=T5(_,$,Y);b5(J,N);let D=T(N.text);G.push({type:"math",mathml:$,fallbackText:D,sourceElement:_}),X=J.chars.length,Z=!0;return}for(let N of Array.from(_.childNodes))W(N)};for(let U of Array.from(Q.childNodes))W(U);Q8(J),B();let K=J.chars.join("");while(J.map.has(K.length))J.map.delete(K.length);return{visibleText:K,map:J.map,chunks:G,containsMathMarkup:Z}},O7=(Q,Y)=>{if(!E5(Q)){let{text:J,map:G}=F7(Q,Y);return{visibleText:J,map:G,chunks:J?[{type:"text",text:J}]:[],containsMathMarkup:!1}}return y5(Q,Y)};var $9=null,Y8=Promise.resolve(),x5=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",k5=async(Q)=>{if(!$9)Z8(Q),$9=import("./chunks/sre-engine-wf9s43gg.js").then(({default:Y})=>{if(!Y||typeof Y.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Y});return $9},I5=(Q)=>Q==="en"?"clearspeak":"mathspeak",J8=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),G8=(Q)=>typeof Q==="string"&&Q.trim()?Q.trim():void 0,j7=(Q)=>{if(!J8(Q))return;let Y=G8(Q.domain),J=G8(Q.style),G=J8(Q.engineOptions)?Q.engineOptions:void 0;if(!Y&&!J&&!G)return;return{...Y?{domain:Y}:{},...J?{style:J}:{},...G?{engineOptions:G}:{}}},v5=async(Q,Y,J,G)=>{let X=x5(Y),j=j7(G),Z=j?.engineOptions||{};await Q.setupEngine?.({...X8(Z),...Z,locale:X,domain:j?.domain||I5(X),...j?.style?{style:j.style}:{},modality:"speech",markup:J}),await Q.engineReady?.()},h5=async(Q)=>{let Y=Y8.then(Q,Q);return Y8=Y.then(()=>{return},()=>{return}),Y},j8=async(Q,Y,J,G,X)=>h5(async()=>{return await v5(Q,J,G,X),Q.toSpeech(Y)}),m5=(Q)=>Q.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),u5=async(Q,Y,J,G)=>{try{let X=m5(await j8(Q,Y,J,"ssml",G));return X.includes("<speak")?X:null}catch(X){return console.debug("[TTSService] Math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},A1=async(Q,Y={})=>{if(!Q.some((K)=>K.type==="math"))return{speechText:T(Q.map((K)=>K.type==="text"?K.text:K.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,G=!1,X=!1,j=Y.loadSre||(()=>k5(j7(Y.mathSpeech)?.engineOptions)),Z=[];for(let K of Q){if(K.type==="text"){Z.push(K.text);continue}try{if(!J)J=await j();let U=T(await j8(J,K.mathml,Y.language,"none",Y.mathSpeech));if(U){Z.push(U),G=!0;continue}X=!0,Z.push(K.fallbackText)}catch(U){X=!0,console.debug("[TTSService] Math speech generation failed; using visible fallback",{message:U instanceof Error?U.message:String(U)}),Z.push(K.fallbackText)}}let B=T(Z.join(" ")),W;if(Y.produceSsml&&J&&G&&Q.length===1&&Q[0].type==="math")W=await u5(J,Q[0].mathml,Y.language,Y.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:G,usedFallback:X,ssml:W}};var p5=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",g5="sre-v1",c5=256,F9=(Q)=>{if(Array.isArray(Q))return`array:[${Q.map(F9).join(",")}]`;if(Q&&typeof Q==="object")return`object:{${Object.entries(Q).sort(([Y],[J])=>Y.localeCompare(J)).map(([Y,J])=>`${JSON.stringify(Y)}:${F9(J)}`).join(",")}}`;if(Q===null)return"null:null";if(typeof Q>"u")return"undefined:";if(typeof Q==="function")return`function:${Q.name||"anonymous"}`;if(typeof Q==="symbol")return`symbol:${String(Q)}`;if(typeof Q==="bigint")return`bigint:${Q.toString()}`;if(typeof Q==="number")return Number.isFinite(Q)?`number:${Q}`:`number:${String(Q)}`;return`${typeof Q}:${JSON.stringify(Q)}`},B8=(Q,Y,J,G)=>`${g5}\x00${p5(Q)}\x00${Y?"ssml":"plain"}\x00${F9(J??null)}\x00${G}`,H9=(Q={})=>{let Y=Math.max(1,Q.maxEntries??c5),J=Q.resolve??((j,Z)=>A1([j],Z)),G=new Map,X=(j,Z)=>{G.delete(j),G.set(j,Z);while(G.size>Y){let B=G.keys().next().value;if(B!==void 0)G.delete(B)}};return async(j,Z)=>{let B=j7(Z.mathSpeech),W=Z.produceSsml===!0,K=B8(Z.language,W,B,j.mathml),U=G.get(K);if(U)return G.delete(K),G.set(K,U),U;let _=await J(j,{...Z,mathSpeech:B});if(W&&_.ssml&&Y>1)X(B8(Z.language,!1,B,j.mathml),{speechText:_.speechText,usedMathSpeech:_.usedMathSpeech,usedFallback:_.usedFallback});return X(K,_),_}};var q8=(Q,Y)=>{let J=T7(Y.word);if(Q.id!==Y.chunkId)return{chunkId:Y.chunkId,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Y.providerOffsetSpace==="unknown"||Q.offsetSpace==="unsupported")return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let G=U9({tokenization:Q.catalogAlignment?.speech??H7({speechText:Q.speechText}),position:Y.position,length:Y.length,boundaryWord:Y.word});if(!G)return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};return{chunkId:Q.id,normalizedWord:J,chunkSpokenStart:G.start,chunkSpokenEnd:G.start+G.length,confidence:G.confidence,reason:Q.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var P7=(Q)=>{if(Q.semanticTarget)return{activeTarget:Q.semanticTarget,regionTarget:Q.regionTarget,quality:Q.semanticTarget.quality==="exact-word"?"exact-word":Q.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:Q.confidence,reason:Q.reason};if(Q.expressionTarget)return{activeTarget:Q.expressionTarget,regionTarget:Q.regionTarget,quality:"expression",confidence:Q.confidence,reason:Q.reason};return{activeTarget:null,regionTarget:Q.regionTarget,quality:"region",confidence:Q.confidence,reason:Q.reason}};var K8=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),D9="mi,mn,mo,mtext",U8="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",V8=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),A8=(Q)=>{if(Q.type==="text-range")return Q.node.parentElement;return Q.element},_1=(Q)=>{let Y=Q;while(Y){if(Y.localName?.toLowerCase()==="mjx-container")return Y;Y=Y.parentElement}return null},W8=(Q)=>{if(!Q)return!1;if(_1(Q))return!1;return!C7(Q)},_8=(Q)=>{let Y=Q.getBoundingClientRect?.();return Boolean(Y&&Y.width>0&&Y.height>0)},N9=(Q)=>{let Y=Q;while(Y){if(Y.localName?.toLowerCase()==="math")return Y;Y=Y.parentElement}return null},$8=(Q,Y)=>{if(Q.length===0)return!1;if(Q.length!==Y.length)return!1;for(let J=0;J<Q.length;J+=1){let G=K8.get(Q[J].localName.toLowerCase());if(!G)return!1;if(Y[J].localName.toLowerCase()!==G)return!1}return!0},d5=(Q,Y)=>{if(!Q)return null;if(!K8.has(Q.localName.toLowerCase()))return null;if(Y.querySelector(V8))return null;let J=N9(Q),G=Y.querySelector("mjx-math");if(!J||!G)return null;let X=Array.from(J.querySelectorAll(D9)),j=X.indexOf(Q);if(j<0)return null;let Z=Array.from(G.querySelectorAll(U8));if(!$8(X,Z))return null;let B=Z[j];if(!B||!_8(B))return null;return B},F8=(Q)=>{let Y=_1(Q);if(Y){if(Y.querySelector(V8))return"expression";let X=N9(Q)??Q,j=Y.querySelector("mjx-math");if(!j)return"expression";let Z=Array.from(X.querySelectorAll(D9)),B=Array.from(j.querySelectorAll(U8));if(!$8(Z,B))return"expression";return B.some((W)=>_8(W))?"token":"expression"}let J=N9(Q)??Q;return Array.from(J.querySelectorAll(D9)).some((X)=>!C7(X))?"token":"expression"},M9=(Q)=>{let Y=A8(Q),J=_1(Y);if(J){let G=d5(Y,J);if(G)return{type:"element",quality:"semantic-token",element:G};return{type:"element",quality:"expression",element:J}}if(Q.type==="text-range"){if(!W8(Q.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Q.node,startOffset:Q.startOffset,endOffset:Q.endOffset}}if(!W8(Q.element))return null;return{type:"element",quality:Q.quality==="region-fallback"?"expression":"semantic-token",element:Q.element}},H8=M9,D8=()=>{let Q=new WeakMap;return(Y)=>{let J=A8(Y),G=_1(J);if(!J||!G)return M9(Y);if(Q.has(J))return Q.get(J)??null;let X=M9(Y);return Q.set(J,X),X}};var N8=(Q,Y,J,G=Q.mathAlignments,X=H8)=>{if(Y.chunkSpokenStart===null||Y.chunkSpokenEnd===null)return null;let j=null;for(let Z of G){let B=i0(Z.alignment,{position:Y.chunkSpokenStart,length:Math.max(1,Y.chunkSpokenEnd-Y.chunkSpokenStart),boundaryWord:J.word})||s0(Z.alignment,{boundaryWord:J.word});if(!B)continue;let W=X(B);if(!W)continue;if(W.quality==="semantic-token")return W;j??=W}return j};var $1=(Q,Y,J)=>{if(!Q||typeof document>"u")return null;if(J<=Y)return null;let G=Q.get(Y),X=Q.get(Math.max(Y,J-1));if(!G)return null;if(!X)X=G;try{let j=document.createRange();return j.setStart(G.node,G.offset),j.setEnd(X.node,X.offset+1),j}catch{return null}};var M8=(Q,Y)=>{if(!Q.catalogAlignment||Y.chunkSpokenStart===null)return null;let J=m0(Q.catalogAlignment,Y.chunkSpokenStart);if(!J)return null;let G=$1(Q.visibleMap,J.start,J.end);if(!G)return null;return{type:"range",quality:Q.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:G}};var l5=(Q)=>Q.regionRange?{type:"range",quality:"region",range:Q.regionRange}:Q.regionElement?{type:"element",quality:"region",element:Q.regionElement}:null,z8=(Q,Y=Q.chunk.mathAlignments)=>{if(Y.length!==1)return null;let J=Y[0]?.alignment.result.fallbackTarget;return J?Q.renderedMathTargetResolver(J):null},i5=(Q,Y)=>{if(!Q)return Y.mathAlignments;return Y.mathAlignments.filter(({element:J})=>{try{if(Q.type==="range")return Q.range.intersectsNode(J);if(Q.type==="element")return Q.element===J||Q.element.contains(J);return Q.node.parentElement?.contains(J)||!1}catch{return!1}})},O8=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),P8=(Q)=>Q.length===1?Q[0].element:null,s5=(Q,Y)=>Y.length>0&&Y.every(({element:J})=>Q.mathCapabilityByElement.get(J)==="token"),L8=3,n5=(Q,Y,J)=>{if(!Y||Y.type!=="range")return!1;let{startContainer:G,endContainer:X}=Y.range;if(G===X&&G.nodeType===L8)return!1;return J.some(({element:Z})=>Q.mathCapabilityByElement.get(Z)==="token"&&Z.contains(G)&&Z.contains(X))},w8=(Q)=>Q?.type==="range"&&C7(Q.range.startContainer),r5=(Q,Y)=>{if(!w8(Y))return null;let{startContainer:J,endContainer:G,startOffset:X,endOffset:j}=Y.range;if(J!==G||J.nodeType!==L8)return null;return Q.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:j})},o5=(Q,Y)=>({chunk:Q,regionTarget:l5(Q),renderedMathTargetResolver:D8(),mathCapabilityByElement:new Map(Q.mathAlignments.map(({element:J})=>[J,Y?F8(J):"expression"])),heldTokenByElement:new Map}),R8=(Q)=>{let Y=Q.mathTokenHighlighting!==!1,J=new Map(Q.chunks.map((G)=>[G.id,o5(G,Y)]));return{chunks:Q.chunks,resolveInitial(G){let X=J.get(G);if(!X)return O8();let j=X.chunk.mathAlignments,Z=j.length===1?j[0].element:null,B=Z?X.mathCapabilityByElement.get(Z):null;if(B==="expression")return P7({semanticTarget:null,expressionTarget:z8(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return P7({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:B==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(G){let X=J.get(G.chunkId);if(!X)return O8();let{chunk:j}=X,Z=q8(j,G),B=M8(j,Z),W=i5(B,j),K=(!B||W.length>0?N8(j,Z,G,W,X.renderedMathTargetResolver):null)||null,U=K?.quality==="semantic-token"?K:r5(X,B)??K,_=Y&&U&&U.quality!=="expression"?U:null,$=U&&U.quality==="expression"?U:null;if(_){let N=P8(W);if(N)X.heldTokenByElement.set(N,_);return P7({semanticTarget:_,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}if(B&&!w8(B)&&(Y?!n5(X,B,W):W.length===0))return P7({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason});if(s5(X,W)){let N=P8(W),D=N?X.heldTokenByElement.get(N)??null:null;return P7({semanticTarget:D,expressionTarget:null,regionTarget:X.regionTarget,confidence:Z.confidence,reason:D?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return P7({semanticTarget:null,expressionTarget:$??z8(X,W),regionTarget:X.regionTarget,confidence:Z.confidence,reason:Z.reason})}}};var a5=(Q)=>{return Q.alignment?.speech.boundaryOffsetSpace??Q.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},t5=(Q)=>{if(Q.mathAlignments?.length)return Q.mathAlignments;if(Q.mathAlignment&&Q.sourceElement)return[{element:Q.sourceElement,alignment:Q.mathAlignment}];return[]},E8=(Q)=>{return(Q.chunks&&Q.chunks.length?Q.chunks:[{speechText:Q.speechText||"",visibleText:Q.visibleText||Q.speechText||"",sourceElement:Q.sourceElement||Q.contentRoot,regionElement:Q.regionElement||Q.sourceElement||Q.contentRoot,regionRange:Q.regionRange,visibleMap:Q.visibleMap}]).map((J,G)=>({id:`tts-chunk-${G}`,speechText:J.speechText,visibleText:J.visibleText,sourceElement:J.sourceElement,contentRoot:Q.contentRoot,regionElement:J.regionElement??J.sourceElement,regionRange:J.regionRange,visibleMap:J.visibleMap,catalogAlignment:J.alignment,mathAlignments:t5(J),offsetSpace:a5(J)}))};var e5=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),F1=(Q,Y)=>{let J=Q.closest(e5);if(J&&Y.contains(J))return J;return Q};var Q2=(Q,Y)=>A1([Q],Y),Y2=(Q)=>(Q||"en").split("-")[0].toLowerCase()||"en",J2=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),G2=new Set(["heading","listitem","option","radio"]),X2=(Q)=>{if(Q.type!=="text"||!Q.sourceElement)return!1;let Y=Q.sourceElement.tagName.toUpperCase(),J=(Q.sourceElement.getAttribute("role")||"").toLowerCase();return J2.has(Y)||G2.has(J)},b8=async(Q)=>{let Y=Q.resolveMathSpeech??Q2,{visibleText:J}=Q,G=[],X=0,j=(B)=>{let W=T(B),K=J.indexOf(W,X),U=K>=0?K:X,_=U+W.length;return X=_,{start:U,end:_}},Z=[];for(let B=0;B<Q.chunks.length;B++){let W=Q.chunks[B];if(W.type==="text"){let N=X2(W)?[{text:W.text,offset:0}]:S7(W.text,{locale:Q.language});for(let D of N){let O=T(D.text);if(!O)continue;let P=j(O);G.push({sourceChunkIndex:B,segment:{kind:"prose",spokenText:O,visibleText:O,visibleSpan:P}}),Z.push(O)}continue}let K=j(W.fallbackText),U=await Y(W,{language:Q.language,produceSsml:Q.produceSsml,mathSpeech:Q.mathSpeech}),_=!U.speechText,$=U.speechText||W.fallbackText;G.push({sourceChunkIndex:B,segment:{kind:"math",spokenText:$,mathml:W.mathml,fallbackText:W.fallbackText,visibleSpan:K,usedFallback:_,ssml:U.ssml}}),Z.push($)}return{segments:G,locale:Y2(Q.language),visibleText:J,plainSpeechText:T(Z.join(" "))}};var Z2=(Q,Y,J)=>{let G=new Map;for(let X=Y;X<J;X++){let j=Q.get(X);if(j)G.set(X-Y,j)}return G},z9=async(Q)=>{let Y=O7(Q.contentRoot,Q.textProcessingOptions),J=await b8({chunks:Y.chunks,visibleText:Y.visibleText,language:Q.language,mathSpeech:Q.mathSpeech,produceSsml:Q.produceSsml,resolveMathSpeech:Q.resolveMathSpeech});return{plan:{items:J.segments.map(({segment:X,sourceChunkIndex:j})=>{let Z=Y.chunks[j];if(X.kind==="prose"){let W=Z?.type==="text"?Z.sourceElement??Q.contentRoot:Q.contentRoot;return{segment:X,anchor:{sourceElement:W,regionElement:F1(W,Q.contentRoot),visibleMap:Z2(Y.map,X.visibleSpan.start,X.visibleSpan.end)}}}let B=Z?.type==="math"?Z.sourceElement??null:null;return{segment:X,anchor:{sourceElement:B,regionElement:B}}}),locale:J.locale,visibleText:J.visibleText,plainSpeechText:J.plainSpeechText},containsMathMarkup:Y.containsMathMarkup,visibleText:Y.visibleText}};var j2=(Q,Y)=>{let J=U1({speechText:Q.spokenText,visibleText:Q.spokenText});return{speechText:Q.spokenText,visibleText:Q.visibleText,sourceElement:Y.sourceElement,regionElement:Y.regionElement,regionRange:$1(Y.visibleMap,0,Q.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Y.visibleMap}},S8=(Q,Y)=>{let J=Y.sourceElement;return{speechText:Q.spokenText,visibleText:Q.fallbackText,sourceElement:J,regionElement:Y.regionElement,speechMatchesVisibleText:Q.spokenText===Q.fallbackText,mathAlignment:J?f7({mathElement:J,speechText:Q.spokenText}):void 0}},B2=(Q,Y,J)=>{let G=Y.sourceElement;return{speechText:J,visibleText:Q.fallbackText,sourceElement:G,regionElement:Y.regionElement,speechMatchesVisibleText:!1,mathAlignment:G?f7({mathElement:G,speechText:J}):void 0,plainFallback:S8(Q,Y)}},O9=(Q,Y={})=>Q.items.map(({segment:J,anchor:G})=>{if(J.kind==="prose")return j2(J,G);if(Y.format==="ssml"&&J.ssml)return B2(J,G,J.ssml);return S8(J,G)});var C8="pie-tts-control-handoff";var w;(function(Q){Q.IDLE="idle",Q.LOADING="loading",Q.PLAYING="playing",Q.PAUSED="paused",Q.ERROR="error"})(w||(w={}));var T8=(Q,Y)=>Q===Y||Q.startContainer===Y.startContainer&&Q.startOffset===Y.startOffset&&Q.endContainer===Y.endContainer&&Q.endOffset===Y.endOffset,K2=(Q,Y)=>{if(Q===Y)return!0;if(!Q||!Y||Q.type!==Y.type||Q.quality!==Y.quality)return!1;if(Q.type==="range"&&Y.type==="range")return T8(Q.range,Y.range);if(Q.type==="element"&&Y.type==="element")return Q.element===Y.element;if(Q.type==="text-range"&&Y.type==="text-range")return Q.node===Y.node&&Q.startOffset===Y.startOffset&&Q.endOffset===Y.endOffset;return!1};class c7{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=w.IDLE;ttsConfig={};currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Map;lastError=null;speakRunId=0;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=H9();static debugEnabled=(()=>{try{if(typeof process<"u"&&process.env?.PIE_TTS_DEBUG==="1")return!0}catch{}return globalThis.__PIE_TTS_DEBUG__===!0})();constructor(){}debugLog(Q,Y){if(!c7.debugEnabled)return;if(Y===void 0)console.debug(Q);else console.debug(Q,Y)}clearPlaybackStartBarrier(Q=this.playbackStartBarrierCleanup){if(Q?.(),this.playbackStartBarrierCleanup===Q)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Q){if(this.playbackStartDeferredRunId!==Q||Q!==this.speakRunId)return;this.setState(w.PLAYING);let Y=this.pendingPlaybackStartHighlights.splice(0);for(let J of Y)J()}installPlaybackStartBarrier(Q,Y=!1){this.clearPlaybackStartBarrier();let J=this.provider,G=J&&"onPlaybackStart"in J?J:null;if(!G&&!Y)return null;let X=G?.onPlaybackStart,j=()=>{try{this.notifyPlaybackStarted(Q)}finally{X?.()}};if(G)G.onPlaybackStart=j;this.playbackStartDeferredRunId=Q;let Z=()=>{if(G?.onPlaybackStart===j)G.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Q)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=Z,Z}runWhenPlaybackStarts(Q,Y){if(this.playbackStartDeferredRunId===Q){this.pendingPlaybackStartHighlights.push(Y);return}Y()}async emitTelemetry(Q,Y){try{await this.telemetryReporter?.(Q,Y)}catch(J){console.warn("[TTSService] telemetry callback failed:",J)}}async initialize(Q,Y={}){this.currentProvider=Q,this.ttsConfig={...Y};let J=Y.providerOptions&&typeof Y.providerOptions==="object"?Y.providerOptions:{};this.telemetryReporter=typeof J.__pieTelemetry==="function"?J.__pieTelemetry:null;try{this.provider=await Q.initialize(Y)}catch(G){if(Q.providerId.toLowerCase()==="browser")throw G;if(!this.isBrowserSpeechFallbackAvailable())throw G;if(!await this.switchProviderToBrowser(G,{operation:"tts-initialize"}))throw G}}async updateSettings(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Y=this.provider;if(typeof Y.updateSettings==="function"){let J={...Q,...Q.providerOptions?{providerOptions:{...this.ttsConfig.providerOptions||{},...Q.providerOptions}}:{}};await Y.updateSettings(J),this.ttsConfig={...this.ttsConfig,...J}}else console.warn("[TTSService] Provider does not support dynamic settings updates. Some settings may require reinitialization.")}setHighlightCoordinator(Q){this.highlightCoordinator=Q}setHighlightTargetResolverProvider(Q){return this.highlightTargetResolverProvider=Q,()=>{if(this.highlightTargetResolverProvider===Q)this.highlightTargetResolverProvider=null}}setCatalogResolver(Q){this.catalogResolver=Q}hasSpokenAlternate(Q,Y="en-US"){if(!Q||!this.catalogResolver)return!1;return this.catalogResolver.getAlternative(Q,{type:"spoken",language:Y,useFallback:!0,form:"content"})?.content!==void 0}getHighlightResolverRuntime(){let Q=null;try{Q=this.highlightTargetResolverProvider?.()??null}catch{Q=null}let Y=Q?.context??{},J=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Y,scopeElement:Y.scopeElement??J},resolver:Q?.resolver??null}}getNodeElement(Q){if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:Q.parentElement}isElementWithinScope(Q,Y){if(!Y)return!0;return Q===Y||Y.contains(Q)}isRangeWithinScope(Q,Y){let J=this.getNodeElement(Q.startContainer),G=this.getNodeElement(Q.endContainer);if(!J||!G)return!1;return this.isElementWithinScope(J,Y)&&this.isElementWithinScope(G,Y)}resolveWordHighlightRange(Q){let{context:Y,resolver:J}=this.getHighlightResolverRuntime(),G=Y.scopeElement??this.currentContentElement;try{let X=J?.resolveWordRange?.(Q,Y);if(X&&this.isRangeWithinScope(X,G))return{range:X,remapped:!T8(Q,X)}}catch{}return{range:Q,remapped:!1}}resolveSentenceHighlightTargets(Q){let{context:Y,resolver:J}=this.getHighlightResolverRuntime(),G=Y.scopeElement??this.currentContentElement;try{let X=J?.resolveSentenceRanges?.(Q,Y);if(!X)return{ranges:Q,elements:[]};let j=[],Z=[];for(let B of X){if(typeof Range<"u"&&B instanceof Range){if(!this.isRangeWithinScope(B,G))return{ranges:Q,elements:[]};j.push(B);continue}if(typeof Element<"u"&&B instanceof Element){if(!this.isElementWithinScope(B,G))return{ranges:Q,elements:[]};Z.push(B);continue}return{ranges:Q,elements:[]}}return{ranges:j,elements:Z}}catch{return{ranges:Q,elements:[]}}}createTextRange(Q,Y,J){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let G=document.createRange();if(G.setStart(Q,Y),G.setEnd(Q,J),G.startContainer!==Q||G.endContainer!==Q)return null;return G}catch{return null}}paintTTSWordRange(Q){if(!this.highlightCoordinator)return;try{if(Q.startContainer===Q.endContainer&&Q.startContainer.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(Q.startContainer,Q.startOffset,Q.endOffset);return}}catch{}this.highlightCoordinator.highlightRange(Q,u.TTS_WORD,_7.YELLOW)}paintTTSSentenceRanges(Q){if(!this.highlightCoordinator)return;let{ranges:Y,elements:J}=this.resolveSentenceHighlightTargets(Q);if(J.length>0&&Y.length===0&&this.highlightCoordinator.highlightTTSSentenceElements){this.highlightCoordinator.highlightTTSSentenceElements(J);return}let G=[...Y];for(let X of J){let j=document.createRange();j.selectNodeContents(X),G.push(j)}this.highlightCoordinator.highlightTTSSentence(G)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}getTextProcessingOptions(Q){let J=(this.ttsConfig.providerOptions||{}).textNormalization||{},G=J.boundarySpacingMode,X=G==="none"||G==="alnum"||G==="segmenterPreferred"?G:void 0;return{locale:Q||(typeof J.locale==="string"?J.locale:void 0),boundarySpacingMode:X}}getMathSpeechOptions(){let Y=(this.ttsConfig.providerOptions||{}).mathSpeech;return j7(Y)}buildPositionMap(Q,Y,J){this.normalizedToDOM.clear();let{text:G,map:X}=F7(Q,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!c7.debugEnabled)return;this.debugLog("[TTSService] Text comparison:",{spokenLength:Y.length,normalizedDomLength:G.length,match:Y===G,spokenPreview:Y.substring(0,150),normalizedPreview:G.substring(0,150),differAtIndex:Y===G?null:(()=>{for(let j=0;j<Math.min(Y.length,G.length);j++)if(Y[j]!==G[j])return{index:j,spokenChar:Y[j],normalizedChar:G[j],spokenContext:Y.substring(Math.max(0,j-20),j+20),normalizedContext:G.substring(Math.max(0,j-20),j+20)};return null})()}),this.debugLog("[TTSService] Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Y.length,normalizedDomLength:G.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Y.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([j,{node:Z,offset:B}])=>({pos:j,offset:B,char:Z.textContent?.[B],expected:Y[j]}))})}getStructuralPauseProfile(){let Y=(this.ttsConfig.providerOptions||{}).structuralPauses||{},J=Y.units||{},G=(X,j)=>{if(typeof X==="number"&&Number.isFinite(X))return X;if(typeof X==="string"&&X.trim()){let Z=Number(X);return Number.isFinite(Z)?Z:j}return j};return{baseMs:G(Y.baseMs,280),units:{minor:G(J.minor,0.65),section:G(J.section,1),major:G(J.major,1.35)},minMs:G(Y.minMs,120),maxMs:G(Y.maxMs,900)}}resolvePauseMsFromUnits(Q){let Y=this.getStructuralPauseProfile(),J=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),G=Y.baseMs*Math.max(0,Q)/J;return Math.max(Y.minMs,Math.min(Y.maxMs,Math.round(G)))}resolveHighlightMode(){let Y=(this.ttsConfig.providerOptions||{}).highlightMode;if(Y==="word"||Y==="sentence")return Y;if((this.currentProvider?.providerId||"").toLowerCase()==="browser")return"sentence";return this.currentProvider?.getCapabilities().supportsWordBoundary??!1?"word":"sentence"}hasExplicitBreakSemantics(Q){if(!Q.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(Q)}isElementHidden(Q){return X9(Q)}getBoundaryStrength(Q){let Y=Number(Q.getAttribute("data-tts-break-ms"));if(Number.isFinite(Y)&&Y>0)return"major";let J=Q.tagName.toUpperCase();if(J.match(/^H[1-6]$/))return"major";let G=(Q.getAttribute("role")||"").toLowerCase();if(G==="heading")return"major";if(G==="listitem"||G==="row"||G==="option"||G==="radio"||J==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(Q).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(Q,Y){let J=Q.parentElement,G=null;while(J&&J!==Y){if(this.isElementHidden(J))return null;let j=Number(J.getAttribute("data-tts-break-ms"));if(Number.isFinite(j)&&j>0)return{anchor:J,units:j/this.getStructuralPauseProfile().baseMs};let Z=(J.getAttribute("role")||"").toLowerCase(),B=J.tagName.toUpperCase();if(B.match(/^H[1-6]$/)||Z==="heading"||Z==="listitem"||B==="LI"){G=J;break}if(!G){if(typeof window<"u"){let W=window.getComputedStyle(J).display;if(W==="block"||W==="list-item"||W.startsWith("table")||W==="flex"||W==="grid")G=J}}J=J.parentElement}if(!G)return null;let X=this.getBoundaryStrength(G);return{anchor:G,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Q,Y,J=0){let G=this.collectSpeechPlanBoundaries(Q,Y);if(J===0)return this.createSpeechPlanSegments(Y,G);let X=new Map;for(let[j,Z]of G)X.set(j-J,Z);return this.createSpeechPlanSegments(Y,X)}collectSpeechPlanBoundaries(Q,Y){let J=new Map,{map:G}=F7(Q,this.getTextProcessingOptions()),X=this.createNodeStartOffsets(G),j=document.createTreeWalker(Q,NodeFilter.SHOW_TEXT),Z=j.nextNode(),B=null;while(Z){let W=Z,K=W.parentElement;if(K&&!this.isElementHidden(K)&&!W1(W)){let U=this.getBoundaryAnchor(W,Q),_=X.get(W);if(U&&_!==void 0&&U.anchor!==B&&_>0)J.set(_,Math.max(J.get(_)||0,U.units)),B=U.anchor}Z=j.nextNode()}return J}createNodeStartOffsets(Q){let Y=new Map;for(let[J,G]of Q.entries())if(!Y.has(G.node))Y.set(G.node,J);return Y}createSpeechPlanSegments(Q,Y){let J=Array.from(Y.keys()).filter((W)=>W>0&&W<Q.length).sort((W,K)=>W-K),G=[],X=0;for(let W of J){let K=Q.substring(X,W),U=K.match(/^\s*/)?.[0].length||0,_=K.match(/\s*$/)?.[0].length||0,$=X+U,N=W-_;if(N>$){let D=Q.substring($,N);G.push({text:D,startOffset:$,pauseMsAfter:this.resolvePauseMsFromUnits(Y.get(W)||0)})}X=W}let Z=Q.substring(X).match(/^\s*/)?.[0].length||0,B=X+Z;if(B<Q.length)G.push({text:Q.substring(B).trimEnd(),startOffset:B,pauseMsAfter:0});return G.filter((W)=>W.text.trim().length>0)}segmentSentences(Q){let Y=this.ttsConfig.providerOptions?.locale||void 0;return S7(Q,{locale:Y})}createSeekSegmentsFromText(Q){return this.segmentSentences(Q).map((Y)=>{let J=Y.text.match(/^\s*/)?.[0].length||0;return{text:Y.text.trim(),startOffset:Y.offset+J,pauseMsAfter:0}}).filter((Y)=>Y.text.length>0)}splitSegmentsAtBoundaries(Q,Y,J){if(Q.length===0||Y.length===0)return Q;let G=Array.from(new Set(Y)).filter((j)=>Number.isFinite(j)&&j>0).sort((j,Z)=>j-Z);if(G.length===0)return Q;let X=[];for(let j of Q){let Z=j.startOffset,B=j.startOffset+j.text.length,W=G.filter((U)=>U>Z&&U<B);if(W.length===0){X.push(j);continue}let K=Z;for(let U of[...W,B]){let _=J.substring(K,U),$=_.match(/^\s*/)?.[0].length||0,N=_.match(/\s*$/)?.[0].length||0,D=K+$,O=U-N;if(O>D)X.push({text:J.substring(D,O),startOffset:D,pauseMsAfter:0});K=U}}return X}createSentenceHighlightSegments(Q){let Y=this.createSeekSegmentsFromText(Q.contentToSpeak);if(!Q.shouldUsePlan||Q.playbackSegments.length===0)return Y;let J=Q.playbackSegments.map((G)=>G.startOffset).filter((G)=>G>0);return this.splitSegmentsAtBoundaries(Y,J,Q.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Q){let Y=0;return Q.map((J)=>{let G=J.plainFallback?.speechText||(this.hasExplicitBreakSemantics(J.speechText)?J.visibleText:J.speechText)||J.visibleText,X=T(G)||J.visibleText||"",j={text:X,startOffset:Y,pauseMsAfter:0};return Y+=Math.max(1,X.length+1),j})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let Q=0;for(let Y=0;Y<this.seekSegments.length;Y++)if(this.seekSegments[Y].startOffset<=this.currentBoundaryOffset)Q=Y;else break;return Q}async speakWithPlan(Q,Y,J){if(!this.provider||Q.length===0)return;let G=J?.highlightMode==="sentence",X=this.provider;if(!G&&typeof X.speakSegments==="function"){this.currentBoundaryOffset=0;let j=this.provider.onWordBoundary;this.provider.onWordBoundary=(Z,B,W)=>{if(j?.(Z,B,W),Number.isFinite(B))this.currentBoundaryOffset=B};try{await X.speakSegments(Q)}finally{if(Y===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=j}return}this.configureWordBoundaryHighlighting({highlightMode:J?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let j of Q){if(Y!==this.speakRunId)return;if(this.currentBoundaryOffset=j.startOffset,G)this.runWhenPlaybackStarts(Y,()=>{this.highlightSentenceSegment(j.startOffset,j.text)});await this.provider.speak(j.text);let Z=j.pauseMsAfter??0;if(Z>0)await new Promise((B)=>setTimeout(B,Z))}}highlightSentenceSegment(Q,Y){if(!this.highlightCoordinator||typeof document>"u")return;let J=Y.trimEnd().length;if(J<=0)return;let G=Q+this.activeWordBoundaryOffset,X=this.normalizedToDOM.get(G),j=this.normalizedToDOM.get(G+J-1);if(!X||!j)return;let Z=document.createRange();Z.setStart(X.node,X.offset),Z.setEnd(j.node,j.offset+1),this.paintTTSSentenceRanges([Z]),this.activeSentenceStartOffset=Q}getSegmentIndexForOffset(Q,Y){if(Q.length===0)return-1;let J=-1;for(let G=0;G<Q.length;G++)if(Q[G].startOffset<=Y)J=G;else break;return J}highlightSentenceForOffset(Q){let Y=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Y.length===0)return;let J=this.getSegmentIndexForOffset(Y,Q);if(J<0)return;let G=Y[J];if(!G)return;if(this.activeSentenceStartOffset===G.startOffset)return;this.highlightSentenceSegment(G.startOffset,G.text)}findHighlightRange(Q,Y){let J=this.normalizedToDOM.get(Q);if(!J)return console.warn(`[TTSService] No mapping found for start position ${Q}`,{totalMappings:this.normalizedToDOM.size,nearbyMappings:Array.from(this.normalizedToDOM.entries()).filter(([j])=>Math.abs(j-Q)<5).map(([j,{offset:Z,node:B}])=>({pos:j,offset:Z,char:B.textContent?.[Z]}))}),null;let G=Q+Y-1,X=this.normalizedToDOM.get(G);if(!X)return console.warn(`[TTSService] No mapping found for end position ${G}`,{startChar:Q,length:Y,totalMappings:this.normalizedToDOM.size}),null;if(J.node!==X.node)return console.warn("[TTSService] Word spans multiple nodes, highlighting in first node only"),{node:J.node,start:J.offset,end:(J.node.textContent||"").length};return{node:J.node,start:J.offset,end:X.offset+1}}async speak(Q,Y){if(!this.provider)throw Error("TTS service not initialized");let J=++this.speakRunId;this.clearPlaybackStartBarrier();let G=null;try{if(await this.applyLanguageSettings(Y),J!==this.speakRunId)return;let X=await this.resolveSpeechContent(Q,Y);if(J!==this.speakRunId)return;let{contentToSpeak:j,speechText:Z,highlightText:B,normalizedText:W,usedCatalogSpoken:K,speechSource:U,speechMatchesVisibleText:_,speechChunks:$}=X;this.logResolvedSpeechContent({contentToSpeak:j,speechSource:U,catalogId:Y?.catalogId}),this.initializeSpeakTracking(B,Y);let N=Y?.highlightModeOverride||(_?this.resolveHighlightMode():"sentence");this.activeHighlightMode=N,this.activeWordBoundaryOffset=Y?.wordBoundaryOffset||0;let D=this.hasExplicitBreakSemantics(j),O=!!this.currentContentElement&&!K&&!D&&_;if(this.playbackChunks=$?.length?$:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):D||!_?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,W,Y?.wordBoundaryOffset||0):this.createSeekSegmentsFromText(B),this.sentenceHighlightSegments=D?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:O,playbackSegments:this.seekSegments}),this.setState(w.LOADING),G=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Y,highlightMode:N,shouldUsePlan:O,runId:J}),_)this.configureWordBoundaryHighlighting({highlightMode:N,wordBoundaryOffset:Y?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!G)this.setState(w.PLAYING);if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:J,highlightMode:N,contentToSpeak:Z,speechChunks:$}),J!==this.speakRunId)return;this.setState(w.IDLE),this.clearHighlightsAndTracking()}catch(X){let j=X;if(console.error("TTS error:",j),this.lastError=j instanceof Error?j.message:String(j),J!==this.speakRunId)return;throw this.setState(w.ERROR),this.clearHighlightsAndTracking(),j}finally{this.clearPlaybackStartBarrier(G)}}async switchProviderToBrowser(Q,Y){if(!this.currentProvider)return!1;let J=new g7,G=this.currentProvider.providerId,X={};if(this.ttsConfig.rate!==void 0)X.rate=this.ttsConfig.rate;if(this.ttsConfig.pitch!==void 0)X.pitch=this.ttsConfig.pitch;if(this.ttsConfig.mathTokenHighlighting!==void 0)X.mathTokenHighlighting=this.ttsConfig.mathTokenHighlighting;let j=Y?.operation||"tts-initialize",Z=Y?.contentToSpeak??"",B=Z.replace(/\s+/g," ").trim().slice(0,120),W=Z.length>0?{textLength:Z.length,textPreview:B.length<Z.length?`${B}…`:B}:{};try{return this.provider?.stop(),this.currentProvider.destroy(),this.currentProvider=J,this.provider=await J.initialize(X),this.ttsConfig=X,await this.emitTelemetry("pie-tool-runtime-fallback",{toolId:"textToSpeech",operation:j,fromProvider:G,toProvider:J.providerId,reason:Q instanceof Error?Q.message:String(Q),...W}),console.warn("[TTSService] TTS provider initialization failed; switched to browser fallback",{fromProvider:G,reason:Q,...W}),!0}catch(K){return await this.emitTelemetry("pie-tool-runtime-fallback-error",{toolId:"textToSpeech",operation:j,fromProvider:G,toProvider:"browser",errorType:"TTSRuntimeFallbackError",message:K instanceof Error?K.message:String(K)}),console.error("[TTSService] Failed to switch to browser fallback provider",K),!1}}isBrowserSpeechFallbackAvailable(){if(typeof window>"u")return!1;if(!("speechSynthesis"in window))return!1;return typeof globalThis.SpeechSynthesisUtterance==="function"}async applyLanguageSettings(Q){if(!Q?.language||!this.provider)return;let Y=this.ttsConfig.providerOptions||{},J=Y.textNormalization||{},G=Y.segmenter||{},X={...Y,locale:Q.language,textNormalization:{...J,locale:Q.language},segmenter:{...G,locale:Q.language}};if(this.ttsConfig={...this.ttsConfig,providerOptions:X},"updateSettings"in this.provider&&typeof this.provider.updateSettings==="function")await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(Q,Y){let J=T(Q);if(Y?.ignoreCatalogs)return{contentToSpeak:J,speechText:J,visibleText:J,highlightText:J,usedCatalogSpoken:!1,speechSource:"dom-or-input",normalizedText:J,containsMathMarkup:!1,speechMatchesVisibleText:!0};if(Y?.catalogId&&this.catalogResolver){let j=this.catalogResolver.getAlternative(Y.catalogId,{type:"spoken",language:Y.language||"en-US",useFallback:!0,context:Y.catalogContext,form:"content"}),Z=j?.content;if(j&&Z!==void 0){let B=Y?.contentElement?O7(Y.contentElement,this.getTextProcessingOptions(Y.language)).visibleText||J:J,W=T(Z);return this.debugLog(`[TTSService] Using catalog content for "${Y.catalogId}" (${j.language})`),{contentToSpeak:Z,speechText:Z,visibleText:B,highlightText:B,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:W===B}}this.debugLog(`[TTSService] No catalog found for "${Y.catalogId}", falling back to generated TTS`)}let G=Y?.contentElement?this.resolveCatalogComposedSpeechContent(Y.contentElement,J,Y):null;if(G)return G;return{...Y?.contentElement?await this.resolveGeneratedSpeechContent(Y.contentElement,J,Y.language):{contentToSpeak:J,speechText:J,visibleText:J,highlightText:J,normalizedText:J,containsMathMarkup:!1,speechMatchesVisibleText:!0},usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Q,Y,J){if(!this.catalogResolver)return null;let G=this.collectCatalogSpeechChunks(Q,J);if(!G.some((Z)=>Z.sourceElement))return null;let X=T(G.map((Z)=>Z.speechText).join(" ")),j=O7(Q,this.getTextProcessingOptions(J.language)).visibleText||Y;return{contentToSpeak:X,speechText:X,visibleText:j,highlightText:j,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:j,containsMathMarkup:!1,speechMatchesVisibleText:G.every((Z)=>Z.speechMatchesVisibleText),speechChunks:G}}collectCatalogSpeechChunks(Q,Y){let J=[],G="",X=()=>{let K=T(G);if(G="",!K)return;J.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},j=(K)=>{let U=K.getAttribute("data-catalog-idref");if(!U)return null;let _={type:"spoken",language:Y.language||"en-US",useFallback:!0,context:Y.catalogContext},$=this.catalogResolver.getAlternative(U,{..._,form:"payload"}),N=$?.payload?w0({payload:$.payload})??void 0:void 0,O=this.catalogResolver.getAlternative(U,{..._,form:"content"})?.content;if(N===void 0&&O===void 0)return null;return{script:O,audio:N}},Z=(K,U)=>{let _=B(K);if(_.length!==1)return null;let $=_[0],N=O7($,this.getTextProcessingOptions(Y.language)).visibleText||T($.textContent||""),D=(O)=>T(O).replace(/\s+/g,"");return D(N)===D(U)?$:null},B=(K)=>{let U=Array.from(K.querySelectorAll("math"));if(K.localName?.toLowerCase()==="math")return[K,...U];return U},W=(K)=>{if($7(K,Q))return;if(K.nodeType===Node.TEXT_NODE){G+=` ${K.textContent||""}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let U=K,_=j(U);if(_){X();let $=O7(U,this.getTextProcessingOptions(Y.language)),N=$.visibleText||T(U.textContent||""),D=F1(U,Q),O=_.script!==void 0?(()=>{let P=_.script,F=U1({speechText:P,visibleText:N}),L=Z(U,N),C=L?f7({mathElement:L,speechText:P}):void 0,v=C?void 0:B(U).map((k)=>({element:k,alignment:f7({mathElement:k,speechText:P})}));return{speechText:P,visibleText:N,sourceElement:U,regionElement:D,speechMatchesVisibleText:T(P)===N,playbackMode:F.playbackMode,alignment:F,mathAlignment:C,mathAlignments:v,visibleMap:$.map}})():null;if(_.audio){J.push(O?{...O,audio:_.audio,plainFallback:O}:{speechText:N,visibleText:N,sourceElement:U,regionElement:D,speechMatchesVisibleText:!1,visibleMap:$.map,audio:_.audio});return}if(O)J.push(O);return}for(let $ of Array.from(U.childNodes))W($)};return W(Q),X(),J}resolveGeneratedPlaybackFormat(){let Q=this.currentProvider;if(!Q)return"plain";if(Q.providerId?.toLowerCase()==="browser")return"plain";return Q.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(Q,Y,J){let G=this.resolveGeneratedPlaybackFormat(),{plan:X,containsMathMarkup:j,visibleText:Z}=await z9({contentRoot:Q,language:J,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(J),produceSsml:G==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver}),B=Z||Y;if(!j)return{contentToSpeak:B,speechText:B,visibleText:B,highlightText:B,normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:!0};let W=O9(X,{format:G}),K=X.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:B,highlightText:B,normalizedText:B,containsMathMarkup:!0,speechMatchesVisibleText:K===B,speechChunks:W}}logResolvedSpeechContent(Q){let Y=Q.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);this.debugLog("[TTSService] Speak resolved content",{source:Q.speechSource,catalogId:Q.catalogId||null,length:Q.contentToSpeak.length,preview:Y})}initializeSpeakTracking(Q,Y){this.currentText=Q,this.currentContentElement=Y?.contentElement||null,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(Q){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,Q.contentToSpeak,Q.options?.language),Q.highlightMode==="sentence"&&Q.shouldUsePlan)return;let Y=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Q.runId,()=>{if(Y)this.highlightSentenceSegment(Y.startOffset,Y.text),this.debugLog("[TTSService] Applied initial sentence highlighting");else try{let J=document.createRange();J.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([J])}catch{}})}configureWordBoundaryHighlighting(Q){if(!this.provider||Q.highlightMode!=="word"||!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Y,J,G)=>{let X=G||Y.length,j=J+this.currentBoundaryOffset,Z=j+Q.wordBoundaryOffset;this.highlightSentenceForOffset(j);let B=this.findHighlightRange(Z,X);if(B&&this.highlightCoordinator){let W=B.node.textContent?.substring(B.start,B.end)||"";this.debugLog(`[TTSService] Highlighting "${W}" (word: "${Y}") at position ${Z}`);let K=this.createTextRange(B.node,B.start,B.end);if(K)this.paintTTSWordRange(this.resolveWordHighlightRange(K).range);else this.highlightCoordinator.highlightTTSWord(B.node,B.start,B.end)}else console.warn(`[TTSService] Could not find highlight range for position ${Z}, length ${X}`)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Q){let Y=Q.regionElement||Q.sourceElement;if(!Y&&!Q.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Q.regionRange){this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([Q.regionRange]);return}if(!Y)return;let J=document.createRange();J.selectNodeContents(Y),this.highlightCoordinator.clearHighlights?.(u.TTS_WORD),this.paintTTSSentenceRanges([J])}catch{}}highlightCatalogActiveRange(Q){if(!this.highlightCoordinator)return;this.paintTTSWordRange(this.resolveWordHighlightRange(Q).range)}highlightRenderableRegionTarget(Q){if(!this.highlightCoordinator||!Q||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&K2(this.lastRenderedRegionTarget,Q))return;try{let Y=document.createRange();if(Q.type==="element")Y.selectNodeContents(Q.element);else if(Q.type==="range"){this.paintTTSSentenceRanges([Q.range]),this.lastRenderedRegionTarget=Q;return}else Y.setStart(Q.node,Q.startOffset),Y.setEnd(Q.node,Q.endOffset);this.paintTTSSentenceRanges([Y]),this.lastRenderedRegionTarget=Q}catch{}}highlightRenderableActiveTarget(Q){if(!this.highlightCoordinator||typeof document>"u")return;if(!Q){this.highlightCoordinator.clearHighlights(u.TTS_WORD);return}if(Q.type==="text-range"){let X=this.createTextRange(Q.node,Q.startOffset,Q.endOffset);if(X)this.paintTTSWordRange(this.resolveWordHighlightRange(X).range);else this.highlightCoordinator.highlightTTSWord(Q.node,Q.startOffset,Q.endOffset);return}if(Q.type==="range"){this.highlightCatalogActiveRange(Q.range);return}let Y=document.createRange();Y.selectNodeContents(Q.element);let J=this.resolveWordHighlightRange(Y);if(J.remapped){this.paintTTSWordRange(J.range);return}let G=Q.element.childNodes.length===1?Q.element.firstChild:null;if(Q.quality==="semantic-token"&&G?.nodeType===Node.TEXT_NODE){this.highlightCoordinator.highlightTTSWord(G,0,G.textContent?.length||0);return}this.highlightCoordinator.highlightTTSWordElement?.(Q.element)}renderHighlightDecision(Q){this.highlightRenderableRegionTarget(Q.regionTarget),this.highlightRenderableActiveTarget(Q.activeTarget)}async speakCatalogChunk(Q,Y){try{await this.speakCatalogChunkOnce(Q,Y)}catch(J){if(Q.plainFallback&&Y===this.speakRunId){if(this.debugLog("[TTSService] SSML chunk speak failed; retrying plain text",{message:J instanceof Error?J.message:String(J)}),this.playbackStartDeferredRunId===Y&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.setState(w.PLAYING);await this.speakCatalogChunkOnce(Q.plainFallback,Y);return}throw J}}async playRecordedAudio(Q,Y){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let J=Q.sources[0],G=document.createElement("audio");G.preload="auto",G.src=q2(J.src,Q.fragment),G.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,j)=>{let Z,B=!1,W=!1,K=()=>{if(W||B)return;B=!0,Y?.()},U=()=>{if(G.removeEventListener("ended",_),G.removeEventListener("error",$),G.removeEventListener("playing",K),Z?.(),this.activeRecordedAudio?.element===G)this.activeRecordedAudio=null},_=()=>{if(W)return;W=!0,U(),X()},$=()=>{if(W)return;W=!0,U(),j(Error(`[tts] recorded audio failed to play: ${J.src}`))};this.activeRecordedAudio={element:G,cancel:()=>{if(W)return;W=!0,U(),G.pause(),X()}},G.addEventListener("ended",_),G.addEventListener("error",$),G.addEventListener("playing",K),Z=W2(G,Q.fragment,_),Promise.resolve(G.play()).then(K).catch($)}).finally(()=>{if(this.activeRecordedAudio?.element===G)this.activeRecordedAudio=null;G.pause(),G.removeAttribute("src")})}cancelRecordedAudio(){let Q=this.activeRecordedAudio;if(!Q)return;this.activeRecordedAudio=null,Q.cancel()}async speakCatalogChunkOnce(Q,Y){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Q.audio){this.runWhenPlaybackStarts(Y,()=>{this.highlightCatalogRegion(Q)}),await this.playRecordedAudio(Q.audio,()=>{this.notifyPlaybackStarted(Y)});return}let J=Q.regionElement||Q.sourceElement||this.currentContentElement,G=J?E8({contentRoot:J,chunks:[Q]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,j=G?R8({chunks:[G],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Y,()=>{if(j&&G&&Q.mathAlignment)this.renderHighlightDecision(j.resolveInitial(G.id));else this.highlightCatalogRegion(Q)}),!(Q.sourceElement&&(Q.mathAlignment&&Q.mathAlignment.speech.tokens.length>0||Q.mathAlignments&&Q.mathAlignments.length>0||Q.alignment&&Q.visibleMap&&(Q.playbackMode==="exact-word"||Q.playbackMode==="anchor-span")))){let U=this.provider,_=U.onWordBoundary;U.onWordBoundary=void 0;try{await U.speak(Q.speechText)}finally{if(this.provider===U&&Y===this.speakRunId&&U.onWordBoundary===void 0)U.onWordBoundary=_}return}let B=this.provider,W=B.onWordBoundary,K=(U,_,$)=>{if(Y!==this.speakRunId)return;if(j&&G){let N=G.offsetSpace==="unsupported"?"unknown":G.offsetSpace;this.renderHighlightDecision(j.resolveBoundary({chunkId:G.id,word:U,position:_,length:$,providerOffsetSpace:N}));return}};B.onWordBoundary=K;try{await B.speak(Q.speechText)}finally{if(this.provider===B&&Y===this.speakRunId&&B.onWordBoundary===K)B.onWordBoundary=W}}async executeSpeakPlayback(Q){if(Q.speechChunks?.length&&this.provider){for(let Y=0;Y<Q.speechChunks.length;Y++){if(Q.runId!==this.speakRunId)return;let J=this.seekSegments[Y];if(J)this.currentBoundaryOffset=J.startOffset;let G=Q.speechChunks[Y];await this.speakCatalogChunk(G,Q.runId)}return}if(Q.shouldUsePlan&&this.currentContentElement){let Y=this.seekSegments;if(Y.length>0)await this.speakWithPlan(Y,Q.runId,{highlightMode:Q.highlightMode});else if(this.provider)await this.provider.speak(Q.contentToSpeak);return}if(this.provider)await this.provider.speak(Q.contentToSpeak)}clearHighlightsAndTracking(){if(this.pendingPlaybackStartHighlights=[],this.activePlaybackRate=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null}selectMappedRangeText(Q,Y){if(typeof Q.comparePoint!=="function")return null;let{text:J,map:G}=F7(Y,this.getTextProcessingOptions()),X=-1,j=-1;for(let[K,{node:U,offset:_}]of G){if(K>=J.length)continue;let $=!1;try{$=Q.comparePoint(U,_)===0&&Q.comparePoint(U,Math.min(_+1,U.length))===0}catch{$=!1}if(!$)continue;if(X===-1||K<X)X=K;if(K>j)j=K}if(X===-1)return null;let Z=J.slice(X,j+1),B=Z.length-Z.trimStart().length,W=Z.trim();return W?{text:W,offset:X+B}:null}async speakRange(Q,Y){if(!this.provider)throw Error("TTS service not initialized");if(W1(Q.commonAncestorContainer)){console.warn("[tts] selection lies inside content marked not-to-be-spoken; nothing was spoken. Selecting a node and pressing read-aloud must not become a way around suppression.");return}let G=Y?.contentRoot||null;if(!G){let K=Q.commonAncestorContainer;G=K.nodeType===Node.ELEMENT_NODE?K:K.parentElement}if(!G)return;let X=Z9(Q,G),j=X.text.trim();if(!j){if(X.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return}let Z=this.selectMappedRangeText(Q,G),B=j,W=Z?.offset??0;if(Z)B=Z.text;else{let K=document.createRange();K.selectNodeContents(G),K.setEnd(Q.startContainer,Q.startOffset);let U=Z9(K,G).text,_=T(U);W=_.length+(/\s$/.test(U)&&_?1:0)}this.debugLog("[TTSService] speakRange offset calculation:",{selectedText:B,mapped:!!Z,offset:W,rootTag:G.tagName}),await this.speak(B,{contentElement:G,ignoreCatalogs:!0,wordBoundaryOffset:W})}pause(){if(!this.provider)return;if(this.state===w.PLAYING)this.activeRecordedAudio?.element.pause(),this.provider.pause(),this.setState(w.PAUSED)}resume(){if(!this.provider)return;if(this.state===w.PAUSED){let Q=this.activeRecordedAudio?.element;if(Q)Promise.resolve(Q.play()).catch(()=>{});this.provider.resume(),this.setState(w.PLAYING)}}normalizePlaybackRate(Q){if(!Number.isFinite(Q))return 1;return Math.max(0.25,Math.min(4,Q))}async restartFromSeekIndex(Q){if(!this.provider||this.seekSegments.length===0)return;let Y=Math.max(0,Math.min(this.seekSegments.length-1,Q)),J=this.playbackChunks.length?this.playbackChunks.slice(Y):null;this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop();let G=++this.speakRunId,X=this.seekSegments.slice(Y);this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.setState(w.LOADING);let j=this.installPlaybackStartBarrier(G,!!J?.[0]?.audio);if(!j)this.setState(w.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),J)for(let Z=0;Z<J.length;Z++){if(G!==this.speakRunId)return;let B=Y+Z,W=this.seekSegments[B];if(W)this.currentBoundaryOffset=W.startOffset;await this.speakCatalogChunk(J[Z],G)}else await this.speakWithPlan(X,G,{highlightMode:this.activeHighlightMode});if(G!==this.speakRunId)return;this.setState(w.IDLE),this.clearHighlightsAndTracking()}catch(Z){if(G!==this.speakRunId)return;throw this.lastError=Z instanceof Error?Z.message:String(Z),this.setState(w.ERROR),this.clearHighlightsAndTracking(),Z}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Q){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Y=this.normalizePlaybackRate(Q),J=this.pendingPlaybackRateRequest;if(J?.rate===Y){await J.promise;return}let G=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let B=this.speakRunId;if(G!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:B};let W=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Y===W)return{didUpdate:!1,playbackRunId:B};return await this.updateSettings({rate:Y}),{didUpdate:!0,playbackRunId:B}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let j=X.then(async(B)=>{if(G!==this.playbackRateRequestId||B.playbackRunId!==this.speakRunId)return;let W=this.activePlaybackRate!==null&&this.activePlaybackRate!==Y;if(!B.didUpdate&&!W)return;if(this.state!==w.PLAYING&&this.state!==w.LOADING||!this.currentText||this.seekSegments.length===0||this.hasExplicitBreakSemantics(this.currentText))return;await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex())}),Z;Z=j.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===Z)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Y,promise:Z},await Z}async seekBy(Q){if(!this.provider||!this.currentText)return;if(this.state!==w.PLAYING&&this.state!==w.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Y=Number.isFinite(Q)?Math.trunc(Q):0;if(Y===0)return;let J=this.getCurrentSeekSegmentIndex(),G=Math.max(0,Math.min(this.seekSegments.length-1,J+Y));if(G===J)return;await this.restartFromSeekIndex(G)}async seekForward(Q=1){let Y=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(Y)}async seekBackward(Q=1){let Y=Number.isFinite(Q)?Math.max(1,Math.trunc(Q)):1;await this.seekBy(-Y)}stop(){if(!this.provider)return;if(this.speakRunId+=1,this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.provider.onWordBoundary=void 0,this.provider.stop(),this.setState(w.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null,this.activePlaybackRate=null}requestControlHandoff(){if(typeof window>"u")return;let Q={source:"host"};window.dispatchEvent(new CustomEvent(C8,{detail:Q}))}isPlaying(){return this.state===w.PLAYING}isPaused(){return this.state===w.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(Q,Y){if(!this.listeners.has(Q))this.listeners.set(Q,new Set);this.listeners.get(Q).add(Y)}offStateChange(Q,Y){let J=this.listeners.get(Q);if(J){if(J.delete(Y),J.size===0)this.listeners.delete(Q)}}setState(Q){if(this.state===Q)return;let Y=this.state;this.state=Q;for(let J of this.listeners.values())for(let G of J)G(Q);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q}),Q===w.PLAYING){let J=Y===w.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(J,{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q});return}if(Q===w.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q});return}if(Q===w.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q,message:this.lastError||void 0});return}if(Q===w.IDLE&&(Y===w.PLAYING||Y===w.PAUSED||Y===w.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",providerId:"tts",previousState:Y,state:Q})}}var U2=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),P9=(Q)=>Q&&typeof Q==="object"?Q:{},V2=(Q)=>Q==="polly"||Q==="google"||Q==="server",i=(Q,Y)=>Q===void 0?Y:Q,A2=(Q,Y="left-aligned")=>typeof Q==="string"&&U2.has(Q)?Q:Y,YY=Object.freeze([0.8,1.25]),JY=Object.freeze([{rate:0.8,label:"Slow",ariaLabel:"Slow speed"},{rate:1,label:"Normal",ariaLabel:"Normal speed",default:!0},{rate:1.25,label:"Fast",ariaLabel:"Fast speed"}]);var GY=Object.freeze([0.8,1,1.25]);var _2=(Q)=>{let Y={...Q,layoutMode:A2(Q.layoutMode)},J=Q.backend||"browser";if(!V2(J))return Y;let G={...Y,apiEndpoint:i(Y.apiEndpoint,"/api/tts"),transportMode:i(Y.transportMode,"pie"),endpointValidationMode:i(Y.endpointValidationMode,"voices"),validateEndpoint:i(Y.validateEndpoint,!0),includeAuthOnAssetFetch:i(Y.includeAuthOnAssetFetch,!1),rate:i(Y.rate,1),language:i(Y.language,"en-US")};if(J==="polly")return{...G,defaultVoice:i(G.defaultVoice,"Joanna"),engine:i(G.engine,"neural"),format:i(G.format,"mp3"),speechMarksMode:i(G.speechMarksMode,"word+sentence")};if(J==="google")return{...G,defaultVoice:i(G.defaultVoice,"en-US-Wavenet-A")};return G},y8=(Q)=>{let Y=P9(Q),J=P9(Y.settings),{provider:G,...X}={...Y,...J};return _2({...X,...typeof G==="string"?{provider:G}:{}})},L9=(Q)=>Q.backend||"browser",$2=(Q,Y)=>{if(Y==="polly"||Y==="google")return Y;if(Y==="server")return Q.serverProvider||Q.provider;return Q.serverProvider||Q.provider},F2=(Q,Y)=>Q.transportMode||(Y==="custom"?"custom":"pie"),f8=(Q)=>{let Y=L9(Q),J=$2(Q,Y),G=F2(Q,J),X=j7(Q.mathSpeech);return{voice:Q.defaultVoice,rate:Q.rate,pitch:Q.pitch,providerOptions:{...P9(Q.providerOptions),...Q.language?{locale:Q.language}:{},...Y==="polly"&&Q.engine?{engine:Q.engine}:{},...Y==="polly"&&typeof Q.sampleRate==="number"?{sampleRate:Q.sampleRate}:{},...Y==="polly"&&Q.format?{format:Q.format}:{},...Y==="polly"?{speechMarkTypes:Q.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...G==="custom"&&typeof Q.cache==="boolean"?{cache:Q.cache}:{},...G==="custom"&&Q.speedRate?{speedRate:Q.speedRate}:{},...G==="custom"&&Q.lang_id?{lang_id:Q.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Q.apiEndpoint,provider:J,language:Q.language,transportMode:G,endpointMode:Q.endpointMode,endpointValidationMode:Q.endpointValidationMode,includeAuthOnAssetFetch:Q.includeAuthOnAssetFetch,assetOrigins:Q.assetOrigins,credentials:Q.credentials,headers:Q.headers,validateEndpoint:Q.validateEndpoint,...typeof Q.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Q.mathTokenHighlighting}:{}}};class H1{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Q,Y,J){try{await Q.onTelemetry?.(Y,J)}catch(G){console.warn("[ToolProviderRegistry] Telemetry callback failed:",G)}}register(Q,Y){if(this.providers.has(Q)){console.warn(`[ToolProviderRegistry] Provider "${Q}" already registered, skipping`);return}if(this.providers.set(Q,Y.provider),this.configs.set(Q,Y),this.initialized.set(Q,!1),console.log(`[ToolProviderRegistry] Registered provider "${Q}" (${Y.provider.providerName})`),Y.lazy===!1)this.initialize(Q).catch((J)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Q}":`,J)})}async initialize(Q){if(this.initialized.get(Q))return;let Y=this.initializationPromises.get(Q);if(Y)return Y;let J=this._doInitialize(Q);this.initializationPromises.set(Q,J);try{await J}finally{this.initializationPromises.delete(Q)}}async _doInitialize(Q){let Y=this.providers.get(Q),J=this.configs.get(Q);if(!Y||!J)throw Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);let G={...J.config},X=(Z)=>{if(!Z||typeof Z!=="object")return"unknown";let B=Z;return(typeof B.backend==="string"?B.backend:typeof B.provider==="string"?B.provider:typeof B.serverProvider==="string"?B.serverProvider:typeof B.providerId==="string"?B.providerId:"")||"unknown"},j=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize"}),Y.requiresAuth&&J.authFetcher){let Z=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch"}),console.log(`[ToolProviderRegistry] Fetching auth for "${Q}"...`);try{let B=await J.authFetcher();G={...G,...B},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch",duration:Date.now()-Z})}catch(B){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Q,providerId:Q,backend:X(G),operation:"auth-fetch",duration:Date.now()-Z,errorType:"ProviderAuthFetchError",message:B instanceof Error?B.message:String(B)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Q}":`,B),Error(`Failed to fetch auth credentials for provider "${Q}"`)}}try{await Y.initialize(G),this.initialized.set(Q,!0),await this.emitTelemetry(J,"pie-tool-init-success",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize",duration:Date.now()-j}),console.log(`[ToolProviderRegistry] Provider "${Q}" initialized`)}catch(Z){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Q,providerId:Q,backend:X(G),operation:"provider-initialize",duration:Date.now()-j,errorType:"ProviderInitializationError",message:Z instanceof Error?Z.message:String(Z)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Q}":`,Z),Z}}async getProvider(Q,Y=!0){let J=this.providers.get(Q);if(!J)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Q,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Q}" not registered`);if(Y&&!this.initialized.get(Q))console.log("[ToolProviderRegistry] Auto-initializing provider:",Q),await this.initialize(Q);return J}getProvidersByCategory(Q){return Array.from(this.providers.entries()).filter(([Y,J])=>J.category===Q).map(([Y])=>Y)}getProviderIds(){return Array.from(this.providers.keys())}has(Q){return this.providers.has(Q)}isInitialized(Q){return this.initialized.get(Q)===!0}isInitializing(Q){return this.initializationPromises.has(Q)}async unregister(Q){let Y=this.providers.get(Q);if(Y){let J=this.initializationPromises.get(Q);if(J)try{await J}catch{}Y.destroy(),this.providers.delete(Q),this.configs.delete(Q),this.initialized.delete(Q),this.initializationPromises.delete(Q),console.log(`[ToolProviderRegistry] Unregistered provider "${Q}"`)}}async destroy(){let Q=Array.from(this.providers.keys());await Promise.all(Q.map((Y)=>this.unregister(Y))),console.log("[ToolProviderRegistry] Registry destroyed")}}class w9{targets=new Set;changeListeners=new Set;registerTarget(Q){return this.targets.add(Q),this.notifyChange(),()=>{if(!this.targets.delete(Q))return;this.notifyChange()}}canRequest(Q,Y){return this.findTarget(Q,Y)!==null}request(Q){let Y=this.findTarget(Q.toolId,Q.level);if(!Y)return!1;try{Y.open(Q.toolId,Q.params)}catch(J){return console.error(`[ToolRequestRegistry] Target failed to open "${Q.toolId}":`,J),!1}return!0}onTargetsChange(Q){return this.changeListeners.add(Q),()=>{this.changeListeners.delete(Q)}}findTarget(Q,Y){let J=this.findTargetAtLevel(Q,Y??"section");if(J||Y!==void 0)return J;for(let G of this.targets){if(G.level==="section")continue;if(this.hostsTool(G,Q))return G}return null}findTargetAtLevel(Q,Y){for(let J of this.targets){if(J.level!==Y)continue;if(this.hostsTool(J,Q))return J}return null}hostsTool(Q,Y){try{return Q.hostsTool(Y)===!0}catch(J){return console.warn(`[ToolRequestRegistry] Target at level "${Q.level}" failed the host check for "${Y}":`,J),!1}}notifyChange(){for(let Q of this.changeListeners)try{Q()}catch(Y){console.warn("[ToolRequestRegistry] Target change listener threw:",Y)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}var H2=(Q)=>`No assessment is bound, so no policy source could grant "${Q}"`;function R9(Q,Y,J,G){return{featureId:Q,granted:!1,action:"block",rule:Y,precedence:0,sourceType:"host",reason:Y==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${J.join(", ")})`,required:!1,assessmentBound:G.assessmentBound}}function x8(Q,Y,J){let G=Y.decisions[0],X=Array.from(Y.perToolFlags.values())[0],j=G?.action==="enable",Z=G?.reason??`Feature "${Q}" not configured`;return{featureId:Q,granted:j,action:G?.action??"skip",rule:G?.rule??"pnp-support",precedence:G?.precedence??6,sourceType:G?.sourceType??"system",reason:J.assessmentBound||j?Z:H2(Q),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:J.assessmentBound}}class E9{provenance;stepCounter=0;constructor(Q){this.provenance={contextId:Q,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(Q,Y){let J={id:Y.id,name:Y.name??Y.id};switch(Q){case"organization":this.provenance.sources.organization={...J,pnpDefaults:Y.config};break;case"assessment":this.provenance.sources.assessment={...J,settings:Y.config};break;case"section":this.provenance.sources.section={...J,settings:Y.config};break;case"item":this.provenance.sources.item={...J,settings:Y.config};break;case"student":this.provenance.sources.student={id:Y.id,pnpProfile:Y.config};break;case"host":this.provenance.sources.host={id:Y.id,config:Y.config};break}return this}addDecision(Q){let Y={step:++this.stepCounter,precedence:Q.precedence,rule:Q.rule,featureId:Q.featureId,action:Q.action,source:{type:Q.sourceType,id:Q.sourceId,name:Q.sourceName},reason:Q.reason,value:Q.value,timestamp:new Date};this.provenance.decisionLog.push(Y);let J=this.provenance.features.get(Q.featureId);if(!J)J={featureId:Q.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Q.featureId,J);if(J.allDecisions.push(Y),Q.action==="advisory"){if(J.finalState==="not-configured")J.finalState="advisory-only"}else if(Q.action!=="skip"){if(!J.winningDecision||Y.precedence<J.winningDecision.precedence)J.winningDecision=Y,J.finalState=Y.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[Q.sourceType]=(this.provenance.summary.bySource[Q.sourceType]||0)+1,this.provenance.summary.byRule[Q.rule]=(this.provenance.summary.byRule[Q.rule]||0)+1,this}reconcileFinalStates(Q){for(let Y of Q){let J=this.provenance.features.get(Y);if(!J){J={featureId:Y,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Y,J);continue}J.finalState="enabled"}for(let Y of this.provenance.features.values()){if(Q.has(Y.featureId))continue;let J=Y.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),G=Y.allDecisions.some((X)=>X.action==="advisory");if(J)Y.finalState="blocked";else if(G)Y.finalState="advisory-only";else Y.finalState="not-configured"}return this}build(){for(let Q of this.provenance.features.values())Q.explanation=D2(Q);for(let Q of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,Q.finalState==="enabled")this.provenance.summary.enabled++;else if(Q.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function D2(Q){if(!Q.winningDecision){if(Q.finalState==="advisory-only"){let j=Q.allDecisions.find((Z)=>Z.action==="advisory");return j?`Feature "${Q.featureId}" was kept in its host-decided state; ${j.reason}`:`Feature "${Q.featureId}" carries an advisory note.`}return`Feature "${Q.featureId}" was not configured at any level.`}let Y=Q.winningDecision,J=Y.source.name||Y.source.type,G=`Feature "${Q.featureId}" is ${Q.finalState}.
|
|
215
|
+
`,$Z=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet"),AZ=Symbol.for("@pie-players/pie-assessment-toolkit/highlight-stylesheet-adopted"),DZ=(Z)=>!!Z&&typeof Z.replaceSync==="function",c6=()=>{let Z=globalThis,Q=Z[$Z];if(DZ(Q))return Q;let J=globalThis.CSSStyleSheet;if(typeof J!=="function")return null;try{let Y=new J;if(!DZ(Y))return null;return Y.replaceSync(zZ),Z[$Z]=Y,Y}catch{return null}},K0=(Z)=>{let Q=Z?.getRootNode?.();if(!m(Q))return;let J=Q,Y=J.adoptedStyleSheets;if(!Y||typeof Y!=="object")return;let X=Array.from(Y),G=J[AZ];if(G&&X.includes(G))return;let j=c6();if(!j)return;try{J.adoptedStyleSheets=[...X,j],J[AZ]=j}catch{}},S1="tts-word",T1="tts-sentence",d9=(Z)=>`annotation-${Z}`,C9=(Z)=>{let Q=CSS.highlights.get(Z);if(Q)return Q;let J=new Highlight;return CSS.highlights.set(Z,J),J},V0=(Z,Q)=>{let J=CSS.highlights.get(Z);if(!J)return;for(let Y of Q)J.delete(Y)},FZ=(Z)=>{let Q=Z[0]?.startContainer;if(!Q)return null;return Q.nodeType===Node.ELEMENT_NODE?Q:d(Q)},G9={source:null,override:null};class $0{ttsWordRanges=new Set;ttsSentenceRanges=new Set;ttsWordElementHighlights=new Set;ttsSentenceElementHighlights=new Set;annotations=new Map;ttsStyleSource=null;nextAnnotationId=1;supported=!1;rangeSerializer;themeObserver=null;constructor(){if(this.rangeSerializer=new b1,typeof CSS>"u"||!("highlights"in CSS)){console.warn("CSS Custom Highlight API not supported (SSR or unsupported browser)");return}this.supported=!0,this.initializeHighlights(),this.registerStyles(),this.applyAdaptiveTTSStyle(),this.setupThemeObservation()}setupThemeObservation(){if(typeof document>"u")return;if(typeof MutationObserver>"u")return;let Z=()=>this.applyAdaptiveTTSStyle();this.themeObserver=new MutationObserver(Z),this.themeObserver.observe(document.documentElement,{attributes:!0,attributeFilter:["style","data-theme","data-color-scheme","class"]});for(let Q of document.querySelectorAll("pie-theme"))this.themeObserver.observe(Q,{attributes:!0,attributeFilter:["theme","scheme","provider","variables","style","data-theme","data-color-scheme"]})}parseColor(Z){if(!Z)return null;let Q=Z.trim();if(!Q)return null;let J=/^#([a-f\d]{3}|[a-f\d]{6})$/i.exec(Q);if(J){let X=J[1];if(X.length===3)return[parseInt(X[0]+X[0],16),parseInt(X[1]+X[1],16),parseInt(X[2]+X[2],16)];return[parseInt(X.slice(0,2),16),parseInt(X.slice(2,4),16),parseInt(X.slice(4,6),16)]}let Y=/^rgba?\((.+)\)$/i.exec(Q);if(Y){let G=Y[1].replace(/\//g,",").split(/[,\s]+/).map((q)=>q.trim()).filter(Boolean),j=Number(G[0]),B=Number(G[1]),U=Number(G[2]);if(Number.isFinite(j)&&Number.isFinite(B)&&Number.isFinite(U))return[j,B,U]}if(typeof document<"u"){let X=document.createElement("span");if(X.style.color=Q,typeof X.style.color==="string"&&X.style.color){document.body?.appendChild(X);let G=typeof getComputedStyle==="function"?getComputedStyle(X).color:"";X.remove();let j=G.trim();if(j&&j!==Q)return this.parseColor(G)}}return null}relativeLuminance([Z,Q,J]){let Y=(B)=>{let U=B/255;return U<=0.03928?U/12.92:((U+0.055)/1.055)**2.4},X=Y(Z),G=Y(Q),j=Y(J);return 0.2126*X+0.7152*G+0.0722*j}contrastRatio(Z,Q){let J=this.relativeLuminance(Z),Y=this.relativeLuminance(Q),X=Math.max(J,Y),G=Math.min(J,Y);return(X+0.05)/(G+0.05)}blend(Z,Q,J){return[Math.round(Z[0]*J+Q[0]*(1-J)),Math.round(Z[1]*J+Q[1]*(1-J)),Math.round(Z[2]*J+Q[2]*(1-J))]}resolveAdaptiveTTSStyle(Z){let Q=[255,235,59],J=[17,24,39],Y=[255,255,255],X=Z||(typeof document<"u"?document.documentElement:null),G=X&&typeof getComputedStyle==="function"?getComputedStyle(X):null,j=this.parseColor(G?.getPropertyValue("--pie-background")||G?.backgroundColor)||Y,B=this.parseColor(G?.getPropertyValue("--pie-text"))||J,U=G9.override,q=U?this.parseColor(U.color)||Q:this.parseColor(G?.getPropertyValue("--pie-missing"))||Q,K=U?[Math.max(0.3,Math.min(0.95,U.opacity))]:[0.8,0.72,0.68,0.62,0.56,0.5],$=K[K.length-1],D=-1/0;for(let u of K){let Q9=this.blend(q,j,u),H9=this.contrastRatio(Q9,j),_9=this.contrastRatio(Q9,B),M9=H9*1.2+_9*0.8;if(H9>=1.25&&_9>=2.4){$=u;break}if(M9>D)D=M9,$=u}let z=Math.max(0.24,Math.min(0.85,$*0.55)),M=Math.max(0.55,Math.min(0.95,$+0.2)),O=Math.max(0.22,Math.min(0.6,$*0.45)),F=B,w=this.blend(F,j,M),R=this.contrastRatio(w,j),b=this.relativeLuminance(j)>0.45?[0,0,0]:[255,255,255],S=R>=1.35?F:b,h=`rgba(${q[0]}, ${q[1]}, ${q[2]}, ${$})`,C=`rgba(${q[0]}, ${q[1]}, ${q[2]}, ${z})`,U9=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${M})`,K9=`rgba(${S[0]}, ${S[1]}, ${S[2]}, ${O})`;return{wordHighlight:h,sentenceHighlight:C,wordUnderline:U9,wordShadow:K9}}applyAdaptiveTTSStyle(Z){if(typeof document>"u")return;if(Z)this.ttsStyleSource=Z,G9.source=Z;let Q=Z??(G9.source?.isConnected?G9.source:null),J=this.resolveAdaptiveTTSStyle(Q),Y=document.documentElement.style,X=[["--pie-tts-word-highlight",J.wordHighlight],["--pie-tts-sentence-highlight",J.sentenceHighlight],["--pie-tts-line-highlight",J.sentenceHighlight],["--pie-tts-word-underline",J.wordUnderline],["--pie-tts-word-shadow",J.wordShadow]];for(let[G,j]of X){if(Y.getPropertyValue?.(G)===j)continue;Y.setProperty(G,j)}}initializeHighlights(){if(!this.supported)return;C9(S1),C9(T1);for(let Z of Object.values(q0))C9(d9(Z))}registerStyles(){if(!this.supported)return;if(typeof document>"u")return;if(document.getElementById("pie-highlight-styles"))return;let Z=document.createElement("style");Z.id="pie-highlight-styles",Z.textContent=zZ,document.head.appendChild(Z)}highlightTTSWord(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(FZ(Z)),this.clearTTSWord();let Q=C9(S1);for(let J of Z)K0(J.startContainer),Q.add(J),this.ttsWordRanges.add(J);this.highlightTTSWordElementFallbacks(Z.filter((J)=>J.startContainer!==J.endContainer||J.startContainer.nodeType!==Node.TEXT_NODE))}highlightTTSWordElement(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z),K0(Z),this.clearTTSWord(),Z.setAttribute("data-pie-tts-word-element","true"),this.ttsWordElementHighlights.add(Z)}highlightTTSSentence(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(FZ(Z)),this.clearTTSSentence();let Q=C9(T1);for(let J of Z)K0(J.startContainer),Q.add(J),this.ttsSentenceRanges.add(J);this.highlightTTSElementFallbacks(Z)}highlightTTSSentenceElements(Z){if(!this.supported)return;this.applyAdaptiveTTSStyle(Z[0]||null),this.clearTTSSentence();for(let Q of Z)K0(Q),Q.setAttribute("data-pie-tts-sentence-element","true"),this.ttsSentenceElementHighlights.add(Q)}static SENTENCE_FALLBACK_SELECTOR="math, mjx-container, svg, img, canvas, [role='img']";static WORD_FALLBACK_SELECTOR="svg, img, canvas, [role='img']";highlightTTSElementFallbacks(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-sentence-element",this.ttsSentenceElementHighlights,$0.SENTENCE_FALLBACK_SELECTOR)}highlightTTSWordElementFallbacks(Z){if(typeof Element>"u")return;this.highlightElementFallbacks(Z,"data-pie-tts-word-element",this.ttsWordElementHighlights,$0.WORD_FALLBACK_SELECTOR)}highlightElementFallbacks(Z,Q,J,Y){let X=(G)=>G.nodeType===Node.ELEMENT_NODE?G:d(G);for(let G of Z){let j=G.commonAncestorContainer,B=m(j)?j:X(j);if(!B)continue;let U=[],q=X(G.startContainer),K=X(G.endContainer);for(let $ of[q,K]){let D=$;while(D){if(D.matches?.(Y))U.push(D);D=d(D)}}if(!m(B)&&B.matches?.(Y))U.push(B);U.push(...Array.from(B.querySelectorAll(Y)));for(let $ of new Set(U)){try{if(!G.intersectsNode($)&&!t($,q)&&!t($,K))continue}catch{continue}$.setAttribute(Q,"true"),J.add($)}}}clearTTSWord(){if(!this.supported)return;V0(S1,this.ttsWordRanges),this.ttsWordRanges.clear();for(let Z of this.ttsWordElementHighlights)Z.removeAttribute("data-pie-tts-word-element");this.ttsWordElementHighlights.clear()}clearTTSSentence(){if(!this.supported)return;V0(T1,this.ttsSentenceRanges),this.ttsSentenceRanges.clear();for(let Z of this.ttsSentenceElementHighlights)Z.removeAttribute("data-pie-tts-sentence-element");this.ttsSentenceElementHighlights.clear()}clearTTS(){if(this.clearTTSWord(),this.clearTTSSentence(),G9.source===this.ttsStyleSource)G9.source=null;this.ttsStyleSource=null}addAnnotation(Z,Q=q0.YELLOW){let J=`annotation-${this.nextAnnotationId++}`,Y=Z.cloneRange();K0(Y.startContainer);let X={id:J,range:Y,type:i.ANNOTATION,color:Q,timestamp:Date.now()};if(this.annotations.set(J,X),this.supported)C9(d9(Q)).add(Y);return J}removeAnnotation(Z){let Q=this.annotations.get(Z);if(!Q){console.warn(`[HighlightCoordinator] Annotation ${Z} not found`);return}if(this.supported)V0(d9(Q.color),[Q.range]);this.annotations.delete(Z)}clearAnnotations(){if(this.supported)for(let Z of this.annotations.values())V0(d9(Z.color),[Z.range]);this.annotations.clear()}getAnnotations(){return Array.from(this.annotations.values())}getAnnotation(Z){return this.annotations.get(Z)??null}changeAnnotationColor(Z,Q){let J=this.annotations.get(Z);if(!J)return;let Y=J.color;if(Y===Q)return;if(J.color=Q,this.supported)V0(d9(Y),[J.range]),C9(d9(Q)).add(J.range)}exportAnnotations(Z=document.body){return this.getAnnotations().map((Q)=>({...this.rangeSerializer.serialize(Q.range,Z),id:Q.id,color:Q.color,timestamp:Q.timestamp}))}importAnnotations(Z,Q=document.body){let J=0;for(let Y of Z){let X=this.rangeSerializer.deserialize(Y,Q);if(X)this.addAnnotation(X,Y.color),J++}return J}highlightRange(Z,Q,J=q0.YELLOW){if(!this.supported)return;switch(Q){case i.TTS_WORD:this.highlightTTSWord([Z]);break;case i.TTS_SENTENCE:this.highlightTTSSentence([Z]);break;case i.ANNOTATION:this.addAnnotation(Z,J);break}}clearHighlights(Z){if(!this.supported)return;switch(Z){case i.TTS_WORD:this.clearTTSWord();break;case i.TTS_SENTENCE:this.clearTTSSentence();break;case i.ANNOTATION:this.clearAnnotations();break}}clearAll(){if(!this.supported)return;this.clearTTS(),this.clearAnnotations()}isSupported(){return this.supported}updateTTSHighlightStyle(Z,Q){if(!this.supported)return;if(typeof document>"u")return;if(!document.getElementById("pie-highlight-styles"))return;let X=((G)=>{let j=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(G);return j?{r:parseInt(j[1],16),g:parseInt(j[2],16),b:parseInt(j[3],16)}:null})(Z);if(!X)return;G9.override={color:`rgb(${X.r}, ${X.g}, ${X.b})`,opacity:Math.max(0.2,Math.min(0.95,Q)),owner:this},this.applyAdaptiveTTSStyle()}destroy(){if(!this.supported)return;if(this.clearTTS(),this.clearAnnotations(),G9.override?.owner===this)G9.override=null;this.themeObserver?.disconnect(),this.themeObserver=null}}import{applyMediaFragment as R4,enforceMediaFragment as E4}from"@pie-players/pie-players-shared/media";import{createPieLogger as C4,isTtsDebugEnabled as R3}from"@pie-players/pie-players-shared/pie";import{isUnsupportedMediaAssetVersion as d6,normalizeMediaFragment as l6,normalizeMediaSources as i6,trimmedOrUndefined as s6}from"@pie-players/pie-players-shared/media";function HZ(Z){if(!Z)return null;let Q=Z.payload;if(!Q||typeof Q!=="object")return null;let J=Q.media;if(!J||typeof J!=="object")return console.warn("[spoken-audio] card carries a `payload` with no `media`; recorded speech needs `media.sources`, so this card is ignored and read-aloud falls back to the script or generated speech"),null;if(d6(J.version))return console.warn(`[spoken-audio] card's media declares version ${String(J.version)}, which this build does not render; the card is ignored and read-aloud falls back to the script or generated speech`),null;if(J.kind!==void 0&&J.kind!=="audio")return console.warn(`[spoken-audio] card's media is kind "${J.kind}", not "audio"; a spoken card carries recorded speech, so this card is ignored`),null;let Y=i6(J.sources);if(Y.length===0)return console.warn("[spoken-audio] card's `media.sources` yielded no usable URL; read-aloud falls back to the script or generated speech"),null;return{sources:Y,fragment:l6(Q.fragment),label:s6(J.label)}}var n6="[data-pie-shell-root]";var _Z=(Z)=>Z?b0(Z,n6):null;var S0="en-US",y1=(Z,Q)=>{let J=!Z?null:Z.nodeType===1?Z:d(Z);while(J){let Y=J.getAttribute("lang")?.trim();if(Y)return Y;if(Q&&J===Q)return;J=d(J)}return},x1=(Z,Q={})=>{let J=Q.boundary!==void 0?Q.boundary:_Z(Z);return(J?y1(Z,J):void 0)||Q.contentLanguage?.trim()||void 0},MZ=(Z,Q={})=>x1(Z,Q)??S0;var y=(Z)=>Z.trim().replace(/\s+/g," "),wZ=()=>/[\p{L}]+|\d+(?:\.\d+)?|[±√=+\-*/()²³^×÷≤≥≠≈<>|%°'′\u2062]/gu,k1=(Z)=>{if(Z.hidden)return!0;if(Z.tagName?.toLowerCase()==="mjx-assistive-mml")return!0;if(Z.getAttribute("aria-hidden")==="true")return!0;if(Z.hasAttribute("inert"))return!0;let Q=Z.classList;if(Q?.contains("sr-only")||Q?.contains("pie-sr-only")||Q?.contains("visually-hidden"))return!0;if(typeof window<"u"){let J=window.getComputedStyle(Z);if(J.display==="none"||J.visibility==="hidden")return!0;let Y=Number.parseFloat(J.width||"0"),X=Number.parseFloat(J.height||"0"),G=Number.isFinite(Y)&&Number.isFinite(X)&&Y<=1&&X<=1,j=J.clipPath.includes("inset(50%")||J.clipPath.includes("inset(100%")||J.clip.includes("rect(0px, 0px, 0px, 0px)")||J.clip.includes("rect(0 0 0 0)");if((J.position==="absolute"||J.position==="fixed")&&G&&(J.overflow==="hidden"||j))return!0;if(J.opacity==="0"&&G)return!0}return!1},l9=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(k1(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},LZ="data-tts-suppress",PZ=new Set(["computer-read-aloud","all"]),OZ=new Set([...PZ,"screen-reader"]),NZ=new Set,r6=(Z)=>{let Q=Z.getAttribute?.(LZ);if(Q===null||Q===void 0)return!1;let J=Q.trim().toLowerCase();if(PZ.has(J))return!0;if(OZ.has(J))return!1;if(!NZ.has(J))NZ.add(J),console.warn(`[tts] ${LZ}="${Q}" is not one of ${Array.from(OZ).join(", ")}; suppressing read-aloud for this content anyway, because a suppression attribute that fails open would leak the answer to items where reading is the construct. Correct the value to silence this.`);return!0},T0=(Z,Q)=>{let J=Z.nodeType===1?Z:c(Z);while(J){if(r6(J))return!0;if(Q&&J===Q)break;J=c(J)}return!1},A9=(Z,Q)=>l9(Z,Q)||T0(Z),f1=(Z,Q)=>{if(typeof Z.intersectsNode!=="function")return{text:Z.toString(),filtered:!1};let J=[],Y=!1;for(let X of R9(Q))if(X9(Z,X))if(A9(X,Q))Y=!0;else J.push(I1(X,Z));return{text:J.join(""),filtered:Y}},I1=(Z,Q)=>{let J=Z.textContent||"",Y=Z===Q.startContainer?Q.startOffset:0,X=Z===Q.endContainer?Q.endOffset:J.length;return J.slice(Y,X)},A0=(Z,Q,J)=>{let Y=null,X=null;for(let G of R9(Q)){if(A9(G,J))continue;let j=G.textContent||"",B=j.search(/\S/);if(B===-1)continue;Y??={node:G,offset:B},X={node:G,offset:j.trimEnd().length-1}}if(!Y||!X)return X9(Z,Q);return U0(Z,Y.node,Y.offset)&&U0(Z,X.node,X.offset)},v1=(Z,Q,J)=>{if(!Z||!Q)return!1;if(/\s/.test(Z)||/\s/.test(Q))return!1;let Y=J?.boundarySpacingMode??"segmenterPreferred";if(Y==="none")return!1;if(Y==="segmenterPreferred")try{let j=globalThis.Intl?.Segmenter;if(typeof j==="function"){let B=new j(J?.locale,{granularity:"word"});if(Array.from(B.segment(`${Z}${Q}`)).filter((K)=>K.isWordLike!==!1&&K.segment.trim().length>0).length>=2)return!0}}catch{}let X=/[A-Za-z0-9]/.test(Z),G=/[A-Za-z0-9]/.test(Q);return X&&G},b9=(Z,Q)=>{let J=new Map;if(typeof document>"u")return{text:"",map:J};let Y=[],X=0,G=!0,j=!1,B=null,U=null;for(let K of R9(Z))if(c(K)&&!A9(K,Z)){let D=K.textContent||"",z=D.match(/\S/),M=z?z[0]:null;if(!G&&!j&&v1(U,M,Q)){if(Y.push(" "),B)J.set(X,B);X++,j=!0}for(let O=0;O<D.length;O++){let F=D[O],w=/\s/.test(F);if(G){if(!w)G=!1,Y.push(F),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++,j=!1,U=F}else if(w){if(!j)Y.push(" "),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++;j=!0}else Y.push(F),J.set(X,{node:K,offset:O}),B={node:K,offset:O},X++,j=!1,U=F}}let q=Y.join("").trimEnd();while(J.has(q.length))J.delete(q.length);return{text:q,map:J}};var o6=/^\s*<speak[\s/>]/i,x0=(Z)=>o6.test(Z),a6=new Set(["speak","p","s","emphasis","prosody","say-as","voice","lang"]),RZ=new Set(["audio","phoneme"]),CZ=(Z)=>Z.replace(/"/g,'"').replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">").replace(/ /g," ").replace(/ /g," ").replace(/&/g,"&"),y0=(Z,Q,J)=>{for(let Y=0;Y<Q.length;Y++)Z.push({char:Q[Y],rawOffset:J===null?null:J+Y})},t6=(Z,Q,J)=>{let Y=Q.slice(J).match(/^&(quot|apos|lt|gt|nbsp|amp|#160);/i);if(!Y)return 0;return y0(Z,CZ(Y[0]),J),Y[0].length},EZ=(Z)=>{Z.push({char:" ",rawOffset:null})},e6=(Z)=>{let Q=new Map,J=[],Y=!0;for(let X of Z){if(/\s/.test(X.char)){if(!Y&&J.length>0){if(J.push(" "),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1)}Y=!0;continue}if(J.push(X.char),X.rawOffset!==null)Q.set(X.rawOffset,J.length-1);Y=!1}while(J.length>0&&J[J.length-1]===" ")J.pop();for(let[X,G]of Q)if(G>=J.length)Q.delete(X);return{text:J.join(""),rawToSpokenOffsetMap:Q}},Z7=(Z)=>{return Z.match(/^<\/?\s*([A-Za-z0-9:-]+)/)?.[1]?.toLowerCase()||""},Q7=(Z,Q)=>{let J=new RegExp(`${Q}\\s*=\\s*("([^"]*)"|'([^']*)')`,"i"),Y=Z.match(J);return CZ(Y?.[2]??Y?.[3]??"")||null},k0=(Z)=>{let Q=[],J=!1,Y=!1,X=0;while(X<Z.length){let j=Z[X];if(j!=="<"){if(j==="&"){let D=t6(Q,Z,X);if(D>0){X+=D;continue}}y0(Q,j,X),X++;continue}let B=Z.indexOf(">",X+1);if(B<0){y0(Q,j,X),X++;continue}Y=!0;let U=Z.slice(X,B+1),q=Z7(U),K=/^<\s*\//.test(U),$=/\/\s*>$/.test(U);if(!K&&q==="sub"){let D=Q7(U,"alias");if(!D){J=!0,X=B+1;continue}y0(Q,D,null);let z=Z.toLowerCase().indexOf("</sub>",B+1);X=z>=0?z+6:B+1;continue}if(!K&&q==="break"){EZ(Q),X=B+1;continue}if(!K&&RZ.has(q)){if(J=!0,$){X=B+1;continue}}if(q&&!a6.has(q)&&!RZ.has(q)&&q!=="break"&&q!=="sub")J=!0;if(!K&&(q==="p"||q==="s"))EZ(Q);X=B+1}let G=e6(Q);return{spokenText:y(G.text),rawToSpokenOffsetMap:G.rawToSpokenOffsetMap,unsupportedSemantic:J,hasMarkup:Y}};var J7=wZ(),Y7=new Map([["zero","0"],["one","1"],["two","2"],["three","3"],["four","4"],["five","5"],["six","6"],["seven","7"],["eight","8"],["nine","9"],["ten","10"]]),X7=(Z)=>{let Q=Z.toLowerCase();return Y7.get(Q)||Q},u1=(Z)=>{let Q=[];for(let J of Z.matchAll(J7)){let Y=J[0],X=J.index??0;Q.push({text:Y,normalized:X7(Y),start:X,end:X+Y.length})}return Q},G7=(Z)=>u1(Z).map((Q,J)=>({...Q,id:`speech-token-${J}`,sourceStart:Q.start,sourceEnd:Q.end,coordinateSystem:"normalized-speech"})),S9=(Z)=>{let Q=k0(Z.speechText);return{speechText:Z.speechText,spokenText:Q.spokenText,tokens:G7(Q.spokenText),rawToSpokenOffsetMap:Q.rawToSpokenOffsetMap,boundaryOffsetSpace:Q.unsupportedSemantic?"unsupported":Q.hasMarkup?"raw-ssml":"plain-spoken-text",unsupportedSemantic:Q.unsupportedSemantic,hasMarkup:Q.hasMarkup}},p1=(Z)=>Boolean(Z&&/^<[^>]+>$/.test(Z.trim())),i9=(Z)=>{if(!Z||p1(Z))return null;return S9({speechText:Z}).tokens[0]?.normalized??null},j7=(Z,Q)=>Z.find((J)=>J.start<=Q&&Q<J.end)||null,B7=(Z,Q)=>{let J=Z.rawToSpokenOffsetMap.get(Q);if(J!==void 0)return J;for(let Y=Q;Y<Z.speechText.length;Y++){let X=Z.rawToSpokenOffsetMap.get(Y);if(X!==void 0)return X;if(Z.speechText[Y]===">")break}return null},h1=(Z,Q,J)=>{if(Q===null)return null;let Y=j7(Z.tokens,Q);if(!Y)return null;return{token:Y,start:Q,length:Math.max(1,Math.min(J,Y.end-Q)),confidence:0.75}},m1=(Z,Q)=>Boolean(Z&&Q&&Z.token.normalized===Q),g1=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||p1(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=i9(Z.boundaryWord),Y=h1(Z.tokenization,B7(Z.tokenization,Z.position),Q),X=h1(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(m1(Y,J))return{...Y,confidence:1};if(m1(X,J))return{...X,confidence:1};if(J)return null;return Z.tokenization.boundaryOffsetSpace==="raw-ssml"?Y||X:X||Y},bZ=(Z)=>{if(Z.tokenization.boundaryOffsetSpace==="unsupported"||!Number.isFinite(Z.position)||p1(Z.boundaryWord))return null;let Q=Math.max(1,Number.isFinite(Z.length)?Z.length:1),J=i9(Z.boundaryWord),Y=h1(Z.tokenization,Z.position>=0&&Z.position<Z.tokenization.spokenText.length?Z.position:null,Q);if(m1(Y,J))return{...Y,confidence:1};if(J)return null;return Y};var W7=[{phrase:["plus","or","minus"],visible:"±",score:8},{phrase:["square","root"],visible:"√",score:8},{phrase:["divided","by"],visible:"/",score:7},{phrase:["all","over"],visible:"/",score:7},{phrase:["equals"],visible:"=",score:7},{phrase:["equal"],visible:"=",score:7},{phrase:["times"],visible:"",score:7},{phrase:["multiplied","by"],visible:"",score:7},{phrase:["over"],visible:"/",score:6},{phrase:["squared"],visible:"²",score:6},{phrase:["squared"],visible:"2",score:4},{phrase:["negative"],visible:"-",score:5},{phrase:["minus"],visible:"-",score:5},{phrase:["plus"],visible:"+",score:5}],U7=(Z,Q)=>{let J=[];for(let Y=0;Y<Z.length;Y++){for(let X=0;X<Q.length;X++)if(Z[Y].normalized===Q[X].normalized)J.push({spokenStartToken:Y,spokenEndToken:Y+1,visibleToken:X,score:10});for(let X of W7){let G=Z.slice(Y,Y+X.phrase.length);if(G.length!==X.phrase.length)continue;if(!G.every((j,B)=>j.normalized===X.phrase[B]))continue;for(let j=0;j<Q.length;j++){if(Q[j].text!==X.visible)continue;J.push({spokenStartToken:Y,spokenEndToken:Y+X.phrase.length,visibleToken:j,score:X.score})}}}return J},K7=(Z,Q)=>{let J=U7(Z,Q).sort((U,q)=>Z[U.spokenStartToken].start-Z[q.spokenStartToken].start||Q[U.visibleToken].start-Q[q.visibleToken].start),Y=Array(J.length).fill(0),X=Array(J.length).fill(-1);for(let U=0;U<J.length;U++){let q=J[U];Y[U]=q.score;for(let K=0;K<U;K++){let $=J[K];if($.spokenEndToken<=q.spokenStartToken&&$.visibleToken<q.visibleToken){let D=q.spokenStartToken-$.spokenEndToken,z=q.visibleToken-$.visibleToken-1,M=Math.max(0,Math.abs(D-z)-2),O=Y[K]+q.score-M;if(O>Y[U])Y[U]=O,X[U]=K}}}let G=-1;for(let U=0;U<Y.length;U++)if(G<0||Y[U]>Y[G])G=U;if(G<0)return[];let j=[],B=G;while(B>=0)j.unshift(J[B]),B=X[B];return j.map((U)=>{let q=Z[U.spokenStartToken],K=Z[U.spokenEndToken-1],$=Q[U.visibleToken];return{spokenStart:q.start,spokenEnd:K.end,visibleStart:$.start,visibleEnd:$.end,score:U.score}})},V7=(Z,Q,J)=>{if(Z.length===0)return 0;let Y=Z.length/Math.max(1,Math.min(Q.length,J.length)),X=Z.reduce((G,j)=>G+j.score,0)/Z.length/10;return Math.min(1,Y*X)},f0=(Z)=>{let Q=S9({speechText:Z.speechText}),J=y(Z.visibleText),Y=Q.tokens,X=u1(J),G=Q.unsupportedSemantic?[]:K7(Y,X),j=V7(G,Y,X),B=Q.spokenText===J&&Q.spokenText.length>0,U=G.length===1&&G[0].score===10&&Y.length<=2&&X.length<=2,q=Q.unsupportedSemantic?"region-fallback":B?"exact-word":G.length>=2||U?j>=0.12?"anchor-span":"region-fallback":"region-fallback";return{speech:Q,visibleText:J,playbackMode:q,anchors:G,confidence:j}},SZ=(Z,Q)=>{if(Z.playbackMode==="region-fallback")return null;let J=Z.anchors.find((G)=>G.spokenStart<=Q&&Q<G.spokenEnd);if(J)return{start:J.visibleStart,end:J.visibleEnd};let Y=null,X=null;for(let G of Z.anchors){if(G.spokenEnd<=Q){Y=G;continue}if(G.spokenStart>Q){X=G;break}}if(Y&&X)return{start:Math.min(Y.visibleStart,X.visibleStart),end:Math.max(Y.visibleEnd,X.visibleEnd)};return null};var q7=new Map([["+",["plus"]],["-",["minus","negative"]],["−",["minus","negative"]],["×",["times","multiplied by"]],["÷",["divided by"]],["=",["equals","equal to"]],["≠",["is not equal to","not equal to"]],["≈",["approximately equals"]],["≤",["less than or equal to"]],["≥",["greater than or equal to"]],["<",["less than"]],[">",["greater than"]],["∠",["angle"]],["△",["triangle"]],["□",["box"]],["○",["circle"]],["°",["degrees","degree"]],["%",["percent"]],["'",["prime"]],["′",["prime"]],["•",["times"]],["·",["times"]],["",["times","multiplied by"]]]),$7=new Map([["","function-application"],["","implicit-multiply"],["","invisible-separator"],["","invisible-plus"]]),TZ=new Map([["2",["squared"]],["3",["cubed"]]]),A7=new Map([["msqrt","radical"],["mroot","radical"],["msub","subscript"],["msubsup","subsupscript"],["munder","underscript"],["mover","overscript"],["munderover","underoverscript"],["mmultiscripts","multiscript"],["menclose","enclosure"]]),D7=(Z)=>Z.replace(/\s+/g," ").trim(),T9=(Z)=>(Z.localName||Z.tagName||"").toLowerCase(),F7=(Z)=>Z.nodeType===Node.ELEMENT_NODE,s9=(Z)=>Array.from(Z.childNodes).filter(F7),c1=(Z)=>D7(Z.textContent||""),j9=(Z,Q)=>({type:"element-range",quality:Q,element:Z}),z7=(Z)=>{switch(Z){case"mi":return"identifier";case"mn":return"number";case"mo":return"operator";case"mtext":case"ms":return"text";case"mspace":return"space";default:return"unknown"}},H7=(Z,Q)=>{if(Q==="operator"){if(Z==="−")return"-";return Z}return Z.toLowerCase()},_7=(Z,Q,J)=>{if(J==="fraction")return["over","divided by"];if(J==="superscript")return TZ.get(Z)??[];if(Z==="|")return["absolute value"];if(Q==="operator")return q7.get(Z)||[];return[]},y9=(Z)=>{let Q=Z.normalized??H7(Z.text,Z.kind||"unknown");return{id:`math-token-${Z.state.nextId++}`,kind:Z.kind,role:Z.role,text:Z.text,normalized:Q,spokenAliases:_7(Z.text,Z.kind,Z.role),sourceElement:Z.sourceElement,path:Z.path,target:Z.target||j9(Z.sourceElement,"element-range"),optional:Z.optional}},x9=(Z,Q,J="tokens")=>{Z[J].push(Q)},yZ=(Z,Q,J)=>{s9(Z).forEach((Y,X)=>B9(Y,Q,`${J}/${T9(Y)}[${X}]`))},M7=(Z,Q,J)=>{let Y=s9(Z);if(Y[0])B9(Y[0],Q,`${J}/numerator`);if(x9(Q,y9({state:Q,kind:"structure",role:"fraction",text:"/",sourceElement:Z,path:J,target:j9(Z,"element-range")})),Y[1])B9(Y[1],Q,`${J}/denominator`)},L7=(Z,Q,J)=>{let Y=Z.getAttribute("open")||"(",X=Z.getAttribute("close")||")";x9(Q,y9({state:Q,kind:"operator",role:Y==="|"?"absolute-value-fence":"open-fence",text:Y,sourceElement:Z,path:`${J}/open`,target:j9(Z,"element-range")})),yZ(Z,Q,J),x9(Q,y9({state:Q,kind:"operator",role:X==="|"?"absolute-value-fence":"close-fence",text:X,sourceElement:Z,path:`${J}/close`,target:j9(Z,"element-range")}))},O7=(Z,Q,J)=>{let Y=s9(Z);if(Y[0])B9(Y[0],Q,`${J}/base`);let X=Y[1];if(!X)return;let G=c1(X);if(TZ.has(G)){x9(Q,y9({state:Q,kind:"structure",role:"superscript",text:G,normalized:G,sourceElement:X,path:`${J}/exponent`,target:j9(Z,"element-range")}));return}B9(X,Q,`${J}/exponent`)},N7=(Z,Q,J,Y)=>{x9(Q,y9({state:Q,kind:"structure",role:Y,text:c1(Z)||Y,normalized:`\x00${Y}`,sourceElement:Z,path:J,target:j9(Z,"element-range")}))},w7=(Z,Q,J)=>{let Y=0;for(let X of s9(Z)){if(T9(X)==="mtr"||T9(X)==="mlabeledtr")Y++,x9(Q,y9({state:Q,kind:"layout",role:"table-row",text:`row-${Y}`,normalized:`row-${Y}`,sourceElement:X,path:`${J}/row[${Y}]`,target:j9(X,"region-fallback")}),"layoutTargets");B9(X,Q,`${J}/${T9(X)}[${Y}]`)}},P7=(Z,Q,J)=>{let Y=c1(Z);if(!Y)return;let X=z7(T9(Z)),G=X==="operator"?$7.get(Y):void 0,j=G??(X==="operator"&&(Y==="("||Y===")")?"grouping-fence":X);x9(Q,y9({state:Q,kind:X,role:j,text:Y,sourceElement:Z,path:J,target:G&&Z.parentElement?j9(Z.parentElement,"region-fallback"):void 0,optional:Boolean(G)||j==="grouping-fence"}))},B9=(Z,Q,J)=>{let Y=T9(Z);switch(Y){case"annotation":case"annotation-xml":return;case"semantics":{let X=s9(Z).find((G)=>{let j=T9(G);return j!=="annotation"&&j!=="annotation-xml"});if(X)B9(X,Q,`${J}/presentation`);return}case"mi":case"mn":case"mo":case"mtext":case"ms":case"mspace":P7(Z,Q,J);return;case"mfrac":M7(Z,Q,J);return;case"msup":O7(Z,Q,J);return;case"mfenced":L7(Z,Q,J);return;case"mtable":w7(Z,Q,J);return;case"mphantom":return;case"maction":{let X=s9(Z)[0];if(X)B9(X,Q,`${J}/action`);return}default:{let X=A7.get(Y);if(X){N7(Z,Q,J,X);return}yZ(Z,Q,J)}}},xZ=(Z)=>{let Q={tokens:[],layoutTargets:[],nextId:0};return B9(Z,Q,"/math"),{tokens:Q.tokens,layoutTargets:Q.layoutTargets,expressionTarget:j9(Z,"region-fallback")}};var kZ=(Z)=>{if(!Z.boundary)return null;return Z.alignment.segments.find((J)=>J.speechTokenIds.includes(Z.boundary.token.id))?.target||null};var R7=(Z)=>{let Q=[],J=new Set,Y=(X)=>{let G=X.toLowerCase().trim().split(/\s+/).filter(Boolean);if(G.length===0)return;let j=G.join(" ");if(J.has(j))return;J.add(j),Q.push(G)};Y(Z.normalized);for(let X of Z.spokenAliases)Y(X);return Q},fZ=(Z,Q,J)=>{let Y=0;for(let X of J){if(X.length<=Y)continue;let G=!0;for(let j=0;j<X.length;j++){let B=Z[Q+j];if(!B||B.normalized.toLowerCase()!==X[j]){G=!1;break}}if(G)Y=X.length}return Y},E7=(Z,Q)=>{let J=[],Y=0;for(let X of Q){let G=R7(X);if(X.optional){let j=fZ(Z,Y,G);if(j>0)J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;continue}while(Y<Z.length){let j=fZ(Z,Y,G);if(j>0){J.push({speechTokens:Z.slice(Y,Y+j),math:X}),Y+=j;break}Y++}}return J},C7=(Z,Q,J)=>{let Y=J.filter((j)=>!j.optional).length,X=Z.filter((j)=>!j.math.optional).length,G=Z.reduce((j,B)=>j+B.speechTokens.length,0);return Y>0&&X===Y&&G===Q.length},b7=(Z)=>Z.map(({speechTokens:Q,math:J})=>({speechTokenIds:Q.map((Y)=>Y.id),mathTokenIds:[J.id],score:1,confidence:1,target:J.target})),IZ=(Z)=>{let Q=Z.minExactWordConfidence??0.95,J=E7(Z.speech.tokens,Z.math.tokens),Y=C7(J,Z.speech.tokens,Z.math.tokens)?1:0;return{segments:Y>=Q?b7(J):[],confidence:Y,fallbackTarget:Z.math.expressionTarget}};var n9=(Z)=>{let Q=S9({speechText:Z.speechText}),J=xZ(Z.mathElement);return{speech:Q,math:J,result:IZ({speech:Q,math:J})}};var vZ=(Z,Q)=>{let J=bZ({tokenization:Z.speech,position:Q.position,length:Q.length,boundaryWord:Q.boundaryWord});return kZ({alignment:Z.result,boundary:J})},hZ=(Z,Q)=>{let J=i9(Q.boundaryWord);if(!J)return null;let Y=Z.math.tokens.filter((X)=>X.normalized.toLowerCase()===J||X.spokenAliases.some((G)=>G.toLowerCase()===J));return Y.length===1?Y[0].target:null};var S7=new Set(["math","maction","menclose","merror","mfenced","mfrac","mi","mmultiscripts","mn","mo","mover","mpadded","mphantom","mprescripts","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msubsup","msup","mtable","mtd","mtext","mtr","munder","munderover","none","semantics","annotation","annotation-xml"]),T7=new Set(["accent","accentunder","align","bevelled","class","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","encoding","fence","height","href","id","largeop","length","linethickness","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","width","xmlns","xml:lang"]),mZ=(Z)=>Z.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">"),y7=(Z)=>mZ(Z).replace(/"/g,"""),x7=(Z,Q)=>{let J=Z.toLowerCase(),Y=Q.trim().toLowerCase();if(J.startsWith("on"))return!0;if(!T7.has(J))return!0;if(Y.includes("javascript:"))return!0;if(Y.includes("data:text/html"))return!0;return!1},k7=(Z)=>{let Q=Z.localName.toLowerCase();if(!S7.has(Q))return!1;let J=Z.namespaceURI;return!J||J==="http://www.w3.org/1998/Math/MathML"||J==="http://www.w3.org/1999/xhtml"},uZ=(Z)=>{if(Z.nodeType===Node.TEXT_NODE)return mZ(Z.textContent||"");if(Z.nodeType===Node.COMMENT_NODE)return"";if(Z.nodeType!==Node.ELEMENT_NODE)return null;let Q=Z;if(!k7(Q))return null;let J=Q.localName.toLowerCase(),Y=[];for(let j of Array.from(Q.attributes)){let B=j.name.toLowerCase();if(x7(B,j.value))continue;if(B==="xmlns"&&j.value!=="http://www.w3.org/1998/Math/MathML")return null;Y.push(`${B}="${y7(j.value)}"`)}if(J==="math"&&!Y.some((j)=>j.startsWith("xmlns=")))Y.unshift('xmlns="http://www.w3.org/1998/Math/MathML"');let X=[];for(let j of Array.from(Q.childNodes)){let B=uZ(j);if(B===null)return null;X.push(B)}let G=Y.length>0?` ${Y.join(" ")}`:"";return`<${J}${G}>${X.join("")}</${J}>`},f7=(Z)=>{if(typeof DOMParser<"u")return new DOMParser().parseFromString(Z,"application/xml");return null},r9=(Z)=>{let Q=String(Z||"").trim();if(!Q)return null;let J=f7(Q);if(!J)return null;if(J.getElementsByTagName("parsererror").length>0)return null;let Y=J.documentElement;if(!Y||Y.localName.toLowerCase()!=="math")return null;return uZ(Y)};var gZ=(Z)=>({chars:[],map:new Map,position:0,inLeadingWhitespace:!0,lastCharWasWhitespace:!1,lastMapped:null,options:Z}),d1=(Z)=>Z.classList?.contains("MathJax")||Z.tagName?.toLowerCase()==="mjx-container",cZ=(Z)=>Z.tagName?.toLowerCase()==="mjx-assistive-mml",l1=(Z)=>{let Q=Z.tagName?.toLowerCase();return Q==="annotation"||Q==="annotation-xml"},I7=(Z)=>{let Q=Z.getAttribute("data-mathml");return Q&&Q.trim()?Q:null},v7=(Z)=>{return E9(Z,"mjx-assistive-mml math")?.outerHTML||null},h7=(Z)=>{if(Z.tagName.toLowerCase()==="math")return r9(Z.outerHTML);let Q=I7(Z);if(Q){let J=r9(Q);if(J)return J}if(d1(Z)){let J=v7(Z);if(J){let Y=r9(J);if(Y)return Y}}return null},m7=new Set(["P","H1","H2","H3","H4","H5","H6","LI","TD","TH","DD","DT","FIGCAPTION","LABEL","BUTTON"]),u7=new Set(["heading","listitem","option","radio","row","cell","columnheader","rowheader"]),p7=(Z,Q)=>{let J=c(Z),Y=null;while(J&&J!==Q){let X=(J.getAttribute("role")||"").toLowerCase(),G=J.tagName.toUpperCase();if(m7.has(G)||u7.has(X)){Y=J;break}J=c(J)}return Y||Q},g7=(Z)=>Boolean(typeof Z.querySelector==="function"&&E9(Z,"math, [data-mathml], .MathJax, mjx-container, mjx-assistive-mml"))||Z.tagName?.toLowerCase()==="math"||Z.hasAttribute?.("data-mathml")||d1(Z),k9=(Z,Q,J)=>{if(/[.,;:!?]/.test(Q)&&Z.chars.length>0&&Z.chars[Z.chars.length-1]===" ")Z.chars.pop(),Z.position--,Z.map.delete(Z.position);if(Z.chars.push(Q),J)Z.map.set(Z.position,J),Z.lastMapped=J;else if(Z.lastMapped)Z.map.set(Z.position,Z.lastMapped);Z.position++},dZ=(Z,Q)=>{if(Z.inLeadingWhitespace||Z.lastCharWasWhitespace||Z.chars.length===0)return!1;let J=Z.chars[Z.chars.length-1];return v1(J,Q,Z.options)},lZ=(Z,Q,J=0,Y=(Q.textContent||"").length)=>{let X=Q.textContent||"",G=!1;for(let j=J;j<Y;j++){let B=X[j],U=/\s/.test(B);if(Z.inLeadingWhitespace){if(!U)Z.inLeadingWhitespace=!1,k9(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1;continue}if(U){if(!Z.lastCharWasWhitespace)k9(Z," ",{node:Q,offset:j});Z.lastCharWasWhitespace=!0;continue}if(!G&&dZ(Z,B))k9(Z," ",{node:Q,offset:j});k9(Z,B,{node:Q,offset:j}),G=!0,Z.lastCharWasWhitespace=!1}},c7=(Z,Q)=>{for(let J=0;J<Q.text.length;J++){let Y=Q.text[J],X=/\s/.test(Y),G=Q.map.get(J)||null,j=G?.node||Z.lastMapped?.node||null,B=G?.offset??Z.lastMapped?.offset??0,U=G?{node:G.node,offset:G.offset}:j?{node:j,offset:B}:null;if(Z.inLeadingWhitespace){if(X)continue;Z.inLeadingWhitespace=!1}if(X){if(!Z.lastCharWasWhitespace)k9(Z," ",U);Z.lastCharWasWhitespace=!0;continue}if(J===0&&dZ(Z,Y))k9(Z," ",U);if(k9(Z,Y,U),Z.lastCharWasWhitespace=!1,G)Z.map.set(Z.position-1,{node:G.node,offset:G.offset}),Z.lastMapped={node:G.node,offset:G.offset};else if(j)Z.map.set(Z.position-1,{node:j,offset:B})}},d7=(Z)=>{if(typeof DOMParser>"u")return"";let Q=new DOMParser().parseFromString(Z,"application/xml");if(Q.getElementsByTagName("parsererror").length>0)return"";let J=[],Y=(X)=>{if(X.nodeType===3){let j=X.textContent||"";if(j.trim())J.push(j);return}if(X.nodeType!==1)return;let G=X;if(l1(G))return;for(let j of Array.from(G.childNodes))Y(j)};return Y(Q.documentElement),y(J.join(" "))},l7=(Z,Q)=>{let J=new Map,Y=d1(Z)?E9(Z,"mjx-assistive-mml math"):null;if(!Y)return J;let X=[],G=(B)=>{if(B.nodeType===3){let U=B.textContent||"";for(let q=0;q<U.length;q++)if(!/\s/.test(U[q]))X.push({node:B,offset:q});return}if(B.nodeType!==1||l1(B))return;for(let U of $9(B))G(U)};G(Y);let j=0;for(let B=0;B<Q.length;B++){if(/\s/.test(Q[B]))continue;let U=X[j];if(U?.node.textContent?.[U.offset]!==Q[B])return new Map;J.set(B,U),j++}return j===X.length?J:new Map},i7=(Z,Q,J)=>{let Y=gZ(J),X=(B)=>{if(A9(B,Z))return;if(B.nodeType===3){lZ(Y,B);return}if(B.nodeType!==1)return;let U=B;if(cZ(U)||l1(U))return;for(let q of $9(U))X(q)};X(Z),iZ(Y);let G=y(Y.chars.join(""));if(G)return{text:G,map:Y.map};let j=d7(Q);if(!j)return b9(Z,J);return{text:j,map:l7(Z,j)}},iZ=(Z)=>{while(Z.chars.length>0&&/\s/.test(Z.chars[Z.chars.length-1]))Z.chars.pop(),Z.position--,Z.map.delete(Z.position)},pZ=(Z,Q,J)=>{let Y=gZ(Q),X=[],G=0,j,B=!1,U=()=>{let $=y(Y.chars.slice(G,Y.chars.length).join(""));if($)X.push({type:"text",text:$,sourceElement:j});G=Y.chars.length,j=void 0},q=($)=>{if(A9($,Z))return;if(J&&!X9(J,$))return;if($.nodeType===3){let M=p7($,Z);if(j&&M!==j)U();j=M;let O=$;lZ(Y,O,J?.startContainer===O?J.startOffset:void 0,J?.endContainer===O?J.endOffset:void 0);return}if($.nodeType!==1)return;let D=$;if(cZ(D))return;let z=h7(D);if(z&&(!J||A0(J,D,Z))){U();let M=i7(D,z,Q);c7(Y,M);let O=y(M.text);X.push({type:"math",mathml:z,fallbackText:O,sourceElement:D}),G=Y.chars.length,B=!0;return}for(let M of $9(D))q(M)};for(let $ of $9(Z))q($);iZ(Y),U();let K=Y.chars.join("");while(Y.map.has(K.length))Y.map.delete(K.length);return{visibleText:K,map:Y.map,chunks:X,containsMathMarkup:B}},D9=(Z,Q,J)=>{if(J)return pZ(Z,Q,J);if(!g7(Z)){let{text:Y,map:X}=b9(Z,Q);return{visibleText:Y,map:X,chunks:Y?[{type:"text",text:Y}]:[],containsMathMarkup:!1}}return pZ(Z,Q)};import{createPieLogger as n7,isTtsDebugEnabled as r7}from"@pie-players/pie-players-shared/pie";var I0=n7("tts-math-speech",r7),sZ=Promise.resolve(),o7=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",a7=(Z)=>{let Q=null,J=!1;return(Y)=>{if(!Q){aZ(Y);let X=Z();Q=X,X.catch((G)=>{if(Q===X)Q=null;if(J){I0.debug("speech-rule-engine failed to load again",G);return}J=!0,I0.warn("speech-rule-engine failed to load; math reads as its visible text until a later read loads it.",G)})}return Q}},t7=a7(()=>import("./chunks/sre-engine-jd8cc08x.js").then(({default:Z})=>{if(!Z||typeof Z.toSpeech!=="function")throw Error("speech-rule-engine did not expose toSpeech");return Z})),i1=(Z)=>{let Q=null;return()=>{return Q??=t7(W9(Z)?.engineOptions),Q}},e7=(Z)=>Z==="en"?"clearspeak":"mathspeak",nZ=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),rZ=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,W9=(Z)=>{if(!nZ(Z))return;let Q=rZ(Z.domain),J=rZ(Z.style),Y=nZ(Z.engineOptions)?Z.engineOptions:void 0;if(!Q&&!J&&!Y)return;return{...Q?{domain:Q}:{},...J?{style:J}:{},...Y?{engineOptions:Y}:{}}},Z4=async(Z,Q,J,Y)=>{let X=o7(Q),G=W9(Y),j=G?.engineOptions||{};await Z.setupEngine?.({...oZ(j),...j,locale:X,domain:G?.domain||e7(X),style:G?.style||"default",modality:"speech",markup:J}),await Z.engineReady?.()},Q4=async(Z)=>{let Q=sZ.then(Z,Z);return sZ=Q.then(()=>{return},()=>{return}),Q},tZ=async(Z,Q,J,Y,X)=>Q4(async()=>{return await Z4(Z,J,Y,X),Z.toSpeech(Q)}),J4=(Z)=>Z.replace(/^\s*<\?xml[^>]*\?>\s*/i,""),Y4=async(Z,Q,J,Y)=>{try{let X=J4(await tZ(Z,Q,J,"ssml",Y));return X.includes("<speak")?X:null}catch(X){return I0.debug("math SSML generation failed; using plain",{message:X instanceof Error?X.message:String(X)}),null}},o9=async(Z,Q={})=>{if(!Z.some((q)=>q.type==="math"))return{speechText:y(Z.map((q)=>q.type==="text"?q.text:q.fallbackText).join(" ")),usedMathSpeech:!1,usedFallback:!1};let J=null,Y=!1,X=!1,G=Q.loadSre||i1(Q.mathSpeech),j=[];for(let q of Z){if(q.type==="text"){j.push(q.text);continue}try{if(!J)J=await G();let K=y(await tZ(J,q.mathml,Q.language,"none",Q.mathSpeech));if(K){j.push(K),Y=!0;continue}X=!0,j.push(q.fallbackText)}catch(K){X=!0,I0.debug("math speech generation failed; using visible fallback",{message:K instanceof Error?K.message:String(K)}),j.push(q.fallbackText)}}let B=y(j.join(" ")),U;if(Q.produceSsml&&J&&Y&&Z.length===1&&Z[0].type==="math")U=await Y4(J,Z[0].mathml,Q.language,Q.mathSpeech)??void 0;return{speechText:B,usedMathSpeech:Y,usedFallback:X,ssml:U}};var X4=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",G4="sre-v1",j4=256,s1=(Z)=>{if(Array.isArray(Z))return`array:[${Z.map(s1).join(",")}]`;if(Z&&typeof Z==="object")return`object:{${Object.entries(Z).sort(([Q],[J])=>Q.localeCompare(J)).map(([Q,J])=>`${JSON.stringify(Q)}:${s1(J)}`).join(",")}}`;if(Z===null)return"null:null";if(typeof Z>"u")return"undefined:";if(typeof Z==="function")return`function:${Z.name||"anonymous"}`;if(typeof Z==="symbol")return`symbol:${String(Z)}`;if(typeof Z==="bigint")return`bigint:${Z.toString()}`;if(typeof Z==="number")return Number.isFinite(Z)?`number:${Z}`:`number:${String(Z)}`;return`${typeof Z}:${JSON.stringify(Z)}`},eZ=(Z,Q,J,Y)=>`${G4}\x00${X4(Z)}\x00${Q?"ssml":"plain"}\x00${s1(J??null)}\x00${Y}`,n1=(Z={})=>{let Q=Math.max(1,Z.maxEntries??j4),J=Z.resolve??((G,j)=>o9([G],j)),Y=new Map,X=(G,j)=>{Y.delete(G),Y.set(G,j);while(Y.size>Q){let B=Y.keys().next().value;if(B!==void 0)Y.delete(B)}};return async(G,j)=>{let B=W9(j.mathSpeech),U=j.produceSsml===!0,q=eZ(j.language,U,B,G.mathml),K=Y.get(q);if(K)return Y.delete(q),Y.set(q,K),K;let $=await J(G,{...j,mathSpeech:B});if($.usedFallback)return $;if(U&&$.ssml&&Q>1)X(eZ(j.language,!1,B,G.mathml),{speechText:$.speechText,usedMathSpeech:$.usedMathSpeech,usedFallback:$.usedFallback});return X(q,$),$}};var Z3=(Z,Q)=>{let J=i9(Q.word);if(Z.id!==Q.chunkId)return{chunkId:Q.chunkId,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary chunk id did not match highlight chunk"};if(Q.providerOffsetSpace==="unknown"||Z.offsetSpace==="unsupported")return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"boundary offset space is unsupported"};let Y=g1({tokenization:Z.catalogAlignment?.speech??S9({speechText:Z.speechText}),position:Q.position,length:Q.length,boundaryWord:Q.word});if(!Y)return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:null,chunkSpokenEnd:null,confidence:0,reason:"could not resolve provider boundary to chunk speech"};return{chunkId:Z.id,normalizedWord:J,chunkSpokenStart:Y.start,chunkSpokenEnd:Y.start+Y.length,confidence:Y.confidence,reason:Z.catalogAlignment?"resolved through catalog alignment":"resolved through speech tokenization"}};var f9=(Z)=>{if(Z.semanticTarget)return{activeTarget:Z.semanticTarget,regionTarget:Z.regionTarget,quality:Z.semanticTarget.quality==="exact-word"?"exact-word":Z.semanticTarget.quality==="expression"?"expression":"semantic-token",confidence:Z.confidence,reason:Z.reason};if(Z.expressionTarget)return{activeTarget:Z.expressionTarget,regionTarget:Z.regionTarget,quality:"expression",confidence:Z.confidence,reason:Z.reason};return{activeTarget:null,regionTarget:Z.regionTarget,quality:"region",confidence:Z.confidence,reason:Z.reason}};var J3=new Map([["mi","mjx-mi"],["mn","mjx-mn"],["mo","mjx-mo"],["mtext","mjx-mtext"]]),r1="mi,mn,mo,mtext",Y3="mjx-mi,mjx-mn,mjx-mo,mjx-mtext",X3=["mjx-mfrac","mjx-msqrt","mjx-mroot","mjx-mtable","mjx-munder","mjx-mover","mjx-munderover"].join(","),G3=(Z)=>{if(Z.type==="text-range")return Z.node.parentElement;return Z.element},v0=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="mjx-container")return Q;Q=Q.parentElement}return null},Q3=(Z)=>{if(!Z)return!1;if(v0(Z))return!1;return!l9(Z)},j3=(Z)=>{let Q=Z.getBoundingClientRect?.();return Boolean(Q&&Q.width>0&&Q.height>0)},o1=(Z)=>{let Q=Z;while(Q){if(Q.localName?.toLowerCase()==="math")return Q;Q=Q.parentElement}return null},B3=(Z,Q)=>{if(Z.length===0)return!1;if(Z.length!==Q.length)return!1;for(let J=0;J<Z.length;J+=1){let Y=J3.get(Z[J].localName.toLowerCase());if(!Y)return!1;if(Q[J].localName.toLowerCase()!==Y)return!1}return!0},B4=(Z,Q)=>{if(!Z)return null;if(!J3.has(Z.localName.toLowerCase()))return null;if(Q.querySelector(X3))return null;let J=o1(Z),Y=Q.querySelector("mjx-math");if(!J||!Y)return null;let X=Array.from(J.querySelectorAll(r1)),G=X.indexOf(Z);if(G<0)return null;let j=Array.from(Y.querySelectorAll(Y3));if(!B3(X,j))return null;let B=j[G];if(!B||!j3(B))return null;return B},W3=(Z)=>{let Q=v0(Z);if(Q){if(Q.querySelector(X3))return"expression";let X=o1(Z)??Z,G=Q.querySelector("mjx-math");if(!G)return"expression";let j=Array.from(X.querySelectorAll(r1)),B=Array.from(G.querySelectorAll(Y3));if(!B3(j,B))return"expression";return B.some((U)=>j3(U))?"token":"expression"}let J=o1(Z)??Z;return Array.from(J.querySelectorAll(r1)).some((X)=>!l9(X))?"token":"expression"},a1=(Z)=>{let Q=G3(Z),J=v0(Q);if(J){let Y=B4(Q,J);if(Y)return{type:"element",quality:"semantic-token",element:Y};return{type:"element",quality:"expression",element:J}}if(Z.type==="text-range"){if(!Q3(Z.node.parentElement))return null;return{type:"text-range",quality:"semantic-token",node:Z.node,startOffset:Z.startOffset,endOffset:Z.endOffset}}if(!Q3(Z.element))return null;return{type:"element",quality:Z.quality==="region-fallback"?"expression":"semantic-token",element:Z.element}},U3=a1,K3=()=>{let Z=new WeakMap;return(Q)=>{let J=G3(Q),Y=v0(J);if(!J||!Y)return a1(Q);if(Z.has(J))return Z.get(J)??null;let X=a1(Q);return Z.set(J,X),X}};var V3=(Z,Q,J,Y=Z.mathAlignments,X=U3)=>{if(Q.chunkSpokenStart===null||Q.chunkSpokenEnd===null)return null;let G=null;for(let j of Y){let B=vZ(j.alignment,{position:Q.chunkSpokenStart,length:Math.max(1,Q.chunkSpokenEnd-Q.chunkSpokenStart),boundaryWord:J.word})||hZ(j.alignment,{boundaryWord:J.word});if(!B)continue;let U=X(B);if(!U)continue;if(U.quality==="semantic-token")return U;G??=U}return G};var F9=(Z)=>Z.node.getRootNode?.()??Z.node,q3=(Z,Q)=>{try{let J=document.createRange();return J.setStart(Z.node,Z.offset),J.setEnd(Q.node,Q.offset+1),J}catch{return null}},t1=(Z,Q,J)=>{if(!Z||typeof document>"u")return null;if(J<=Q)return null;let Y=Z.get(Q),X=Z.get(Math.max(Q,J-1));if(!Y)return null;if(!X)X=Y;if(F9(X)!==F9(Y)){let G=F9(Y);X=Y;for(let j=Q+1;j<J;j++){let B=Z.get(j);if(B&&F9(B)===G)X=B}}return q3(Y,X)},z9=(Z,Q,J)=>{if(!Z||typeof document>"u"||J<=Q)return[];let Y=Z.get(Q);if(!Y)return[];let X=F9(Y),G=!1;for(let K=Q+1;K<J&&!G;K++){let $=Z.get(K);if($&&F9($)!==X)G=!0}if(!G){let K=t1(Z,Q,J);return K?[K]:[]}let j=[],B=null,U=null,q=()=>{if(B&&U){let K=q3(B,U);if(K)j.push(K)}B=null,U=null};for(let K=Q;K<J;K++){let $=Z.get(K);if(!$)continue;if(B&&F9(B)!==F9($))q();if(!B)B=$;U=$}return q(),j};var $3=(Z,Q)=>{if(!Z.catalogAlignment||Q.chunkSpokenStart===null)return null;let J=SZ(Z.catalogAlignment,Q.chunkSpokenStart);if(!J)return null;let Y=z9(Z.visibleMap,J.start,J.end);if(Y.length===0)return null;return{type:"range",quality:Z.catalogAlignment.playbackMode==="exact-word"?"exact-word":"semantic-token",range:Y[0],ranges:Y.length>1?Y:void 0}};var W4=(Z)=>{let Q=z9(Z.visibleMap,0,Z.visibleText.length);return Q.length>1?Q:void 0},U4=(Z)=>Z.regionRange?{type:"range",quality:"region",range:Z.regionRange,ranges:W4(Z)}:Z.regionElement?{type:"element",quality:"region",element:Z.regionElement}:null,A3=(Z,Q=Z.chunk.mathAlignments)=>{if(Q.length!==1)return null;let J=Q[0]?.alignment.result.fallbackTarget;return J?Z.renderedMathTargetResolver(J):null},K4=(Z,Q)=>{if(!Z)return Q.mathAlignments;return Q.mathAlignments.filter(({element:J})=>{try{if(Z.type==="range")return(Z.ranges??[Z.range]).some((Y)=>X9(Y,J));if(Z.type==="element")return t(Z.element,J);return t(d(Z.node),J)}catch{return!1}})},D3=()=>({activeTarget:null,regionTarget:null,quality:"region",confidence:0,reason:"boundary chunk id was not found"}),F3=(Z)=>Z.length===1?Z[0].element:null,V4=(Z,Q)=>Q.length>0&&Q.every(({element:J})=>Z.mathCapabilityByElement.get(J)==="token"),z3=3,q4=(Z,Q,J)=>{if(!Q||Q.type!=="range")return!1;let{startContainer:Y,endContainer:X}=Q.range;if(Y===X&&Y.nodeType===z3)return!1;return J.some(({element:j})=>Z.mathCapabilityByElement.get(j)==="token"&&j.contains(Y)&&j.contains(X))},H3=(Z)=>Z?.type==="range"&&l9(Z.range.startContainer),$4=(Z,Q)=>{if(!H3(Q))return null;let{startContainer:J,endContainer:Y,startOffset:X,endOffset:G}=Q.range;if(J!==Y||J.nodeType!==z3)return null;return Z.renderedMathTargetResolver({type:"text-range",quality:"exact-word",node:J,startOffset:X,endOffset:G})},A4=(Z,Q)=>({chunk:Z,regionTarget:U4(Z),renderedMathTargetResolver:K3(),mathCapabilityByElement:new Map(Z.mathAlignments.map(({element:J})=>[J,Q?W3(J):"expression"])),heldTokenByElement:new Map}),_3=(Z)=>{let Q=Z.mathTokenHighlighting!==!1,J=new Map(Z.chunks.map((Y)=>[Y.id,A4(Y,Q)]));return{chunks:Z.chunks,resolveInitial(Y){let X=J.get(Y);if(!X)return D3();let G=X.chunk.mathAlignments,j=G.length===1?G[0].element:null,B=j?X.mathCapabilityByElement.get(j):null;if(B==="expression")return f9({semanticTarget:null,expressionTarget:A3(X),regionTarget:X.regionTarget,confidence:0.5,reason:"initial expression (sticky expression mode)"});return f9({semanticTarget:null,expressionTarget:null,regionTarget:X.regionTarget,confidence:0,reason:B==="token"?"initial region (sticky token mode, awaiting first token)":"initial region fallback"})},resolveBoundary(Y){let X=J.get(Y.chunkId);if(!X)return D3();let{chunk:G}=X,j=Z3(G,Y),B=$3(G,j),U=K4(B,G),q=(!B||U.length>0?V3(G,j,Y,U,X.renderedMathTargetResolver):null)||null,K=q?.quality==="semantic-token"?q:$4(X,B)??q,$=Q&&K&&K.quality!=="expression"?K:null,D=K&&K.quality==="expression"?K:null;if($){let z=F3(U);if(z)X.heldTokenByElement.set(z,$);return f9({semanticTarget:$,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}if(B&&!H3(B)&&(Q?!q4(X,B,U):U.length===0))return f9({semanticTarget:B,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason});if(V4(X,U)){let z=F3(U),M=z?X.heldTokenByElement.get(z)??null:null;return f9({semanticTarget:M,expressionTarget:null,regionTarget:X.regionTarget,confidence:j.confidence,reason:M?"hold last token (sticky token mode)":"region (sticky token mode, awaiting first token)"})}return f9({semanticTarget:null,expressionTarget:D??A3(X,U),regionTarget:X.regionTarget,confidence:j.confidence,reason:j.reason})}}};var D4=(Z)=>{return Z.alignment?.speech.boundaryOffsetSpace??Z.mathAlignment?.speech.boundaryOffsetSpace??"plain-spoken-text"},F4=(Z)=>{if(Z.mathAlignments?.length)return Z.mathAlignments;if(Z.mathAlignment&&Z.sourceElement)return[{element:Z.sourceElement,alignment:Z.mathAlignment}];return[]},M3=(Z)=>{return(Z.chunks&&Z.chunks.length?Z.chunks:[{speechText:Z.speechText||"",visibleText:Z.visibleText||Z.speechText||"",sourceElement:Z.sourceElement||Z.contentRoot,regionElement:Z.regionElement||Z.sourceElement||Z.contentRoot,regionRange:Z.regionRange,visibleMap:Z.visibleMap}]).map((J,Y)=>({id:`tts-chunk-${Y}`,speechText:J.speechText,visibleText:J.visibleText,sourceElement:J.sourceElement,contentRoot:Z.contentRoot,regionElement:J.regionElement??J.sourceElement,regionRange:J.regionRange,visibleMap:J.visibleMap,catalogAlignment:J.alignment,mathAlignments:F4(J),offsetSpace:D4(J)}))};var z4=["[data-pie-tts-region]","[data-catalog-region]","li","p","label","section","[role='group']","[role='region']","div"].join(","),h0=(Z,Q)=>{let J=b0(Z,z4);if(J&&t(Q,J))return J;return Z};var I9=(Z,Q)=>{let J=Q?.useSentenceSegmenter!==!1;try{if(!J)throw Error("Segmenter disabled by policy");let B=globalThis.Intl?.Segmenter;if(typeof B==="function"){let U=new B(Q?.locale,{granularity:"sentence"}),q=Array.from(U.segment(Z)).map((K)=>({text:K.segment,offset:K.index})).filter((K)=>K.text.trim().length>0);if(q.length>0)return q}}catch{}let Y=/[^.!?]+(?:[.!?]+|$)/g,X=Z.match(Y)||[Z],G=[],j=0;for(let B of X){let U=Z.indexOf(B,j);if(U===-1)continue;G.push({text:B,offset:U}),j=U+B.length}return G.length>0?G:[{text:Z,offset:0}]},e1=(Z,Q,J)=>{let Y=Math.max(1,Math.floor(Q)),X=[],G=-1,j=-1,B=()=>{if(G>=0)X.push({text:Z.slice(G,j),offset:G});G=-1},U=(q,K)=>{if(G>=0&&K-G<=Y){j=K;return}B();let $=q;while(K-$>Y){let z=Z.slice($,$+Y+1).search(/\s\S*$/),M=z>0?$+z:$+Y;X.push({text:Z.slice($,M).trimEnd(),offset:$}),$=M;while($<K&&/\s/.test(Z[$]))$++}if($<K)G=$,j=K};for(let q of I9(Z,J)){let K=q.text.search(/\S/);if(K===-1)continue;let $=q.offset+K;U($,q.offset+q.text.trimEnd().length)}return B(),X};var H4=(Z,Q)=>o9([Z],Q),_4=(Z)=>(Z||"en").split("-")[0].toLowerCase()||"en",M4=new Set(["H1","H2","H3","H4","H5","H6","LI","LABEL","BUTTON"]),L4=new Set(["heading","listitem","option","radio"]),O4=(Z)=>{if(Z.type!=="text"||!Z.sourceElement)return!1;let Q=Z.sourceElement.tagName.toUpperCase(),J=(Z.sourceElement.getAttribute("role")||"").toLowerCase();return M4.has(Q)||L4.has(J)},L3=async(Z)=>{let Q=Z.resolveMathSpeech??H4,J=i1(Z.mathSpeech),{visibleText:Y}=Z,X=[],G=0,j=(U)=>{let q=y(U),K=Y.indexOf(q,G),$=K>=0?K:G,D=$+q.length;return G=D,{start:$,end:D}},B=[];for(let U=0;U<Z.chunks.length;U++){let q=Z.chunks[U];if(q.type==="text"){let M=O4(q)?[{text:q.text,offset:0}]:I9(q.text,{locale:Z.language});for(let O of M){let F=y(O.text);if(!F)continue;let w=j(F);X.push({sourceChunkIndex:U,segment:{kind:"prose",spokenText:F,visibleText:F,visibleSpan:w}}),B.push(F)}continue}let K=j(q.fallbackText),$=await Q(q,{language:Z.language,produceSsml:Z.produceSsml,mathSpeech:Z.mathSpeech,loadSre:J}),D=!$.speechText,z=$.speechText||q.fallbackText;X.push({sourceChunkIndex:U,segment:{kind:"math",spokenText:z,mathml:q.mathml,fallbackText:q.fallbackText,visibleSpan:K,usedFallback:D,ssml:$.ssml}}),B.push(z)}return{segments:X,locale:_4(Z.language),visibleText:Y,plainSpeechText:y(B.join(" "))}};var N4=(Z,Q,J)=>{let Y=new Map;for(let X=Q;X<J;X++){let G=Z.get(X);if(G)Y.set(X-Q,G)}return Y},Z8=async(Z)=>{let Q=D9(Z.contentRoot,Z.textProcessingOptions,Z.range),J=await L3({chunks:Q.chunks,visibleText:Q.visibleText,language:Z.language,mathSpeech:Z.mathSpeech,produceSsml:Z.produceSsml,resolveMathSpeech:Z.resolveMathSpeech});return{plan:{items:J.segments.map(({segment:X,sourceChunkIndex:G})=>{let j=Q.chunks[G];if(X.kind==="prose"){let U=j?.type==="text"?j.sourceElement??Z.contentRoot:Z.contentRoot;return{segment:X,anchor:{sourceElement:U,regionElement:h0(U,Z.contentRoot),visibleMap:N4(Q.map,X.visibleSpan.start,X.visibleSpan.end)}}}let B=j?.type==="math"?j.sourceElement??null:null;return{segment:X,anchor:{sourceElement:B,regionElement:B}}}),locale:J.locale,visibleText:J.visibleText,plainSpeechText:J.plainSpeechText},containsMathMarkup:Q.containsMathMarkup,visibleText:Q.visibleText}};var w4=(Z,Q)=>{let J=f0({speechText:Z.spokenText,visibleText:Z.spokenText});return{speechText:Z.spokenText,visibleText:Z.visibleText,sourceElement:Q.sourceElement,regionElement:Q.regionElement,regionRange:t1(Q.visibleMap,0,Z.visibleText.length)??void 0,speechMatchesVisibleText:!0,playbackMode:J.playbackMode,alignment:J,visibleMap:Q.visibleMap}},O3=(Z,Q)=>{let J=Q.sourceElement;return{speechText:Z.spokenText,visibleText:Z.fallbackText,sourceElement:J,regionElement:Q.regionElement,speechMatchesVisibleText:Z.spokenText===Z.fallbackText,mathAlignment:J?n9({mathElement:J,speechText:Z.spokenText}):void 0}},P4=(Z,Q,J)=>{let Y=Q.sourceElement;return{speechText:J,visibleText:Z.fallbackText,sourceElement:Y,regionElement:Q.regionElement,speechMatchesVisibleText:!1,mathAlignment:Y?n9({mathElement:Y,speechText:J}):void 0,plainFallback:O3(Z,Q)}},Q8=(Z,Q={})=>Z.items.map(({segment:J,anchor:Y})=>{if(J.kind==="prose")return w4(J,Y);if(Q.format==="ssml"&&J.ssml)return P4(J,Y,J.ssml);return O3(J,Y)});function m0(Z){let Q=Z instanceof Error?Z:Error(String(Z));return Q.code="tts-start-failed",Q}var N3="pie-tts-control-handoff";var e=C4("tts-service",R3),P;(function(Z){Z.IDLE="idle",Z.LOADING="loading",Z.PLAYING="playing",Z.PAUSED="paused",Z.ERROR="error"})(P||(P={}));var v9=(Z)=>typeof Z==="string"&&Z.trim()?Z.trim():void 0,w3=(Z,Q={})=>{if(!Z)return Q;return{locale:"locale"in Z?v9(Z.locale):Q.locale,textNormalization:Z.textNormalization&&"locale"in Z.textNormalization?v9(Z.textNormalization.locale):Q.textNormalization,segmenter:Z.segmenter&&"locale"in Z.segmenter?v9(Z.segmenter.locale):Q.segmenter}},P3=(Z)=>("commonAncestorContainer"in Z),E3=(Z,Q)=>Z===Q||Z.startContainer===Q.startContainer&&Z.startOffset===Q.startOffset&&Z.endContainer===Q.endContainer&&Z.endOffset===Q.endOffset,b4=(Z,Q)=>{if(Z===Q)return!0;if(!Z||!Q||Z.type!==Q.type||Z.quality!==Q.quality)return!1;if(Z.type==="range"&&Q.type==="range")return E3(Z.range,Q.range);if(Z.type==="element"&&Q.type==="element")return Z.element===Q.element;if(Z.type==="text-range"&&Q.type==="text-range")return Z.node===Q.node&&Z.startOffset===Q.startOffset&&Z.endOffset===Q.endOffset;return!1};class J8{currentProvider=null;provider=null;highlightCoordinator=null;highlightTargetResolverProvider=null;catalogResolver=null;state=P.IDLE;resumeState=P.PLAYING;ttsConfig={};hostLocales={};readLocale=S0;disposed=!1;readinessGate=null;mathSpeechSource=null;currentText=null;currentContentElement=null;normalizedToDOM=new Map;listeners=new Set;lastError=null;speakRunId=0;currentBoundaryOffset=0;activeWordBoundaryOffset=0;seekSegments=[];playbackChunks=[];activeRecordedAudio=null;sentenceHighlightSegments=[];activeSentenceStartOffset=null;playbackStartDeferredRunId=null;pendingPlaybackStartHighlights=[];playbackStartBarrierCleanup=null;pauseHold=null;structuralPause=null;playbackRateWriteQueue=Promise.resolve();playbackRateRequestId=0;pendingPlaybackRateRequest=null;activePlaybackRate=null;activeHighlightMode="word";lastRenderedRegionTarget=null;telemetryReporter=null;generatedMathSpeechResolver=n1();constructor(){}clearPlaybackStartBarrier(Z=this.playbackStartBarrierCleanup){if(Z?.(),this.playbackStartBarrierCleanup===Z)this.playbackStartBarrierCleanup=null}notifyPlaybackStarted(Z){if(this.playbackStartDeferredRunId!==Z||Z!==this.speakRunId)return;if(this.state===P.PAUSED)this.activeRecordedAudio?.element.pause(),this.provider?.pause();this.markPlaying();let Q=this.pendingPlaybackStartHighlights.splice(0);for(let J of Q)J()}installPlaybackStartBarrier(Z,Q=!1){this.clearPlaybackStartBarrier();let J=this.provider,Y=J&&"onPlaybackStart"in J?J:null;if(!Y&&!Q)return null;let X=Y?.onPlaybackStart,G=()=>{try{this.notifyPlaybackStarted(Z)}finally{X?.()}};if(Y)Y.onPlaybackStart=G;this.playbackStartDeferredRunId=Z;let j=()=>{if(Y?.onPlaybackStart===G)Y.onPlaybackStart=X;if(this.playbackStartDeferredRunId===Z)this.playbackStartDeferredRunId=null,this.pendingPlaybackStartHighlights=[]};return this.playbackStartBarrierCleanup=j,j}runWhenPlaybackStarts(Z,Q){if(this.playbackStartDeferredRunId===Z){this.pendingPlaybackStartHighlights.push(Q);return}Q()}async waitWhilePaused(Z){while(this.state===P.PAUSED&&Z===this.speakRunId){if(!this.pauseHold){let Q=()=>{},J=new Promise((Y)=>{Q=Y});this.pauseHold={promise:J,release:Q}}await this.pauseHold.promise}}releasePauseHold(){let Z=this.pauseHold;this.pauseHold=null,Z?.release()}waitStructuralPause(Z){return this.cancelStructuralPause(),new Promise((Q)=>{let J=()=>{if(this.structuralPause?.finish===J)clearTimeout(this.structuralPause.timer),this.structuralPause=null;Q()};this.structuralPause={timer:setTimeout(J,Z),finish:J}})}cancelStructuralPause(){this.structuralPause?.finish()}abandonRun(){this.clearPlaybackStartBarrier(),this.cancelRecordedAudio(),this.cancelStructuralPause(),this.releasePauseHold()}beginRun(){let Z=this.state===P.LOADING||this.state===P.PLAYING||this.state===P.PAUSED,Q=++this.speakRunId;if(this.abandonRun(),Z)this.provider?.stop();return this.setState(P.LOADING),Q}markPlaying(){if(this.state===P.PAUSED){this.resumeState=P.PLAYING;return}this.setState(P.PLAYING)}assertNotDisposed(){if(this.disposed)throw m0(Error("TTS service disposed"))}async emitTelemetry(Z,Q){try{await this.telemetryReporter?.(Z,Q)}catch(J){console.warn("[TTSService] telemetry callback failed:",J)}}async initialize(Z,Q={}){if(this.disposed)throw Error("TTS service disposed");this.currentProvider=Z,this.ttsConfig={...Q},this.hostLocales=w3(Q.providerOptions);let J=this.providerOptions().__pieTelemetry;this.telemetryReporter=typeof J==="function"?J:null,this.provider=await Z.initialize(Q)}async updateSettings(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q={...Z,...Z.providerOptions?{providerOptions:{...this.providerOptions(),...Z.providerOptions}}:{}};await this.provider.updateSettings(Q),this.ttsConfig={...this.ttsConfig,...Q},this.hostLocales=w3(Z.providerOptions,this.hostLocales)}setHighlightCoordinator(Z){this.highlightCoordinator=Z}setReadinessGate(Z){this.readinessGate=Z}setMathSpeechSource(Z){this.mathSpeechSource=Z}pendingReadiness(){if(this.provider||!this.readinessGate)return null;return this.readinessGate().catch((Z)=>{throw m0(Z)})}setHighlightTargetResolverProvider(Z){return this.highlightTargetResolverProvider=Z,()=>{if(this.highlightTargetResolverProvider===Z)this.highlightTargetResolverProvider=null}}setCatalogResolver(Z){this.catalogResolver=Z}getHighlightResolverRuntime(){let Z=null;try{Z=this.highlightTargetResolverProvider?.()??null}catch{Z=null}let Q=Z?.context??{},J=typeof HTMLElement<"u"&&this.currentContentElement instanceof HTMLElement?this.currentContentElement:null;return{context:{...Q,scopeElement:Q.scopeElement??J},resolver:Z?.resolver??null}}getNodeElement(Z){if(!Z)return null;return Z.nodeType===Node.ELEMENT_NODE?Z:d(Z)}isElementWithinScope(Z,Q){if(!Q)return!0;return t(Q,Z)}isRangeWithinScope(Z,Q){let J=this.getNodeElement(Z.startContainer),Y=this.getNodeElement(Z.endContainer);if(!J||!Y)return!1;return this.isElementWithinScope(J,Q)&&this.isElementWithinScope(Y,Q)}resolveWordHighlightRange(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveWordRange?.(Z,Q);if(X&&this.isRangeWithinScope(X,Y))return{range:X,remapped:!E3(Z,X)}}catch{}return{range:Z,remapped:!1}}resolveSentenceHighlightTargets(Z){let{context:Q,resolver:J}=this.getHighlightResolverRuntime(),Y=Q.scopeElement??this.currentContentElement;try{let X=J?.resolveSentenceRanges?.(Z,Q);if(!X)return{ranges:Z,elements:[]};let G=[],j=[];for(let B of X){if(typeof Range<"u"&&B instanceof Range){if(!this.isRangeWithinScope(B,Y))return{ranges:Z,elements:[]};G.push(B);continue}if(typeof Element<"u"&&B instanceof Element){if(!this.isElementWithinScope(B,Y))return{ranges:Z,elements:[]};j.push(B);continue}return{ranges:Z,elements:[]}}return{ranges:G,elements:j}}catch{return{ranges:Z,elements:[]}}}createTextRange(Z,Q,J){if(typeof document>"u")return null;if(typeof document.createRange!=="function")return null;try{let Y=document.createRange();if(Y.setStart(Z,Q),Y.setEnd(Z,J),Y.startContainer!==Z||Y.endContainer!==Z)return null;return Y}catch{return null}}paintTTSWord(Z){if(!this.highlightCoordinator||Z.length===0)return;this.highlightCoordinator.highlightTTSWord(Z.map((Q)=>this.resolveWordHighlightRange(Q).range))}paintTTSSentenceRanges(Z){if(!this.highlightCoordinator)return;let{ranges:Q,elements:J}=this.resolveSentenceHighlightTargets(Z);if(J.length>0&&Q.length===0){this.highlightCoordinator.highlightTTSSentenceElements(J);return}let Y=[...Q];for(let X of J){let G=document.createRange();G.selectNodeContents(X),Y.push(G)}this.highlightCoordinator.highlightTTSSentence(Y)}getCapabilities(){return this.currentProvider?.getCapabilities()||null}providerOptions(){let Z=this.ttsConfig.providerOptions;return Z&&typeof Z==="object"?Z:{}}maxTextLength(){let Z=this.currentProvider?.getCapabilities?.().maxTextLength;return typeof Z==="number"&&Z>0?Z:void 0}async speakWithinLimit(Z,Q){let J=this.provider;if(!J)return;let Y=this.maxTextLength();if(!Y||Z.length<=Y){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;await J.speak(Z);return}if(x0(Z))throw Error(`[tts] SSML of ${Z.length} characters exceeds the provider's limit of ${Y}`);let X=J.onWordBoundary;try{for(let G of e1(Z,Y,{locale:this.readLocale})){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==J)return;J.onWordBoundary=X?(j,B,U)=>X(j,B+G.offset,U):void 0,await J.speak(G.text)}}finally{if(this.provider===J&&Q===this.speakRunId)J.onWordBoundary=X}}segmentsWithinLimit(Z){let Q=this.maxTextLength();if(!Q)return Z;return Z.flatMap((J)=>{if(J.text.length<=Q)return[J];let Y=e1(J.text,Q,{locale:this.readLocale});return Y.map((X,G)=>({text:X.text,startOffset:J.startOffset+X.offset,pauseMsAfter:G===Y.length-1?J.pauseMsAfter:void 0}))})}getTextProcessingOptions(Z){let Q=this.providerOptions().textNormalization?.boundarySpacingMode;return{locale:Z,boundarySpacingMode:Q==="none"||Q==="alnum"||Q==="segmenterPreferred"?Q:void 0}}resolveReadLanguage(Z,Q){let J=x1(Z,{contentLanguage:Q})??v9(this.providerOptions().lang_id);return{contentLanguage:J,locale:J??this.hostLocales.locale??this.hostLocales.textNormalization??S0}}getMathSpeechOptions(){if(this.mathSpeechSource)return W9(this.mathSpeechSource());return W9(this.providerOptions().mathSpeech)}buildPositionMap(Z,Q,J){this.normalizedToDOM.clear();let{text:Y,map:X}=b9(Z,this.getTextProcessingOptions(J));if(this.normalizedToDOM=X,!R3())return;e.debug("Text comparison:",{spokenLength:Q.length,normalizedDomLength:Y.length,match:Q===Y,spokenPreview:Q.substring(0,150),normalizedPreview:Y.substring(0,150),differAtIndex:Q===Y?null:(()=>{for(let G=0;G<Math.min(Q.length,Y.length);G++)if(Q[G]!==Y[G])return{index:G,spokenChar:Q[G],normalizedChar:Y[G],spokenContext:Q.substring(Math.max(0,G-20),G+20),normalizedContext:Y.substring(Math.max(0,G-20),G+20)};return null})()}),e.debug("Position map built:",{entries:this.normalizedToDOM.size,spokenTextLength:Q.length,normalizedDomLength:Y.length,mapLengthMatchesSpoken:this.normalizedToDOM.size===Q.length,firstFewMappings:Array.from(this.normalizedToDOM.entries()).slice(0,10).map(([G,{node:j,offset:B}])=>({pos:G,offset:B,char:j.textContent?.[B],expected:Q[G]}))})}getStructuralPauseProfile(){let Z=this.providerOptions().structuralPauses||{},Q=Z.units||{},J=(Y,X)=>{if(typeof Y==="number"&&Number.isFinite(Y))return Y;if(typeof Y==="string"&&Y.trim()){let G=Number(Y);return Number.isFinite(G)?G:X}return X};return{baseMs:J(Z.baseMs,280),units:{minor:J(Q.minor,0.65),section:J(Q.section,1),major:J(Q.major,1.35)},minMs:J(Z.minMs,120),maxMs:J(Z.maxMs,900)}}resolvePauseMsFromUnits(Z){let Q=this.getStructuralPauseProfile(),J=Math.max(0.25,Math.min(4,Number(this.ttsConfig.rate||1))),Y=Q.baseMs*Math.max(0,Z)/J;return Math.max(Q.minMs,Math.min(Q.maxMs,Math.round(Y)))}resolveHighlightMode(){let Z=this.providerOptions().highlightMode;if(Z==="word"||Z==="sentence")return Z;let Q=this.currentProvider?.getCapabilities();if(Q?.defaultHighlightMode)return Q.defaultHighlightMode;return Q?.supportsWordBoundary?"word":"sentence"}hasExplicitBreakSemantics(Z){if(!Z.includes("<"))return!1;return/<\s*break\b|<\s*speak\b|<\s*prosody\b|<\s*p\b|<\s*s\b/i.test(Z)}isElementHidden(Z){return k1(Z)}getBoundaryStrength(Z){let Q=Number(Z.getAttribute("data-tts-break-ms"));if(Number.isFinite(Q)&&Q>0)return"major";let J=Z.tagName.toUpperCase();if(J.match(/^H[1-6]$/))return"major";let Y=(Z.getAttribute("role")||"").toLowerCase();if(Y==="heading")return"major";if(Y==="listitem"||Y==="row"||Y==="option"||Y==="radio"||J==="LI")return"section";if(typeof window<"u"){let X=window.getComputedStyle(Z).display;if(X==="block"||X==="list-item"||X.startsWith("table")||X==="flex"||X==="grid")return"minor"}return"minor"}getBoundaryAnchor(Z,Q){let J=c(Z),Y=null;while(J&&J!==Q){if(this.isElementHidden(J))return null;let G=Number(J.getAttribute("data-tts-break-ms"));if(Number.isFinite(G)&&G>0)return{anchor:J,units:G/this.getStructuralPauseProfile().baseMs};let j=(J.getAttribute("role")||"").toLowerCase(),B=J.tagName.toUpperCase();if(B.match(/^H[1-6]$/)||j==="heading"||j==="listitem"||B==="LI"){Y=J;break}if(!Y){if(typeof window<"u"){let U=window.getComputedStyle(J).display;if(U==="block"||U==="list-item"||U.startsWith("table")||U==="flex"||U==="grid")Y=J}}J=c(J)}if(!Y)return null;let X=this.getBoundaryStrength(Y);return{anchor:Y,units:this.getStructuralPauseProfile().units[X]}}createSpeechPlan(Z,Q,J,Y){let X=this.collectSpeechPlanBoundaries(Z,Q,Y);if(J===0)return this.createSpeechPlanSegments(Q,X);let G=new Map;for(let[j,B]of X)G.set(j-J,B);return this.createSpeechPlanSegments(Q,G)}collectSpeechPlanBoundaries(Z,Q,J){let Y=new Map,{map:X}=b9(Z,this.getTextProcessingOptions(J)),G=this.createNodeStartOffsets(X),j=null;for(let B of R9(Z)){let U=c(B);if(U&&!this.isElementHidden(U)&&!T0(B)){let q=this.getBoundaryAnchor(B,Z),K=G.get(B);if(q&&K!==void 0&&q.anchor!==j&&K>0)Y.set(K,Math.max(Y.get(K)||0,q.units)),j=q.anchor}}return Y}createNodeStartOffsets(Z){let Q=new Map;for(let[J,Y]of Z.entries())if(!Q.has(Y.node))Q.set(Y.node,J);return Q}createSpeechPlanSegments(Z,Q){let J=Array.from(Q.keys()).filter((U)=>U>0&&U<Z.length).sort((U,q)=>U-q),Y=[],X=0;for(let U of J){let q=Z.substring(X,U),K=q.match(/^\s*/)?.[0].length||0,$=q.match(/\s*$/)?.[0].length||0,D=X+K,z=U-$;if(z>D){let M=Z.substring(D,z);Y.push({text:M,startOffset:D,pauseMsAfter:this.resolvePauseMsFromUnits(Q.get(U)||0)})}X=U}let j=Z.substring(X).match(/^\s*/)?.[0].length||0,B=X+j;if(B<Z.length)Y.push({text:Z.substring(B).trimEnd(),startOffset:B,pauseMsAfter:0});return Y.filter((U)=>U.text.trim().length>0)}segmentSentences(Z){return I9(Z,{locale:this.readLocale})}createSeekSegmentsFromText(Z){return this.segmentSentences(Z).map((Q)=>{let J=Q.text.match(/^\s*/)?.[0].length||0;return{text:Q.text.trim(),startOffset:Q.offset+J,pauseMsAfter:0}}).filter((Q)=>Q.text.length>0)}splitSegmentsAtBoundaries(Z,Q,J){if(Z.length===0||Q.length===0)return Z;let Y=Array.from(new Set(Q)).filter((G)=>Number.isFinite(G)&&G>0).sort((G,j)=>G-j);if(Y.length===0)return Z;let X=[];for(let G of Z){let j=G.startOffset,B=G.startOffset+G.text.length,U=Y.filter((K)=>K>j&&K<B);if(U.length===0){X.push(G);continue}let q=j;for(let K of[...U,B]){let $=J.substring(q,K),D=$.match(/^\s*/)?.[0].length||0,z=$.match(/\s*$/)?.[0].length||0,M=q+D,O=K-z;if(O>M)X.push({text:J.substring(M,O),startOffset:M,pauseMsAfter:0});q=K}}return X}createSentenceHighlightSegments(Z){let Q=this.createSeekSegmentsFromText(Z.contentToSpeak);if(!Z.shouldUsePlan||Z.playbackSegments.length===0)return Q;let J=Z.playbackSegments.map((Y)=>Y.startOffset).filter((Y)=>Y>0);return this.splitSegmentsAtBoundaries(Q,J,Z.contentToSpeak)}createSeekSegmentsFromSpeechChunks(Z){let Q=0;return Z.map((J)=>{let Y=J.plainFallback?.speechText||(this.hasExplicitBreakSemantics(J.speechText)?J.visibleText:J.speechText)||J.visibleText,X=y(Y)||J.visibleText||"",G={text:X,startOffset:Q,pauseMsAfter:0};return Q+=Math.max(1,X.length+1),G})}getCurrentSeekSegmentIndex(){if(this.seekSegments.length===0)return 0;let Z=0;for(let Q=0;Q<this.seekSegments.length;Q++)if(this.seekSegments[Q].startOffset<=this.currentBoundaryOffset)Z=Q;else break;return Z}async speakWithPlan(Z,Q,J){if(!this.provider||Z.length===0)return;let Y=J?.highlightMode==="sentence",X=this.provider;if(!Y&&typeof X.speakSegments==="function"){if(await this.waitWhilePaused(Q),Q!==this.speakRunId||this.provider!==X)return;this.currentBoundaryOffset=0;let G=this.provider.onWordBoundary;this.provider.onWordBoundary=(j,B,U)=>{if(G?.(j,B,U),Number.isFinite(B))this.currentBoundaryOffset=B};try{await X.speakSegments(this.segmentsWithinLimit(Z))}finally{if(Q===this.speakRunId&&this.provider===X)this.provider.onWordBoundary=G}return}this.configureWordBoundaryHighlighting({highlightMode:J?.highlightMode||"word",wordBoundaryOffset:this.activeWordBoundaryOffset});for(let G of Z){if(await this.waitWhilePaused(Q),Q!==this.speakRunId)return;if(this.currentBoundaryOffset=G.startOffset,Y)this.runWhenPlaybackStarts(Q,()=>{this.highlightSentenceSegment(G.startOffset,G.text)});await this.speakWithinLimit(G.text,Q);let j=G.pauseMsAfter??0;if(j>0&&Q===this.speakRunId)await this.waitStructuralPause(j)}}highlightSentenceSegment(Z,Q){if(!this.highlightCoordinator||typeof document>"u")return;let J=Q.trimEnd().length;if(J<=0)return;let Y=Z+this.activeWordBoundaryOffset,X=this.normalizedToDOM.get(Y),G=this.normalizedToDOM.get(Y+J-1);if(!X||!G)return;let j=z9(this.normalizedToDOM,Y,Y+J);if(j.length===0)return;this.paintTTSSentenceRanges(j),this.activeSentenceStartOffset=Z}getSegmentIndexForOffset(Z,Q){if(Z.length===0)return-1;let J=-1;for(let Y=0;Y<Z.length;Y++)if(Z[Y].startOffset<=Q)J=Y;else break;return J}highlightSentenceForOffset(Z){let Q=this.sentenceHighlightSegments;if(!this.highlightCoordinator||Q.length===0)return;let J=this.getSegmentIndexForOffset(Q,Z);if(J<0)return;let Y=Q[J];if(!Y)return;if(this.activeSentenceStartOffset===Y.startOffset)return;this.highlightSentenceSegment(Y.startOffset,Y.text)}async speak(Z,Q={}){this.assertNotDisposed();let J=this.pendingReadiness(),Y=J?this.beginRun():null;if(J){try{await J}catch(j){if(Y===this.speakRunId)this.setState(P.IDLE);throw j}if(this.assertNotDisposed(),Y!==this.speakRunId)return}if(!this.provider){if(Y!==null)this.setState(P.IDLE);throw m0(Error("TTS service not initialized"))}let X=this.resolveReadLanguage(P3(Z)?Z.startContainer:Z,Q.language),G=P3(Z)?this.resolveRangeTarget(Z,Q,X):this.resolveElementTarget(Z,Q,X);if(!G){if(Y!==null)this.setState(P.IDLE);return}await this.speakContent(G.text,G.options,Y??this.beginRun())}isSuppressedTarget(Z){if(!T0(Z))return!1;return console.warn("[tts] the content to read lies inside content marked not-to-be-spoken; nothing was spoken."),!0}resolveElementTarget(Z,Q,J){if(this.isSuppressedTarget(Z))return null;let Y=D9(Z,this.getTextProcessingOptions(J.locale)).visibleText.trim();if(!Y)return console.warn("[tts] the content to read holds no speakable text; nothing was spoken."),null;return{text:Y,options:{catalogId:Q.catalogId,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:Z}}}resolveRangeTarget(Z,Q,J){if(this.isSuppressedTarget(Z.commonAncestorContainer))return null;let Y=Z.commonAncestorContainer,X=Q.contentRoot||(Y.nodeType===Node.ELEMENT_NODE?Y:d(Y));if(!X)return null;let G=f1(Z,X),j=G.text.trim();if(!j){if(G.filtered)console.warn("[tts] every part of the selection is either hidden or marked not-to-be-spoken; nothing was spoken.");return null}let B=this.selectMappedRangeText(Z,X,J.locale),U=j,q=B?.offset??0;if(B)U=B.text;else{let K=document.createRange();K.selectNodeContents(X),K.setEnd(Z.startContainer,Z.startOffset);let $=f1(K,X).text,D=y($);q=D.length+(/\s$/.test($)&&D?1:0)}return e.debug("selection offset calculation:",{selectedText:U,mapped:!!B,offset:q,rootTag:X.tagName}),{text:U,options:{catalogId:Q.catalogId&&A0(Z,X,X)?Q.catalogId:void 0,catalogContext:Q.catalogContext,language:J.locale,contentLanguage:J.contentLanguage,contentElement:X,contentRange:Z,wordBoundaryOffset:q}}}async speakContent(Z,Q,J){let Y=null;try{if(await this.applyLanguageSettings(Q),J!==this.speakRunId)return;let X=await this.resolveSpeechContent(Z,Q);if(J!==this.speakRunId)return;let{contentToSpeak:G,speechText:j,highlightText:B,normalizedText:U,usedCatalogSpoken:q,speechSource:K,speechMatchesVisibleText:$,speechChunks:D}=X;this.logResolvedSpeechContent({contentToSpeak:G,speechSource:K,catalogId:Q?.catalogId}),this.initializeSpeakTracking(B,Q);let z=$?this.resolveHighlightMode():"sentence";this.activeHighlightMode=z,this.activeWordBoundaryOffset=Q?.wordBoundaryOffset||0;let M=this.hasExplicitBreakSemantics(G),O=!!this.currentContentElement&&!q&&!M&&$;if(this.playbackChunks=D?.length?D:[],this.seekSegments=this.playbackChunks.length?this.createSeekSegmentsFromSpeechChunks(this.playbackChunks):M||!$?[]:O&&this.currentContentElement?this.createSpeechPlan(this.currentContentElement,U,Q?.wordBoundaryOffset||0,Q?.language):this.createSeekSegmentsFromText(B),this.sentenceHighlightSegments=M?[]:this.createSentenceHighlightSegments({contentToSpeak:B,shouldUsePlan:O,playbackSegments:this.seekSegments}),Y=this.installPlaybackStartBarrier(J,!!this.playbackChunks[0]?.audio),this.prepareHighlightsForSpeak({contentToSpeak:B,options:Q,highlightMode:z,shouldUsePlan:O,runId:J}),$)this.configureWordBoundaryHighlighting({highlightMode:z,wordBoundaryOffset:Q?.wordBoundaryOffset||0});else this.clearWordBoundaryHighlighting();if(!Y)this.markPlaying();if(this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1)),await this.executeSpeakPlayback({shouldUsePlan:O,runId:J,highlightMode:z,contentToSpeak:j,speechChunks:D}),J!==this.speakRunId)return;this.setState(P.IDLE),this.clearHighlightsAndTracking()}catch(X){if(J!==this.speakRunId)return;throw console.error("TTS error:",X),this.lastError=X instanceof Error?X.message:String(X),this.setState(P.ERROR),this.clearHighlightsAndTracking(),X}finally{this.clearPlaybackStartBarrier(Y)}}async applyLanguageSettings(Z){if(!this.provider)return;this.readLocale=Z.language;let Q=Z.contentLanguage,J=this.providerOptions(),Y={locale:Q??this.hostLocales.locale,textNormalization:Q??this.hostLocales.textNormalization,segmenter:Q??this.hostLocales.segmenter};if(J.contentLanguage===Q&&v9(J.locale)===Y.locale&&v9(J.textNormalization?.locale)===Y.textNormalization&&v9(J.segmenter?.locale)===Y.segmenter)return;let X={...J,locale:Y.locale,textNormalization:{...J.textNormalization,locale:Y.textNormalization},segmenter:{...J.segmenter,locale:Y.segmenter},contentLanguage:Q};this.ttsConfig={...this.ttsConfig,providerOptions:X},await this.provider.updateSettings({providerOptions:X})}async resolveSpeechContent(Z,Q){let J=y(Z);if(Q.catalogId&&this.catalogResolver){let G=this.catalogResolver.getAlternative(Q.catalogId,{type:"spoken",language:Q.language,useFallback:!0,context:Q.catalogContext,form:"content"}),j=G?.content;if(G&&j!==void 0){let B=D9(Q.contentElement,this.getTextProcessingOptions(Q.language)).visibleText||J,U=y(j);return e.debug(`Using catalog content for "${Q.catalogId}" (${G.language})`),{contentToSpeak:j,speechText:j,visibleText:B,highlightText:B,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:B,containsMathMarkup:!1,speechMatchesVisibleText:U===B}}e.debug(`No catalog found for "${Q.catalogId}", falling back to generated TTS`)}let Y=this.resolveCatalogComposedSpeechContent(Q.contentElement,J,Q);if(Y)return Y;return{...await this.resolveGeneratedSpeechContent(Q.contentElement,J,Q.language,Q.contentRange),usedCatalogSpoken:!1,speechSource:"dom-or-input"}}resolveCatalogComposedSpeechContent(Z,Q,J){if(!this.catalogResolver)return null;let Y=this.collectCatalogSpeechChunks(Z,J);if(!Y.some((j)=>j.sourceElement))return null;let X=y(Y.map((j)=>j.speechText).join(" ")),G=J.contentRange?Q:D9(Z,this.getTextProcessingOptions(J.language)).visibleText||Q;return{contentToSpeak:X,speechText:X,visibleText:G,highlightText:G,usedCatalogSpoken:!0,speechSource:"catalog-spoken",normalizedText:G,containsMathMarkup:!1,speechMatchesVisibleText:Y.every((j)=>j.speechMatchesVisibleText),speechChunks:Y}}collectCatalogSpeechChunks(Z,Q){let J=[],Y="",X=()=>{let K=y(Y);if(Y="",!K)return;J.push({speechText:K,visibleText:K,sourceElement:null,speechMatchesVisibleText:!0})},G=Q.contentRange,j=(K)=>{let $=K.getAttribute("data-catalog-idref");if(!$)return null;if(G&&!A0(G,K,Z))return null;let D={type:"spoken",language:y1(K,Z)||Q.language,useFallback:!0,context:Q.catalogContext},z=this.catalogResolver.getAlternative($,{...D,form:"payload"}),M=z?.payload?HZ({payload:z.payload})??void 0:void 0,F=this.catalogResolver.getAlternative($,{...D,form:"content"})?.content;if(M===void 0&&F===void 0)return null;return{script:F,audio:M}},B=(K,$)=>{let D=U(K);if(D.length!==1)return null;let z=D[0],M=D9(z,this.getTextProcessingOptions(Q.language)).visibleText||y(z.textContent||""),O=(F)=>y(F).replace(/\s+/g,"");return O(M)===O($)?z:null},U=(K)=>{let $=KZ(K,"math");if(K.localName?.toLowerCase()==="math")return[K,...$];return $},q=(K)=>{if(A9(K,Z))return;if(K.nodeType===Node.TEXT_NODE){if(!G)Y+=` ${K.textContent||""}`;else if(X9(G,K))Y+=` ${I1(K,G)}`;return}if(K.nodeType!==Node.ELEMENT_NODE)return;let $=K,D=j($);if(D){X();let z=D9($,this.getTextProcessingOptions(Q.language)),M=z.visibleText||y(UZ($)),O=h0($,Z),F=D.script!==void 0?(()=>{let w=D.script,R=f0({speechText:w,visibleText:M}),b=B($,M),S=b?n9({mathElement:b,speechText:w}):void 0,h=S?void 0:U($).map((C)=>({element:C,alignment:n9({mathElement:C,speechText:w})}));return{speechText:w,visibleText:M,sourceElement:$,regionElement:O,speechMatchesVisibleText:y(w)===M,playbackMode:R.playbackMode,alignment:R,mathAlignment:S,mathAlignments:h,visibleMap:z.map}})():null;if(D.audio){J.push(F?{...F,audio:D.audio,plainFallback:F}:{speechText:M,visibleText:M,sourceElement:$,regionElement:O,speechMatchesVisibleText:!1,visibleMap:z.map,audio:D.audio});return}if(F)J.push(F);return}for(let z of $9($))q(z)};return q(Z),X(),J}resolveGeneratedPlaybackFormat(){let Z=this.currentProvider;if(!Z)return"plain";return Z.getCapabilities?.().supportsSSML?"ssml":"plain"}async resolveGeneratedSpeechContent(Z,Q,J,Y){let X=this.resolveGeneratedPlaybackFormat(),{plan:G,containsMathMarkup:j,visibleText:B}=await Z8({contentRoot:Z,range:Y,language:J,mathSpeech:this.getMathSpeechOptions(),textProcessingOptions:this.getTextProcessingOptions(J),produceSsml:X==="ssml",resolveMathSpeech:this.generatedMathSpeechResolver});if(!j){let $=Y?Q:B||Q;return{contentToSpeak:$,speechText:$,visibleText:$,highlightText:$,normalizedText:$,containsMathMarkup:!1,speechMatchesVisibleText:!0}}let U=B||Q,q=Q8(G,{format:X}),K=G.plainSpeechText;return{contentToSpeak:K,speechText:K,visibleText:U,highlightText:U,normalizedText:U,containsMathMarkup:!0,speechMatchesVisibleText:K===U,speechChunks:q}}logResolvedSpeechContent(Z){let Q=Z.contentToSpeak.replace(/\s+/g," ").trim().slice(0,200);e.debug("Speak resolved content",{source:Z.speechSource,catalogId:Z.catalogId||null,length:Z.contentToSpeak.length,preview:Q})}initializeSpeakTracking(Z,Q){this.currentText=Z,this.currentContentElement=Q.contentElement,this.lastError=null,this.currentBoundaryOffset=0,this.playbackChunks=[],this.activeSentenceStartOffset=null}prepareHighlightsForSpeak(Z){if(!this.currentContentElement||!this.highlightCoordinator)return;if(this.buildPositionMap(this.currentContentElement,Z.contentToSpeak,Z.options.language),Z.highlightMode==="sentence"&&Z.shouldUsePlan)return;let Q=this.sentenceHighlightSegments[0]||this.seekSegments[0];this.runWhenPlaybackStarts(Z.runId,()=>{if(Q)this.highlightSentenceSegment(Q.startOffset,Q.text),e.debug("Applied initial sentence highlighting");else try{let J=document.createRange();J.selectNodeContents(this.currentContentElement),this.paintTTSSentenceRanges([J])}catch{}})}configureWordBoundaryHighlighting(Z){if(!this.provider)return;if(Z.highlightMode==="sentence"){this.provider.onWordBoundary=void 0;return}if(!this.highlightCoordinator||!this.currentContentElement)return;this.provider.onWordBoundary=(Q,J,Y)=>{let X=Y||Q.length,G=J+this.currentBoundaryOffset,j=G+Z.wordBoundaryOffset;this.highlightSentenceForOffset(G);let B=z9(this.normalizedToDOM,j,j+X);if(B.length===0){e.debug(`no text at position ${j}, length ${X}, to highlight`);return}e.debug(`Highlighting "${B.join("")}" (word: "${Q}") at position ${j}`),this.paintTTSWord(B)}}clearWordBoundaryHighlighting(){if(this.provider)this.provider.onWordBoundary=void 0}highlightCatalogRegion(Z){let Q=Z.regionElement||Z.sourceElement;if(!Q&&!Z.regionRange||!this.highlightCoordinator)return;try{if(this.lastRenderedRegionTarget=null,Z.regionRange){let Y=z9(Z.visibleMap,0,Z.visibleText.length);this.highlightCoordinator.clearHighlights(i.TTS_WORD),this.paintTTSSentenceRanges(Y.length>1?Y:[Z.regionRange]);return}if(!Q)return;let J=document.createRange();J.selectNodeContents(Q),this.highlightCoordinator.clearHighlights(i.TTS_WORD),this.paintTTSSentenceRanges([J])}catch{}}highlightRenderableRegionTarget(Z){if(!this.highlightCoordinator||!Z||typeof document>"u")return;if(!this.highlightTargetResolverProvider&&b4(this.lastRenderedRegionTarget,Z))return;try{let Q=document.createRange();if(Z.type==="element")Q.selectNodeContents(Z.element);else if(Z.type==="range"){this.paintTTSSentenceRanges(Z.ranges??[Z.range]),this.lastRenderedRegionTarget=Z;return}else Q.setStart(Z.node,Z.startOffset),Q.setEnd(Z.node,Z.endOffset);this.paintTTSSentenceRanges([Q]),this.lastRenderedRegionTarget=Z}catch{}}highlightRenderableActiveTarget(Z){if(!this.highlightCoordinator||typeof document>"u")return;if(!Z){this.highlightCoordinator.clearHighlights(i.TTS_WORD);return}if(Z.type==="text-range"){let X=this.createTextRange(Z.node,Z.startOffset,Z.endOffset);if(X)this.paintTTSWord([X]);return}if(Z.type==="range"){this.paintTTSWord(Z.ranges??[Z.range]);return}let Q=document.createRange();Q.selectNodeContents(Z.element);let J=this.resolveWordHighlightRange(Q);if(J.remapped){this.highlightCoordinator.highlightTTSWord([J.range]);return}let Y=Z.element.childNodes.length===1?Z.element.firstChild:null;if(Z.quality==="semantic-token"&&Y?.nodeType===Node.TEXT_NODE){let X=document.createRange();X.selectNodeContents(Y),this.highlightCoordinator.highlightTTSWord([X]);return}this.highlightCoordinator.highlightTTSWordElement(Z.element)}renderHighlightDecision(Z){this.highlightRenderableRegionTarget(Z.regionTarget),this.highlightRenderableActiveTarget(Z.activeTarget)}async speakCatalogChunk(Z,Q){try{await this.speakCatalogChunkOnce(Z,Q)}catch(J){if(Z.plainFallback&&Q===this.speakRunId){if(e.debug("SSML chunk speak failed; retrying plain text",{message:J instanceof Error?J.message:String(J)}),this.playbackStartDeferredRunId===Q&&this.provider&&!("onPlaybackStart"in this.provider))this.pendingPlaybackStartHighlights=[],this.clearPlaybackStartBarrier(),this.markPlaying();await this.speakCatalogChunkOnce(Z.plainFallback,Q);return}throw J}}async playRecordedAudio(Z,Q){if(typeof document>"u")throw Error("[tts] no document available to play recorded audio");let J=Z.sources[0],Y=document.createElement("audio");Y.preload="auto",Y.src=R4(J.src,Z.fragment),Y.playbackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate||1)),await new Promise((X,G)=>{let j,B=!1,U=!1,q=()=>{if(U||B)return;B=!0,Q?.()},K=()=>{if(Y.removeEventListener("ended",$),Y.removeEventListener("error",D),Y.removeEventListener("playing",q),j?.(),this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null},$=()=>{if(U)return;U=!0,K(),X()},D=()=>{if(U)return;U=!0,K(),G(Error(`[tts] recorded audio failed to play: ${J.src}`))},z=()=>{Promise.resolve(Y.play()).then(q).catch((M)=>{if(M?.name==="AbortError"&&this.state===P.PAUSED)return;D()})};this.activeRecordedAudio={element:Y,cancel:()=>{if(U)return;U=!0,K(),Y.pause(),X()},play:z},Y.addEventListener("ended",$),Y.addEventListener("error",D),Y.addEventListener("playing",q),j=E4(Y,Z.fragment,$),z()}).finally(()=>{if(this.activeRecordedAudio?.element===Y)this.activeRecordedAudio=null;Y.pause(),Y.removeAttribute("src")})}cancelRecordedAudio(){let Z=this.activeRecordedAudio;if(!Z)return;this.activeRecordedAudio=null,Z.cancel()}async speakCatalogChunkOnce(Z,Q){if(!this.provider)return;if(this.lastRenderedRegionTarget=null,Z.audio){this.runWhenPlaybackStarts(Q,()=>{this.highlightCatalogRegion(Z)}),await this.playRecordedAudio(Z.audio,()=>{this.notifyPlaybackStarted(Q)});return}let J=Z.regionElement||Z.sourceElement||this.currentContentElement,Y=J?M3({contentRoot:J,chunks:[Z]})[0]:null,X=this.ttsConfig.mathTokenHighlighting!==!1,G=Y?_3({chunks:[Y],mathTokenHighlighting:X}):null;if(this.runWhenPlaybackStarts(Q,()=>{if(G&&Y&&Z.mathAlignment)this.renderHighlightDecision(G.resolveInitial(Y.id));else this.highlightCatalogRegion(Z)}),!(this.resolveHighlightMode()==="word"&&Z.sourceElement&&(Z.mathAlignment&&Z.mathAlignment.speech.tokens.length>0||Z.mathAlignments&&Z.mathAlignments.length>0||Z.alignment&&Z.visibleMap&&(Z.playbackMode==="exact-word"||Z.playbackMode==="anchor-span")))){let K=this.provider,$=K.onWordBoundary;K.onWordBoundary=void 0;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===K&&Q===this.speakRunId&&K.onWordBoundary===void 0)K.onWordBoundary=$}return}let B=this.provider,U=B.onWordBoundary,q=(K,$,D)=>{if(Q!==this.speakRunId)return;if(G&&Y){let z=Y.offsetSpace==="unsupported"?"unknown":Y.offsetSpace;this.renderHighlightDecision(G.resolveBoundary({chunkId:Y.id,word:K,position:$,length:D,providerOffsetSpace:z}));return}};B.onWordBoundary=q;try{await this.speakWithinLimit(Z.speechText,Q)}finally{if(this.provider===B&&Q===this.speakRunId&&B.onWordBoundary===q)B.onWordBoundary=U}}async executeSpeakPlayback(Z){if(Z.speechChunks?.length&&this.provider){for(let Q=0;Q<Z.speechChunks.length;Q++){if(await this.waitWhilePaused(Z.runId),Z.runId!==this.speakRunId)return;let J=this.seekSegments[Q];if(J)this.currentBoundaryOffset=J.startOffset;let Y=Z.speechChunks[Q];await this.speakCatalogChunk(Y,Z.runId)}return}if(Z.shouldUsePlan&&this.currentContentElement){let Q=this.seekSegments;if(Q.length>0)await this.speakWithPlan(Q,Z.runId,{highlightMode:Z.highlightMode});else await this.speakWithinLimit(Z.contentToSpeak,Z.runId);return}await this.speakWithinLimit(Z.contentToSpeak,Z.runId)}clearHighlightsAndTracking(){if(this.clearWordBoundaryHighlighting(),this.pendingPlaybackStartHighlights=[],this.activePlaybackRate=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null}selectMappedRangeText(Z,Q,J){if(typeof Z.comparePoint!=="function")return null;let{text:Y,map:X}=b9(Q,this.getTextProcessingOptions(J)),G=-1,j=-1;for(let[K,{node:$,offset:D}]of X){if(K>=Y.length)continue;if(!U0(Z,$,D))continue;if(G===-1||K<G)G=K;if(K>j)j=K}if(G===-1)return null;let B=Y.slice(G,j+1),U=B.length-B.trimStart().length,q=B.trim();return q?{text:q,offset:G+U}:null}pause(){if(this.state!==P.PLAYING&&this.state!==P.LOADING)return;this.resumeState=this.state,this.activeRecordedAudio?.element.pause(),this.provider?.pause(),this.setState(P.PAUSED)}resume(){if(this.state!==P.PAUSED)return;this.setState(this.resumeState),this.activeRecordedAudio?.play(),this.provider?.resume(),this.releasePauseHold()}normalizePlaybackRate(Z){if(!Number.isFinite(Z))return 1;return Math.max(0.25,Math.min(4,Z))}async restartFromSeekIndex(Z){if(!this.provider||this.seekSegments.length===0)return;let Q=Math.max(0,Math.min(this.seekSegments.length-1,Z)),J=this.playbackChunks.length?this.playbackChunks.slice(Q):null,Y=this.state===P.PAUSED;this.speakRunId+=1,this.abandonRun(),this.provider.onWordBoundary=void 0,this.provider.stop();let X=++this.speakRunId,G=this.seekSegments.slice(Q);if(this.highlightCoordinator?.clearTTS(),this.activeSentenceStartOffset=null,this.currentBoundaryOffset=this.seekSegments[Q].startOffset,!Y)this.setState(P.LOADING);let j=this.installPlaybackStartBarrier(X,!!J?.[0]?.audio);if(Y)this.resumeState=j?P.LOADING:P.PLAYING;else if(!j)this.setState(P.PLAYING);this.activePlaybackRate=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));try{if(this.configureWordBoundaryHighlighting({highlightMode:this.activeHighlightMode,wordBoundaryOffset:this.activeWordBoundaryOffset}),J)for(let B=0;B<J.length;B++){if(await this.waitWhilePaused(X),X!==this.speakRunId)return;let U=Q+B,q=this.seekSegments[U];if(q)this.currentBoundaryOffset=q.startOffset;await this.speakCatalogChunk(J[B],X)}else await this.speakWithPlan(G,X,{highlightMode:this.activeHighlightMode});if(X!==this.speakRunId)return;this.setState(P.IDLE),this.clearHighlightsAndTracking()}catch(B){if(X!==this.speakRunId)return;throw this.lastError=B instanceof Error?B.message:String(B),this.setState(P.ERROR),this.clearHighlightsAndTracking(),B}finally{this.clearPlaybackStartBarrier(j)}}async setPlaybackRate(Z){if(!this.provider)throw Error("TTSService not initialized. Call initialize() first.");let Q=this.normalizePlaybackRate(Z),J=this.pendingPlaybackRateRequest;if(J?.rate===Q){await J.promise;return}let Y=++this.playbackRateRequestId,X=this.playbackRateWriteQueue.then(async()=>{let B=this.speakRunId;if(Y!==this.playbackRateRequestId)return{didUpdate:!1,playbackRunId:B};let U=this.normalizePlaybackRate(Number(this.ttsConfig.rate??1));if(Q===U)return{didUpdate:!1,playbackRunId:B};return await this.updateSettings({rate:Q}),{didUpdate:!0,playbackRunId:B}});this.playbackRateWriteQueue=X.then(()=>{return},()=>{return});let G=X.then(async(B)=>{if(Y!==this.playbackRateRequestId||B.playbackRunId!==this.speakRunId)return;let U=this.activePlaybackRate!==null&&this.activePlaybackRate!==Q;if(!B.didUpdate&&!U)return;if(this.state!==P.PLAYING&&this.state!==P.LOADING||!this.currentText||this.seekSegments.length===0||this.hasExplicitBreakSemantics(this.currentText))return;await this.restartFromSeekIndex(this.getCurrentSeekSegmentIndex())}),j;j=G.finally(()=>{if(this.pendingPlaybackRateRequest?.promise===j)this.pendingPlaybackRateRequest=null}),this.pendingPlaybackRateRequest={rate:Q,promise:j},await j}async seekBy(Z){if(!this.provider||!this.currentText)return;if(this.state!==P.PLAYING&&this.state!==P.PAUSED)return;if(this.hasExplicitBreakSemantics(this.currentText))return;if(this.seekSegments.length===0)return;let Q=Number.isFinite(Z)?Math.trunc(Z):0;if(Q===0)return;let J=this.getCurrentSeekSegmentIndex(),Y=Math.max(0,Math.min(this.seekSegments.length-1,J+Q));if(Y===J)return;await this.restartFromSeekIndex(Y)}async seekForward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(Q)}async seekBackward(Z=1){let Q=Number.isFinite(Z)?Math.max(1,Math.trunc(Z)):1;await this.seekBy(-Q)}stop(){if(this.speakRunId+=1,this.abandonRun(),this.provider)this.provider.onWordBoundary=void 0,this.provider.stop();if(this.setState(P.IDLE),this.currentText=null,this.highlightCoordinator)this.highlightCoordinator.clearTTS();this.lastRenderedRegionTarget=null,this.currentContentElement=null,this.normalizedToDOM.clear(),this.currentBoundaryOffset=0,this.activeWordBoundaryOffset=0,this.seekSegments=[],this.playbackChunks=[],this.sentenceHighlightSegments=[],this.activeSentenceStartOffset=null,this.activePlaybackRate=null}releaseProvider(){this.stop(),this.provider=null,this.currentProvider=null}dispose(){if(this.disposed)return;this.releaseProvider(),this.disposed=!0,this.speakRunId+=1,this.abandonRun(),this.playbackRateRequestId+=1,this.pendingPlaybackRateRequest=null,this.listeners.clear(),this.readinessGate=null,this.mathSpeechSource=null,this.highlightTargetResolverProvider=null,this.highlightCoordinator=null,this.catalogResolver=null,this.telemetryReporter=null}requestControlHandoff(){if(typeof window>"u")return;let Z={source:"host"};window.dispatchEvent(new CustomEvent(N3,{detail:Z}))}isPlaying(){return this.state===P.PLAYING}isPaused(){return this.state===P.PAUSED}getState(){return this.state}getCurrentText(){return this.currentText}getLastError(){return this.lastError}onStateChange(Z){let Q=(J)=>Z(J);return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}setState(Z){if(this.state===Z)return;let Q=this.state;this.state=Z;for(let J of[...this.listeners])J(Z);if(this.emitTelemetry("pie-tool-playback-state-changed",{toolId:"textToSpeech",previousState:Q,state:Z}),Z===P.PLAYING){let J=Q===P.PAUSED?"pie-tool-playback-resume":"pie-tool-playback-start";this.emitTelemetry(J,{toolId:"textToSpeech",previousState:Q,state:Z});return}if(Z===P.PAUSED){this.emitTelemetry("pie-tool-playback-pause",{toolId:"textToSpeech",previousState:Q,state:Z});return}if(Z===P.ERROR){this.emitTelemetry("pie-tool-playback-error",{toolId:"textToSpeech",previousState:Q,state:Z,message:this.lastError||void 0});return}if(Z===P.IDLE&&(Q===P.PLAYING||Q===P.PAUSED||Q===P.LOADING))this.emitTelemetry("pie-tool-playback-stop",{toolId:"textToSpeech",previousState:Q,state:Z})}}import{createPieLogger as S4,isTtsDebugEnabled as T4}from"@pie-players/pie-players-shared/pie";var C3=S4("browser-tts-provider",T4),b3=5000,T3=2000,y4=["__pieTelemetry","contentLanguage","highlightMode","locale","mathSpeech","segmenter","structuralPauses","textNormalization"],y3=(Z)=>{let Q={};if(Z.rate!==void 0)Q.rate=Z.rate;if(Z.pitch!==void 0)Q.pitch=Z.pitch;if(Z.mathTokenHighlighting!==void 0)Q.mathTokenHighlighting=Z.mathTokenHighlighting;let J=Z.providerOptions;if(J&&typeof J==="object"){let Y={};for(let X of y4)if(J[X]!==void 0)Y[X]=J[X];if(Object.keys(Y).length>0)Q.providerOptions=Y}return Q},S3=(Z)=>{if(!x0(Z))return{text:Z,sourceOffset:(X)=>X};let{spokenText:Q,rawToSpokenOffsetMap:J}=k0(Z),Y=[];for(let[X,G]of J){let j=Y[G];if(j===void 0||X<j)Y[G]=X}return{text:Q,sourceOffset:(X)=>{for(let G=X;G>=0;G--){let j=Y[G];if(j!==void 0)return j}return 0}}},Y8=(Z)=>String(Z||"").trim().toLowerCase(),x4=()=>{let Z=typeof navigator<"u"?navigator.language||navigator.languages?.[0]:"";return Y8(Z||"en-US")},k4=(Z,Q)=>{let J=Y8(Q)||x4(),Y=J.split("-")[0]||"en",X=Y8(Z.lang);return X===J||X.startsWith(`${Y}-`)},f4=(Z,Q,J)=>{if(Q)return Z.find((G)=>G.voiceURI===Q)||Z.find((G)=>G.name===Q)||null;let Y=(G)=>k4(G,J),X=[(G)=>G.localService&&Y(G),(G)=>G.default&&Y(G),(G)=>Y(G),(G)=>G.localService,(G)=>G.default];for(let G of X){let j=Z.find(G);if(j)return j}return Z[0]||null},I4=(Z,Q,J=()=>!0)=>{if(Z.getVoices().length>0)return Promise.resolve(!0);let Y=typeof Z.addEventListener==="function"&&typeof Z.removeEventListener==="function";if(!Y&&!("onvoiceschanged"in Z))return Promise.resolve(!1);return new Promise((X)=>{let G=Y?null:Z.onvoiceschanged,j=!1,B=(D)=>{if(j)return;if(j=!0,clearTimeout($),Y)Z.removeEventListener("voiceschanged",q);else if(Z.onvoiceschanged===K)Z.onvoiceschanged=G;X(D)},U=()=>{if(!J())B(!1);else if(Z.getVoices().length>0)B(!0)},q=()=>U(),K=(D)=>{try{G?.call(Z,D)}finally{U()}},$=setTimeout(()=>B(!1),Q);if(Y)Z.addEventListener("voiceschanged",q);else Z.onvoiceschanged=K;U()})},v4=(Z)=>!Z.default;class X8{providerId="browser";providerName="Browser Speech Synthesis";version="1.0.0";async initialize(Z){if(typeof window>"u")throw Error("BrowserTTSProvider requires browser environment");if(!("speechSynthesis"in window))throw Error("Browser does not support Speech Synthesis API");if(typeof Z.voice==="string"&&Z.voice.trim())await I4(window.speechSynthesis,T3);return new x3(Z)}getCapabilities(){return{supportsPause:!0,supportsResume:!0,supportsWordBoundary:!0,defaultHighlightMode:"sentence",supportsVoiceSelection:!0,supportsRateControl:!0,supportsPitchControl:!0,supportsSSML:!1}}destroy(){}}class x3{utterance=null;config=null;_isPlaying=!1;_isPaused=!1;speakRunId=0;activeRunId=null;releasePauseHold=null;settlePendingChunk=null;settlePendingGap=null;onPlaybackStart=void 0;constructor(Z){this.config=Z}async waitWhilePaused(Z){while(this._isPaused&&Z===this.speakRunId)await new Promise((Q)=>{this.releasePauseHold=Q});return Z===this.speakRunId}releaseHold(){let Z=this.releasePauseHold;this.releasePauseHold=null,Z?.()}resolveBrowserVoice(){let Z=typeof this.config?.voice==="string"?this.config.voice.trim():"",Q=speechSynthesis.getVoices();if(Z&&Q.length===0)throw Error(`Configured browser voice "${Z}" could not be resolved because the browser did not publish its voice inventory within ${T3/1000} seconds.`);let J=f4(Q,Z||void 0,this.getContentLocale());if(Z&&!J)throw Error(`Configured browser voice "${Z}" is unavailable. Select a voice exposed by this browser using its voiceURI or name.`);return J}async speak(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice(),Y=S3(Z),X=this.splitIntoChunks(Y.text);for(let G of X){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(G.text,G.offset,Q,J,Y.sourceOffset))break}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async speakSegments(Z){if(!this.config)throw Error("TTS not initialized");this.stop();let Q=this.speakRunId;this.activeRunId=Q;try{let J=this.resolveBrowserVoice();for(let Y of Z){if(Q!==this.speakRunId)break;let X=S3(Y.text),G=this.splitIntoChunks(X.text);for(let B of G){if(this._isPaused&&!await this.waitWhilePaused(Q))break;if(!await this.speakChunk(B.text,B.offset,Q,J,(q)=>Y.startOffset+X.sourceOffset(q)))break}let j=Math.max(0,Number(Y.pauseMsAfter||0));if(j>0&&Q===this.speakRunId){if(!await this.waitForPause(j,Q))break}}}finally{if(this.activeRunId===Q)this.activeRunId=null}}async waitForPause(Z,Q){return await new Promise((J)=>{let Y=()=>{if(clearTimeout(X),this.settlePendingGap===Y)this.settlePendingGap=null;J()},X=setTimeout(Y,Z);this.settlePendingGap=Y}),Q===this.speakRunId}splitIntoChunks(Z){if(Z.length<=260)return[{text:Z,offset:0}];let J=this.segmentSentences(Z),Y=[],X="",G=0;for(let j of J){let B=j.text.trim();if(!B)continue;let U=j.text.search(/\S/),q=j.offset+(U===-1?0:U);if(!X){X=B,G=q;continue}let K=`${X} ${B}`;if(K.length<=260)X=K;else Y.push({text:X,offset:G}),X=B,G=q}if(X)Y.push({text:X,offset:G});return Y.length?Y:[{text:Z,offset:0}]}getContentLocale(){let Z=this.config?.providerOptions?.contentLanguage;return typeof Z==="string"&&Z.trim()?Z.trim():void 0}getSegmentationPolicy(){let Z=this.config?.providerOptions||{},Q=Z.segmenter||{},Y=Q.mode!=="regexOnly",X=typeof Q.locale==="string"&&Q.locale.trim().length>0?Q.locale:typeof Z.locale==="string"&&Z.locale.trim().length>0?Z.locale:void 0;return{useSentenceSegmenter:Y,useWordSegmenter:Y,locale:X}}segmentSentences(Z){let Q=this.getSegmentationPolicy();return I9(Z,{locale:Q.locale,useSentenceSegmenter:Q.useSentenceSegmenter})}inferWordLength(Z,Q){let J=Math.max(0,Math.min(Q,Math.max(0,Z.length-1)));return Z.slice(J).match(/^\s*([^\s]+)/)?.[1]?.length||1}async speakChunk(Z,Q,J,Y,X){return new Promise((G,j)=>{if(J!==this.speakRunId){G(!1);return}let B=new SpeechSynthesisUtterance(Z);this.utterance=B;let U=this.getContentLocale();if(U)B.lang=U;if(Y&&v4(Y))B.voice=Y;if(this.config?.rate)B.rate=this.config.rate;if(this.config?.pitch)B.pitch=this.config.pitch;let q=!1,K=!1,$=null,D=null,z=()=>{if(this.utterance===B)this.utterance=null},M=()=>{if($!==null)clearTimeout($),$=null},O=()=>{B.onstart=null,B.onend=null,B.onerror=null,B.onpause=null,B.onresume=null,B.onboundary=null},F=(R,b)=>{if(K)return;if(K=!0,M(),O(),z(),D&&this.settlePendingChunk===D)this.settlePendingChunk=null;if(J===this.speakRunId)this._isPlaying=!1;if(b)j(b);else G(R)},w=(R)=>Error(R==="ended"?"Browser speech synthesis ended before audio started. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.":`Browser speech synthesis did not start within ${b3/1000} seconds. The browser speech engine may be unavailable or stuck; try another voice or restart the browser.`);D=()=>F(!1),this.settlePendingChunk=D,B.onstart=()=>{if(J!==this.speakRunId){F(!1);return}if(q=!0,M(),this._isPlaying=!0,this._isPaused)speechSynthesis.pause();try{this.onPlaybackStart?.()}catch(R){console.error("Browser TTS playback-start callback failed",R)}},B.onend=()=>{if(J!==this.speakRunId){F(!1);return}if(!q){F(!1,w("ended"));return}F(!0)},B.onerror=(R)=>{if(J!==this.speakRunId){F(!1);return}if(R.error==="interrupted"||R.error==="canceled"){F(!1);return}F(!1,Error(`Speech synthesis error: ${R.error}`))},B.onpause=()=>{if(J!==this.speakRunId)return;this._isPaused=!0},B.onresume=()=>{if(J!==this.speakRunId)return;this._isPaused=!1},B.onboundary=(R)=>{if(J!==this.speakRunId)return;if(C3.debug(`boundary event: ${R.name}, charIndex ${R.charIndex}, charLength ${R.charLength}`),R.name!=="word"||!this.onWordBoundary)return;let b=Math.max(0,Math.min(R.charIndex,Math.max(0,Z.length-1))),S=Number(R.charLength||0),h=this.inferWordLength(Z,b),C=Number.isFinite(S)&&S>0&&S<=80&&b+S<=Z.length?S:h,U9=Z.substring(b,Math.min(Z.length,b+C)).trim(),K9=Q+b,u=X(K9),Q9=X(K9+C-1)+1-u;C3.debug(`word boundary "${U9}" at ${u}`),this.onWordBoundary(U9,u,Q9)},$=setTimeout(()=>{if(K||q||J!==this.speakRunId)return;F(!1,w("timedOut")),speechSynthesis.cancel()},b3);try{speechSynthesis.speak(B)}catch(R){F(!1,R instanceof Error?R:Error("Browser speech synthesis failed to queue speech"))}})}pause(){if(this._isPaused)return;if(this._isPlaying)speechSynthesis.pause(),this._isPaused=!0;else if(this.activeRunId===this.speakRunId)this._isPaused=!0}resume(){if(!this._isPaused)return;if(this._isPaused=!1,this._isPlaying)speechSynthesis.resume();this.releaseHold()}stop(){let Z=this.utterance,Q=this._isPlaying||Z!==null;if(this.speakRunId+=1,this.activeRunId=null,this.settlePendingChunk?.(),this.settlePendingGap?.(),Q)speechSynthesis.cancel();this.utterance=null,this._isPlaying=!1,this._isPaused=!1,this.releaseHold()}isPlaying(){return this._isPlaying&&!this._isPaused}isPaused(){return this._isPaused}updateSettings(Z){if(!this.config)this.config={};if(Z.rate!==void 0)this.config.rate=Z.rate;if(Z.pitch!==void 0)this.config.pitch=Z.pitch;if(Z.voice!==void 0)this.config.voice=Z.voice;if(Z.providerOptions!==void 0)this.config.providerOptions={...this.config.providerOptions||{},...Z.providerOptions||{}}}onWordBoundary}var h4=new Set(["reserved-row","expanding-row","floating-overlay","left-aligned"]),k3=(Z)=>Z&&typeof Z==="object"?Z:{},Z9=(Z,Q)=>Z===void 0?Q:Z,m4=(Z,Q="left-aligned")=>typeof Z==="string"&&h4.has(Z)?Z:Q,gJ=Object.freeze([{rate:0.8,label:"Slow",ariaLabel:"Slow speed"},{rate:1,label:"Normal",ariaLabel:"Normal speed",default:!0},{rate:1.25,label:"Fast",ariaLabel:"Fast speed"}]);var cJ=Object.freeze([0.8,1,1.25]);var u4=(Z)=>{let Q={...Z,layoutMode:m4(Z.layoutMode)};if(Z.backend!=="server")return Q;let J={...Q,apiEndpoint:Z9(Q.apiEndpoint,"/api/tts"),transportMode:Z9(Q.transportMode,"pie"),endpointValidationMode:Z9(Q.endpointValidationMode,"voices"),validateEndpoint:Z9(Q.validateEndpoint,!0),includeAuthOnAssetFetch:Z9(Q.includeAuthOnAssetFetch,!1),rate:Z9(Q.rate,1),language:Z9(Q.language,"en-US")};if(Z.serverProvider==="polly")return{...J,engine:Z9(J.engine,"neural"),format:Z9(J.format,"mp3"),speechMarksMode:Z9(J.speechMarksMode,"word+sentence")};return J},G8=(Z)=>{let{enabled:Q,provider:J,...Y}=k3(Z);return u4(Y)},j8=(Z)=>Z.backend||"browser",B8=(Z)=>{let Q=j8(Z)==="server"?Z.serverProvider:void 0,J=Q==="polly",Y=Z.transportMode||(Q==="custom"?"custom":"pie"),X=W9(Z.mathSpeech);return{voice:Z.defaultVoice,rate:Z.rate,pitch:Z.pitch,providerOptions:{...k3(Z.providerOptions),...Z.language?{locale:Z.language}:{},...J&&Z.engine?{engine:Z.engine}:{},...J&&typeof Z.sampleRate==="number"?{sampleRate:Z.sampleRate}:{},...J&&Z.format?{format:Z.format}:{},...J?{speechMarkTypes:Z.speechMarksMode==="word+sentence"?["word","sentence"]:["word"]}:{},...Y==="custom"&&typeof Z.cache==="boolean"?{cache:Z.cache}:{},...Y==="custom"&&Z.speedRate?{speedRate:Z.speedRate}:{},...Y==="custom"&&Z.lang_id?{lang_id:Z.lang_id}:{},...X?{mathSpeech:X}:{}},apiEndpoint:Z.apiEndpoint,provider:Q,language:Z.language,transportMode:Y,endpointMode:Z.endpointMode,endpointValidationMode:Z.endpointValidationMode,includeAuthOnAssetFetch:Z.includeAuthOnAssetFetch,assetOrigins:Z.assetOrigins,credentials:Z.credentials,headers:Z.headers,validateEndpoint:Z.validateEndpoint,...typeof Z.mathTokenHighlighting==="boolean"?{mathTokenHighlighting:Z.mathTokenHighlighting}:{}}};import{createPieLogger as p4,isGlobalDebugEnabled as g4}from"@pie-players/pie-players-shared/pie";var a9=p4("ToolProviderRegistry",g4);class u0{providers=new Map;configs=new Map;initialized=new Map;initializationPromises=new Map;async emitTelemetry(Z,Q,J){try{await Z.onTelemetry?.(Q,J)}catch(Y){console.warn("[ToolProviderRegistry] Telemetry callback failed:",Y)}}register(Z,Q){let J=this.providers.get(Z),Y=this.initializationPromises.get(Z);if(this.providers.set(Z,Q.provider),this.configs.set(Z,Q),this.initialized.set(Z,!1),this.initializationPromises.delete(Z),J)if(Y)Y.catch(()=>{}).then(()=>this.destroyProvider(Z,J));else this.destroyProvider(Z,J);if(a9.debug(`${J?"Replaced":"Registered"} provider "${Z}" (${Q.provider.providerName})`),Q.lazy===!1)this.initialize(Z).catch((X)=>{console.error(`[ToolProviderRegistry] Failed to initialize provider "${Z}":`,X)})}async initialize(Z){if(this.initialized.get(Z))return;let Q=this.initializationPromises.get(Z);if(Q)return Q;let J=this.providers.get(Z),Y=this._doInitialize(Z);this.initializationPromises.set(Z,Y);try{await Y}catch(X){if(!this.isReplaced(Z,J))throw X}finally{if(this.initializationPromises.get(Z)===Y)this.initializationPromises.delete(Z)}if(this.isReplaced(Z,J))return this.initialize(Z)}isReplaced(Z,Q){let J=this.providers.get(Z);return J!==void 0&&J!==Q}destroyProvider(Z,Q){try{Q.destroy()}catch(J){console.warn(`[ToolProviderRegistry] Failed to destroy provider "${Z}":`,J)}}async _doInitialize(Z){let Q=this.providers.get(Z),J=this.configs.get(Z);if(!Q||!J)throw Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);let Y={...J.config},X=(j)=>{let B=j&&typeof j==="object"?j.backend:void 0;return typeof B==="string"&&B?B:"unknown"},G=Date.now();if(await this.emitTelemetry(J,"pie-tool-init-start",{toolId:Z,backend:X(Y),operation:"provider-initialize"}),Q.requiresAuth&&J.authFetcher){let j=Date.now();await this.emitTelemetry(J,"pie-tool-backend-call-start",{toolId:Z,backend:X(Y),operation:"auth-fetch"}),a9.debug(`Fetching auth for "${Z}"...`);try{let B=await J.authFetcher();Y={...Y,...B},await this.emitTelemetry(J,"pie-tool-backend-call-success",{toolId:Z,backend:X(Y),operation:"auth-fetch",duration:Date.now()-j})}catch(B){throw await this.emitTelemetry(J,"pie-tool-backend-call-error",{toolId:Z,backend:X(Y),operation:"auth-fetch",duration:Date.now()-j,errorType:"ProviderAuthFetchError",message:B instanceof Error?B.message:String(B)}),console.error(`[ToolProviderRegistry] Auth fetch failed for "${Z}":`,B),Error(`Failed to fetch auth credentials for provider "${Z}"`)}}try{if(await Q.initialize(Y),this.providers.get(Z)===Q)this.initialized.set(Z,!0);await this.emitTelemetry(J,"pie-tool-init-success",{toolId:Z,backend:X(Y),operation:"provider-initialize",duration:Date.now()-G}),a9.debug(`Provider "${Z}" initialized`)}catch(j){throw await this.emitTelemetry(J,"pie-tool-init-error",{toolId:Z,backend:X(Y),operation:"provider-initialize",duration:Date.now()-G,errorType:"ProviderInitializationError",message:j instanceof Error?j.message:String(j)}),console.error(`[ToolProviderRegistry] Initialization failed for "${Z}":`,j),j}}async getProvider(Z,Q=!0){let J=this.providers.get(Z);if(!J)throw console.error("[ToolProviderRegistry] Provider not found:",{requestedId:Z,availableProviders:Array.from(this.providers.keys())}),Error(`[ToolProviderRegistry] Provider "${Z}" not registered`);if(Q&&!this.initialized.get(Z))a9.debug("Auto-initializing provider:",Z),await this.initialize(Z);return J}getProvidersByCategory(Z){return Array.from(this.providers.entries()).filter(([Q,J])=>J.category===Z).map(([Q])=>Q)}getProviderIds(){return Array.from(this.providers.keys())}has(Z){return this.providers.has(Z)}isInitialized(Z){return this.initialized.get(Z)===!0}isInitializing(Z){return this.initializationPromises.has(Z)}async unregister(Z){let Q=this.providers.get(Z);if(Q){let J=this.initializationPromises.get(Z);if(J){try{await J}catch{}if(this.providers.get(Z)!==Q)return}this.destroyProvider(Z,Q),this.providers.delete(Z),this.configs.delete(Z),this.initialized.delete(Z),this.initializationPromises.delete(Z),a9.debug(`Unregistered provider "${Z}"`)}}async destroy(){let Z=Array.from(this.providers.keys());await Promise.all(Z.map((Q)=>this.unregister(Q))),a9.debug("Registry destroyed")}}class W8{targets=new Set;changeListeners=new Set;registerTarget(Z){return this.targets.add(Z),this.notifyTargetsChange(),()=>{if(!this.targets.delete(Z))return;this.notifyTargetsChange()}}canRequest(Z,Q,J){return this.findTarget(Z,Q,J)!==null}request(Z){let Q=this.findTarget(Z.toolId,Z.level,Z.scopeId);if(!Q)return!1;try{Q.open(Z.toolId,Z.params)}catch(J){return console.error(`[ToolRequestRegistry] Target failed to open "${Z.toolId}":`,J),!1}return!0}onTargetsChange(Z){return this.changeListeners.add(Z),()=>{this.changeListeners.delete(Z)}}findTarget(Z,Q,J){let Y=this.findTargetAtLevel(Z,Q??"section",J);if(Y||Q!==void 0)return Y;for(let X of this.targets){if(X.level==="section")continue;if(J!==void 0&&X.scopeId!==J)continue;if(this.hostsTool(X,Z))return X}return null}findTargetAtLevel(Z,Q,J){for(let Y of this.targets){if(Y.level!==Q)continue;if(J!==void 0&&Y.scopeId!==J)continue;if(this.hostsTool(Y,Z))return Y}return null}hostsTool(Z,Q){try{return Z.hostsTool(Q)===!0}catch(J){return console.warn(`[ToolRequestRegistry] Target at level "${Z.level}" failed the host check for "${Q}":`,J),!1}}notifyTargetsChange(){for(let Z of this.changeListeners)try{Z()}catch(Q){console.warn("[ToolRequestRegistry] Target change listener threw:",Q)}}dispose(){this.targets.clear(),this.changeListeners.clear()}}class U8{provenance;stepCounter=0;constructor(Z){this.provenance={contextId:Z,resolvedAt:new Date,sources:{},features:new Map,decisionLog:[],summary:{totalFeatures:0,enabled:0,blocked:0,notConfigured:0,bySource:{},byRule:{}}}}addSource(Z,Q){let J={id:Q.id,name:Q.name??Q.id};switch(Z){case"organization":this.provenance.sources.organization={...J,pnpDefaults:Q.config};break;case"assessment":this.provenance.sources.assessment={...J,settings:Q.config};break;case"section":this.provenance.sources.section={...J,settings:Q.config};break;case"item":this.provenance.sources.item={...J,settings:Q.config};break;case"student":this.provenance.sources.student={id:Q.id,pnpProfile:Q.config};break;case"host":this.provenance.sources.host={id:Q.id,config:Q.config};break}return this}addDecision(Z){let Q={step:++this.stepCounter,precedence:Z.precedence,rule:Z.rule,featureId:Z.featureId,action:Z.action,source:{type:Z.sourceType,id:Z.sourceId,name:Z.sourceName},reason:Z.reason,value:Z.value,timestamp:new Date};this.provenance.decisionLog.push(Q);let J=this.provenance.features.get(Z.featureId);if(!J)J={featureId:Z.featureId,finalState:"not-configured",allDecisions:[],explanation:""},this.provenance.features.set(Z.featureId,J);if(J.allDecisions.push(Q),Z.action==="advisory"){if(J.finalState==="not-configured")J.finalState="advisory-only"}else if(Z.action!=="skip"){if(!J.winningDecision||Q.precedence<J.winningDecision.precedence)J.winningDecision=Q,J.finalState=Q.action==="enable"?"enabled":"blocked"}return this.provenance.summary.bySource[Z.sourceType]=(this.provenance.summary.bySource[Z.sourceType]||0)+1,this.provenance.summary.byRule[Z.rule]=(this.provenance.summary.byRule[Z.rule]||0)+1,this}reconcileFinalStates(Z){for(let Q of Z){let J=this.provenance.features.get(Q);if(!J){J={featureId:Q,finalState:"enabled",allDecisions:[],explanation:""},this.provenance.features.set(Q,J);continue}J.finalState="enabled"}for(let Q of this.provenance.features.values()){if(Z.has(Q.featureId))continue;let J=Q.allDecisions.some((X)=>X.action!=="skip"&&X.action!=="advisory"),Y=Q.allDecisions.some((X)=>X.action==="advisory");if(J)Q.finalState="blocked";else if(Y)Q.finalState="advisory-only";else Q.finalState="not-configured"}return this}build(){for(let Z of this.provenance.features.values())Z.explanation=c4(Z);for(let Z of this.provenance.features.values())if(this.provenance.summary.totalFeatures++,Z.finalState==="enabled")this.provenance.summary.enabled++;else if(Z.finalState==="blocked")this.provenance.summary.blocked++;else this.provenance.summary.notConfigured++;return this.provenance}}function c4(Z){if(!Z.winningDecision){if(Z.finalState==="advisory-only"){let G=Z.allDecisions.find((j)=>j.action==="advisory");return G?`Feature "${Z.featureId}" was kept in its host-decided state; ${G.reason}`:`Feature "${Z.featureId}" carries an advisory note.`}return`Feature "${Z.featureId}" was not configured at any level.`}let Q=Z.winningDecision,J=Q.source.name||Q.source.type,Y=`Feature "${Z.featureId}" is ${Z.finalState}.
|
|
216
216
|
|
|
217
|
-
`;
|
|
218
|
-
`,
|
|
219
|
-
`,
|
|
220
|
-
`;let X=
|
|
217
|
+
`;Y+=`**Primary Reason** (${Q.rule}):
|
|
218
|
+
`,Y+=`${Q.reason}
|
|
219
|
+
`,Y+=`Source: ${J} (${Q.source.type})
|
|
220
|
+
`;let X=Z.allDecisions.filter((G)=>G.step!==Q.step&&G.action!=="skip"&&G.action!=="advisory"&&G.precedence>Q.precedence);if(X.length>0){Y+=`
|
|
221
221
|
**Overridden Rules**:
|
|
222
|
-
`;for(let
|
|
223
|
-
`}return G}function k8(Q){let{request:Y,tools:J,pnpPolicy:G,customSources:X,contextId:j}=Q,Z=new E9(j);Z.addSource("host",{id:Y.scope.scopeId,name:`${Y.level}:${Y.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=L7(J.placement[Y.level]),W=L7(J.policy.allowed),K=new Set(L7(J.policy.blocked)),U=[];for(let F of B)U.push(F),Z.addDecision({precedence:0,rule:"placement-membership",featureId:F,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Y.level}`});if(U=U.filter((F)=>{if(J.providers?.[F]?.enabled===!1)return Z.addDecision({precedence:0,rule:"provider-disabled",featureId:F,action:"block",sourceType:"host",reason:`tools.providers.${F}.enabled === false`,value:!1}),!1;return!0}),W.length>0){let F=new Set(W);U=U.filter((L)=>{if(!F.has(L))return Z.addDecision({precedence:0,rule:"host-allowlist",featureId:L,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:W}),!1;return!0})}U=U.filter((F)=>{if(K.has(F))return Z.addDecision({precedence:0,rule:"host-blocked",featureId:F,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let _=[],$=new Map;for(let F of U)$.set(F,["placement"]);let N=new Set(U),D=null;if(G.enforcement==="on"&&G.source&&(G.assessment||G.currentItemRef)){if(D=G.source.apply({assessment:G.assessment,currentItemRef:G.currentItemRef}),D.sources.assessment)Z.addSource("assessment",D.sources.assessment);if(D.sources.student)Z.addSource("student",D.sources.student);if(D.sources.item)Z.addSource("item",D.sources.item);for(let F of D.decisions)Z.addDecision({precedence:F.precedence,rule:F.rule,featureId:F.featureId,action:F.action,sourceType:F.sourceType,reason:F.reason,value:F.value});for(let F of D.unmappedSupportIds)_.push({code:"tool-policy.unknownSupportId",level:Y.level,toolId:F,message:`No registered tool claims PNP support id "${F}"; it was carried through as a feature id and matched nothing. Expected an AfA 3.0 / QTI 3.0 access feature id.`,source:"pnp.pnp-support"});U=U.filter((F)=>{return!D.blockedToolIds.has(F)});for(let F of Array.from($.keys()))if(D.blockedToolIds.has(F))$.delete(F);for(let F of D.mandatedToolIds){if(!!N.has(F))continue;let v=D.perToolFlags.get(F)?.rule??"required-tool",k=N2(F,{placement:B,allowed:W,blocked:K,providers:J.providers}),p={rule:v,hostRule:k.hostRule,hostValue:k.hostValue};_.push({code:"tool-policy.requiredToolBlocked",level:Y.level,toolId:F,message:`Profile policy mandates "${F}" (${v}) but host policy removed it from level "${Y.level}" via ${k.hostRule}.`,details:p}),Z.addDecision({precedence:0,rule:"required-tool-blocked",featureId:F,action:"advisory",sourceType:"host",reason:`Host removed required tool "${F}" via ${k.hostRule}`,value:p})}for(let F of U){let L=D.perToolFlags.get(F);if(L){let C=$.get(F)??[];C.push(`pnp.${L.rule}`),$.set(F,C)}}}for(let F=0;F<X.length;F++){let L=X[F],C=U.slice(),v=L.refine({request:Y,candidates:C}),k=new Set(v.refinedCandidates);for(let R of v.refinedCandidates)if(!C.includes(R))_.push({code:"tool-policy.placementMissing",level:Y.level,toolId:R,message:`Custom source "${L.id}" tried to add tool "${R}" that was not in candidates; ignored.`,source:`custom.${L.id}`}),k.delete(R);U=C.filter((R)=>k.has(R));let p=new Set;if(v.decisions){for(let R of v.decisions)if(Z.addDecision({precedence:R.precedence??100+F,rule:R.rule,featureId:R.featureId,action:R.action,sourceType:R.sourceType,reason:R.reason,value:R.value}),R.action==="block")p.add(R.featureId)}for(let R of C){if(k.has(R))continue;if(p.has(R))continue;Z.addDecision({precedence:100+F,rule:"custom-source",featureId:R,action:"block",sourceType:"custom",reason:`Custom policy source "${L.id}" removed tool "${R}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:L.id}})}for(let R of U){let g=$.get(R)??["placement"];g.push(`custom.${L.id}`),$.set(R,g)}for(let R of C)if(!k.has(R))$.delete(R)}let O=new Set(U),P=U.map((F)=>{let L=D?.perToolFlags.get(F);return{toolId:F,required:L?.required??!1,alwaysAvailable:L?.alwaysAvailable??!1,settings:L?.settings,sources:$.get(F)??["placement"]}});return Z.reconcileFinalStates(O),{visibleTools:P,diagnostics:_,provenance:Z.build()}}function N2(Q,Y){if(!Y.placement.includes(Q))return{hostRule:"placement-missing",hostValue:Y.placement};if(Y.providers?.[Q]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Y.allowed.length>0&&!Y.allowed.includes(Q))return{hostRule:"host-allowlist",hostValue:Y.allowed};if(Y.blocked.has(Q))return{hostRule:"host-blocked",hostValue:Array.from(Y.blocked)};return{hostRule:"placement-missing",hostValue:Y.placement}}function I8(Q){if(!Q)return!1;let Y=Q.personalNeedsProfile;if(Y){if(Array.isArray(Y.supports)&&Y.supports.length>0)return!0;if(Array.isArray(Y.prohibitedSupports)&&Y.prohibitedSupports.length>0)return!0;if(Array.isArray(Y.activateAtInit)&&Y.activateAtInit.length>0)return!0}let J=Q.settings;if(J){let G=J.districtPolicy;if(G){if(Array.isArray(G.blockedTools)&&G.blockedTools.length>0)return!0;if(Array.isArray(G.requiredTools)&&G.requiredTools.length>0)return!0;if(G.policies&&typeof G.policies==="object"&&Object.keys(G.policies).length>0)return!0}let X=J.testAdministration;if(X&&typeof X==="object")for(let j of Object.keys(X)){let Z=X[j];if(Z===void 0||Z===null)continue;if(Array.isArray(Z)&&Z.length===0)continue;if(typeof Z==="object"&&!Array.isArray(Z)&&Object.keys(Z).length===0)continue;return!0}}return!1}function v8(Q){let Y=Q?.settings;if(!Y)return!1;if(Array.isArray(Y.requiredTools)&&Y.requiredTools.length>0)return!0;if(Array.isArray(Y.restrictedTools)&&Y.restrictedTools.length>0)return!0;if(Y.toolParameters&&typeof Y.toolParameters==="object"&&Object.keys(Y.toolParameters).length>0)return!0;return!1}function d7(Q){if(I8(Q.assessment))return"on";if(v8(Q.currentItemRef))return"on";return"off"}class D1{id="pnp";toolRegistry;constructor(Q){this.toolRegistry=Q}apply(Q){let{ctx:Y,result:J}=this.prepare(Q),{pnp:G,districtPolicy:X,itemSettings:j}=Y,Z=new Set;G?.supports?.forEach((B)=>Z.add(B)),G?.prohibitedSupports?.forEach((B)=>Z.add(B)),X?.blockedTools?.forEach((B)=>Z.add(B)),X?.requiredTools?.forEach((B)=>Z.add(B)),j?.requiredTools?.forEach((B)=>Z.add(B)),j?.restrictedTools?.forEach((B)=>Z.add(B));for(let B of Z)this.resolveSupport(B,Y,J);return J}resolveFeature(Q,Y){let{ctx:J,result:G}=this.prepare(Y);return this.resolveSupport(Q,J,G),G}prepare(Q){let{assessment:Y,currentItemRef:J}=Q,G=Y?.personalNeedsProfile,X=Y?.settings,j=J?.settings,Z={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:new Set,sources:{}};if(X?.districtPolicy||X?.testAdministration)Z.sources.assessment={id:Y?.id||"unknown",name:Y?.name||Y?.id||"Assessment",config:X};if(G)Z.sources.student={id:"student",name:"Student PNP Profile",config:G};if(J&&j)Z.sources.item={id:J.identifier,name:J.identifier,config:j};return{ctx:{pnp:G,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:j,toolConfigs:X?.toolConfigs},result:Z}}resolveSupport(Q,Y,J){if(Y.districtPolicy?.blockedTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:1,rule:"district-block",featureId:X,action:"block",sourceType:"assessment",reason:`District policy blocks "${Q}" for all assessments`,value:Y.districtPolicy.blockedTools});return}if(Y.testAdmin?.toolOverrides?.[Q]===!1){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:2,rule:"test-admin-override",featureId:X,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Q}" for this session`,value:Y.testAdmin.toolOverrides});return}if(Y.itemSettings?.restrictedTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:3,rule:"item-restriction",featureId:X,action:"block",sourceType:"item",reason:`Item restricts "${Q}" (e.g., mental math question blocks calculator)`,value:Y.itemSettings.restrictedTools});return}if(Y.itemSettings?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.mandatedToolIds.add(X),J.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,Y),rule:"item-requirement",sourceType:"item"}),J.decisions.push({precedence:4,rule:"item-requirement",featureId:X,action:"enable",sourceType:"item",reason:`Item requires "${Q}" for this question`,value:Y.itemSettings.requiredTools});return}if(Y.districtPolicy?.requiredTools?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.mandatedToolIds.add(X),J.perToolFlags.set(X,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Q,Y),rule:"district-requirement",sourceType:"assessment"}),J.decisions.push({precedence:5,rule:"district-requirement",featureId:X,action:"enable",sourceType:"assessment",reason:`District policy requires "${Q}" for all assessments`,value:Y.districtPolicy.requiredTools});return}if(Y.pnp?.prohibitedSupports?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.blockedToolIds.add(X),J.decisions.push({precedence:6,rule:"pnp-prohibited",featureId:X,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Q}"`,value:Y.pnp.prohibitedSupports});return}if(Y.pnp?.supports?.includes(Q)){let X=this.mapSupportToToolId(Q,J);J.perToolFlags.set(X,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Q,Y),rule:"pnp-support",sourceType:"student"}),J.decisions.push({precedence:6,rule:"pnp-support",featureId:X,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Q}"`,value:Y.pnp.supports});return}let G=this.mapSupportToToolId(Q,J);J.decisions.push({precedence:6,rule:"pnp-support",featureId:G,action:"skip",sourceType:"system",reason:`Feature "${Q}" not configured at any level`,value:{supportId:Q}})}mapSupportToToolId(Q,Y){let J=this.toolRegistry.getToolsByPNPSupport(Q);if(J.size===0){if(this.toolRegistry.getAllTools().length>0)Y.unmappedSupportIds.add(Q);return Q}return Array.from(J)[0]}resolveToolSettings(Q,Y){return Y.itemSettings?.toolParameters?.[Q]??Y.toolConfigs?.[Q]}}var h8=b7({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class N1{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;currentItemRef;pnpEnforcement;disposed=!1;constructor(Q){this.toolRegistry=Q.toolRegistry,this.contextId=Q.contextId??"tool-policy",this.pnpPolicySource=new D1(this.toolRegistry),this.customSources=Q.customSources?[...Q.customSources]:[];let Y=Q.inputs??{};this.tools=Y.tools??h8,this.assessment=Y.assessment??null,this.currentItemRef=Y.currentItemRef??null,this.pnpEnforcement=Y.pnpEnforcement??d7({assessment:this.assessment,currentItemRef:this.currentItemRef})}decide(Q){this.assertNotDisposed();let Y=Q.scope.scopeId?`${this.contextId}:${Q.level}:${Q.scope.scopeId}`:`${this.contextId}:${Q.level}`;return k8({request:Q,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0,enforcement:this.pnpEnforcement},customSources:this.customSources,contextId:Y})}decideFeature(Q){this.assertNotDisposed();let Y=this.hostFeatureGate(Q);if(Y)return Y;return x8(Q,this.pnpPolicySource.resolveFeature(Q,{assessment:this.assessment??void 0,currentItemRef:this.currentItemRef??void 0}),{assessmentBound:this.assessment!==null})}hostFeatureGate(Q){let Y={assessmentBound:this.assessment!==null},J=L7(this.tools.policy.blocked);if(J.includes(Q))return R9(Q,"host-blocked",J,Y);let G=L7(this.tools.policy.allowed);if(G.length>0&&!G.includes(Q))return R9(Q,"host-allowlist",G,Y);return null}getVisibleToolIds(Q,Y){return this.decide({level:Q,scope:{level:Q,scopeId:Y}}).visibleTools.map((J)=>J.toolId)}updateInputs(Q){this.assertNotDisposed();let Y=!1,J=!1;if("tools"in Q){let G=Q.tools??h8;if(!Object.is(this.tools,G))this.tools=G,Y=!0}if("assessment"in Q){let G=Q.assessment??null;if(!Object.is(this.assessment,G))this.assessment=G,Y=!0}if("currentItemRef"in Q){let G=Q.currentItemRef??null;if(!Object.is(this.currentItemRef,G))this.currentItemRef=G,Y=!0}if("pnpEnforcement"in Q&&Q.pnpEnforcement){if(this.pnpEnforcement!==Q.pnpEnforcement)this.pnpEnforcement=Q.pnpEnforcement,J=!0}if(Y||J)this.emit({reason:J&&!Y?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}replaceToolRegistry(Q,Y){this.assertNotDisposed(),this.toolRegistry=Q,this.pnpPolicySource=new D1(Q),this.tools=Y,this.emit({reason:"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Q){return this.assertNotDisposed(),this.customSources.push(Q),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Y=this.customSources.indexOf(Q);if(Y!==-1){if(this.customSources.splice(Y,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(Q){return this.listeners.add(Q),()=>{this.listeners.delete(Q)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,currentItemRef:this.currentItemRef,pnpEnforcement:this.pnpEnforcement})}emit(Q){for(let Y of Array.from(this.listeners))try{Y(Q)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}class s extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class C9 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var M1=(Q)=>!!Q&&typeof Q==="object"&&!Array.isArray(Q),M2=(Q,Y,J)=>{let G={...Y,...J};if(Q==="textToSpeech"&&M1(Y.settings)&&M1(J.settings)){if(G.settings={...Y.settings,...J.settings},M1(Y.settings.mathSpeech)&&M1(J.settings.mathSpeech))G.settings.mathSpeech={...Y.settings.mathSpeech,...J.settings.mathSpeech}}return G},z2=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],O2=["section-navigation-change","section-session-applied","section-loading-complete","section-items-complete-changed","section-error","timed-media-cue-changed","timed-media-policy-degraded","timed-media-invalid"];class T9{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new w9;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;boundAssessment=null;boundCurrentItemRef=null;reportedUnboundFeaturePolicy=!1;reportedMissingTTSProvider=!1;heldMissingTTSProviderBackend=null;reportedRegistryUnavailable=!1;resolveConfig(Q){let Y=c1(Q.toolConfigStrictness),J=Q.toolRegistry??new S9,G=Q.deferToolConfigValidation===!0?b7(Q.tools):this.validateToolsConfig(Q.tools,{strictness:Y,source:"ToolkitCoordinator.init",toolRegistry:J});return{...Q,toolConfigStrictness:Y,toolRegistry:J,tools:{...G,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...G.providers}},accessibility:{language:"en-US",...Q.accessibility??{},catalogs:Q.accessibility?.catalogs??[]}}}validateToolsConfig(Q,Y){let{config:J,diagnostics:G}=d1(Q,Y.toolRegistry),X=this.reportedRegistryUnavailable||!this.toolRegistrySettled?G.filter((j)=>j.code!=="tools.registryUnavailable"):G;if(l1(X,Y),Y.strictness!=="off"&&X.some((j)=>j.code==="tools.registryUnavailable"))this.reportedRegistryUnavailable=!0;return J}constructor(Q){if(!Q.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");this.toolRegistrySupplied=Q.toolRegistry!=null,this.toolRegistrySettled=this.toolRegistrySupplied;let Y=this.resolveConfig(Q);if(this.assessmentId=Y.assessmentId,this.config=Y,this.toolRegistry=Y.toolRegistry??new S9,this.installToolContextResolvers(Y.toolContextResolvers),this.hooks=Y.hooks??{},this.lazyInit=Q.lazyInit===!0,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=Q.frameworkErrorBus??new u7,this.ownsFrameworkErrorBus=!Q.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new G9,this.highlightCoordinator=new p7,this.elementToolStateStore=new Y9,this.catalogResolver=new Q9(Y.accessibility?.catalogs||[],Y.accessibility?.language||"en-US"),this.toolProviderRegistry=new H1,this._registerToolProviders(),this.ttsService=new c7,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.setupStatePersistenceHooks(),this.policyEngine=new N1({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,currentItemRef:null,pnpEnforcement:this.resolveEffectivePnpEnforcement()}}),!this.lazyInit)this.waitUntilReady().catch((J)=>{if(J instanceof s)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready"})})}assertNotDisposed(){if(this.disposePromise!==null)throw new s}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((Q)=>{let Y=this.hooks.onFrameworkError;if(!Y)return;try{Y(Q)}catch(J){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",J)}})}async emitTelemetry(Q,Y){try{await this.hooks.onTelemetry?.(Q,Y)}catch(G){console.warn("[ToolkitCoordinator] telemetry hook failed:",G)}let J=Y?{...Y}:void 0;for(let G of this.telemetryListeners)try{G({eventName:Q,payload:J?{...J}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Q){for(let Y of this.sectionControllerLifecycleListeners)try{Y(Q)}catch(J){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",J)}}handleError(Q,Y){let J=W0({error:Q,context:Y});this.frameworkErrorBus.reportFrameworkError(J)}subscribeFrameworkErrors(Q){return this.frameworkErrorBus.subscribeFrameworkErrors(Q)}reportFrameworkError(Q){this.frameworkErrorBus.reportFrameworkError(Q)}getSectionControllerMapKey(Q){return`${Q.assessmentId}::${Q.sectionId}::${Q.attemptId||""}`}createDefaultSectionPersistence(){let Q=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Y=(J)=>{let{assessmentId:G,sectionId:X,attemptId:j}=J.key;return`pie:section-controller:v1:${G}:${X}:${j||"default"}`};return{async loadSession(J){if(!Q)return null;let G=Q.getItem(Y(J));if(!G)return null;try{return JSON.parse(G)}catch{return null}},async saveSession(J,G){if(!Q)return;Q.setItem(Y(J),JSON.stringify(G))},async clearSession(J){if(!Q)return;Q.removeItem(Y(J))}}}async resolveSectionPersistence(Q){let Y=this.getSectionControllerMapKey(Q.key),J=this.sectionPersistenceStrategies.get(Y);if(J)return J;let G={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Q,G)??await G.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Y,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Q)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Q)).catch((Y)=>{this.handleError(Y,{phase:"state-save"})})})}async ensureStateLoaded(){if(this.stateLoaded)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let Q=this.hooks.loadToolState;if(!Q)return;try{let Y=await Q();if(this.assertNotDisposed(),Y&&typeof Y==="object")this.elementToolStateStore.loadState(Y);this.stateLoaded=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Y)})}catch(Y){if(Y instanceof s)throw Y;this.handleError(Y,{phase:"state-load"})}})().finally(()=>{this.stateLoadPromise=void 0}),this.stateLoadPromise}reportMissingTTSProvider(Q){if(!this.toolRegistrySettled){this.heldMissingTTSProviderBackend=Q;return}if(this.reportedMissingTTSProvider)return;this.reportedMissingTTSProvider=!0,console.warn(`[ToolkitCoordinator] Text-to-speech is configured for the "${Q}" backend but falls back to browser speech: no "tts" tool provider is registered. A coordinator registers tool providers only from its \`toolRegistry\`, or from its toolkit's when constructed without one, so supply one that carries the text-to-speech registration — for the packaged capability set, \`createPackagedToolRegistry()\` from "@pie-players/pie-default-tool-loaders". Reported once per coordinator.`)}adoptToolRegistry(Q){if(this.disposePromise!==null||this.toolRegistrySettled)return!1;this.toolRegistrySettled=!0;let Y=this.heldMissingTTSProviderBackend;this.heldMissingTTSProviderBackend=null;let J=this.config.toolConfigStrictness??"error",G="ToolkitCoordinator.adoptToolRegistry";if(!Q){if(this.validateToolsConfig(this.config.tools,{strictness:J,source:G,toolRegistry:this.toolRegistry}),Y)this.reportMissingTTSProvider(Y);return!1}this.toolRegistry=Q,this.config.toolRegistry=Q;try{this.config.tools=this.validateToolsConfig(this.config.tools,{strictness:J==="off"?"off":"warn",source:G,toolRegistry:Q})}catch(j){console.warn("[ToolkitCoordinator] Tool config does not validate against the adopted tool registry:",j)}this.policyEngine.replaceToolRegistry(Q,this.config.tools);let X=this.ttsInitialized||this.ttsInitPromise!==void 0||this.ttsReconfigurePromise!==void 0;for(let j of this.getProviderDescriptorTools()){if(X&&j.toolId==="textToSpeech")continue;this.registerProviderFromTool(j)}if(X)this.scheduleTTSReconfigure();return!0}_registerToolProviders(){let Q=this.getProviderDescriptorTools();for(let Y of Q)this.registerProviderFromTool(Y)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Q)=>!!Q.provider)}async registerProviderFromTool(Q){let Y=Q.provider;if(!Y)return;let J=null,G;try{let X=this.getToolConfig(Q.toolId)||void 0;if(X?.enabled===!1)return;if(J=b9(Q,X),!J||this.toolProviderRegistry.has(J))return;let j=Y.createProvider(X),Z=Y.getInitConfig?.(X)??X?.provider?.init??{},B=this.addToolTelemetryReporter({toolId:Q.toolId,providerId:J,initConfig:Z}),W=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:J}),K=Y.getAuthFetcher?.(X)??X?.provider?.runtime?.authFetcher;G={provider:j,config:B,lazy:Y.lazy??!0,authFetcher:K,onTelemetry:W}}catch(X){this.reportProviderRegisterFailure(X,J,Q.toolId);return}await this.registerProvider(J,G)}createToolTelemetryForwarder(Q){return async(Y,J)=>{await this.emitTelemetry(Y,{...J||{},toolId:Q.toolId,providerId:Q.providerId})}}addToolTelemetryReporter(Q){let Y=Q.initConfig&&typeof Q.initConfig==="object"?{...Q.initConfig}:{},J=typeof Y.onTelemetry==="function"?Y.onTelemetry:null,G=this.createToolTelemetryForwarder({toolId:Q.toolId,providerId:Q.providerId});return Y.onTelemetry=async(X,j)=>{if(J)await J(X,j);await G(X,j)},Y}async registerProvider(Q,Y){try{this.toolProviderRegistry.register(Q,Y);let J={providerId:Q,providerName:Y.provider.providerName};await this.hooks.onProviderRegistered?.(Q,J),await this.emitTelemetry("pie-toolkit-provider-registered",{providerId:Q,providerName:Y.provider.providerName})}catch(J){this.reportProviderRegisterFailure(J,Q)}}reportProviderRegisterFailure(Q,Y,J){console.warn(Y?`[ToolkitCoordinator] Failed to register provider "${Y}":`:`[ToolkitCoordinator] Failed to register the provider of tool "${J}":`,Q),this.handleError(Q,{phase:"provider-register",providerId:Y??void 0})}async ensureProviderReady(Q){this.assertNotDisposed();let Y=this.providerInitPromises.get(Q);if(Y)return Y;let J=(async()=>{let G=await this.toolProviderRegistry.getProvider(Q,!1);this.assertNotDisposed();let X={providerId:Q,providerName:G.providerName};try{return await this.hooks.onProviderInitStart?.(Q,X),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(Q),this.assertNotDisposed(),await this.hooks.onProviderReady?.(Q,X),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{providerId:Q}),this.assertNotDisposed(),G}catch(j){if(j instanceof s)throw j;let Z=j instanceof Error?j:Error(String(j));throw this.handleError(Z,{phase:"provider-init",providerId:Q}),Z}})().finally(()=>{this.providerInitPromises.delete(Q)});return this.providerInitPromises.set(Q,J),J}setHooks(Q){if(Object.assign(this.hooks,Q),this.setupStatePersistenceHooks(),this.disposePromise===null&&Q.onCoordinatorReady&&this.isReady())Promise.resolve(Q.onCoordinatorReady(this)).catch((Y)=>{this.handleError(Y,{phase:"coordinator-ready"})})}subscribeTelemetry(Q){return this.telemetryListeners.add(Q),()=>{this.telemetryListeners.delete(Q)}}getSectionController(Q){let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Y))}subscribeSectionEvents(Q){if(this.activeCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Y=this.activeSubscriptions.get(Q.listener);if(Y)Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null;let J={listener:Q.listener,eventTypes:Q.eventTypes,itemIds:Q.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Q.listener,J);let G=this.sectionControllers.get(this.activeCohortMapKey);if(G)this.bindSubscriptionToController(J,G);let X=!1;return()=>{if(X)return;if(X=!0,J.unsubscribeCurrent?.(),J.unsubscribeCurrent=null,this.activeSubscriptions.get(Q.listener)===J)this.activeSubscriptions.delete(Q.listener)}}bindSubscriptionToController(Q,Y){Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let J=Y.subscribe;if(typeof J!=="function")return;let G=this.buildSectionEventPredicate(Q);Q.unsubscribeCurrent=J.call(Y,(Z)=>{if(!G(Z))return;this.deliverSectionEventSafely(Q.listener,Z)});let X=this.buildContentLoadedReplayEvents(Y);for(let Z of X)if(G(Z))this.deliverSectionEventSafely(Q.listener,Z);let j=this.buildLoadingCompleteReplayEvent(Y);if(j&&G(j))this.deliverSectionEventSafely(Q.listener,j)}deliverSectionEventSafely(Q,Y){try{Q(Y)}catch(J){console.warn("[ToolkitCoordinator] section-event listener failed:",J)}}setActiveCohort(Q){if(this.activeCohortMapKey===Q)return;this.activeCohortMapKey=Q;let Y=this.sectionControllers.get(Q);if(!Y)return;for(let J of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(J,Y)}setActiveCohortIfLatestRequest(Q){if(this.latestRequestedActiveCohortMapKey!==Q)return;this.setActiveCohort(Q)}suspendActiveCohortIfSuperseded(Q){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===Q)return;this.activeCohortMapKey=null;for(let Y of Array.from(this.activeSubscriptions.values()))Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null}clearActiveCohortIfMatches(Q){if(this.activeCohortMapKey!==Q)return;this.activeCohortMapKey=null;for(let Y of Array.from(this.activeSubscriptions.values()))Y.unsubscribeCurrent?.(),Y.unsubscribeCurrent=null}buildSectionEventPredicate(Q){let Y=Q.eventTypes?new Set(Q.eventTypes):null,J=Q.itemIds?new Set(Q.itemIds):null;return(G)=>{if(Y||J){let X=G?.type||null;if(Y&&(!X||!Y.has(X)))return!1;if(J){if(!Array.from(this.collectEventItemIds(G)).some((Z)=>J.has(Z)))return!1}}return!0}}collectEventItemIds(Q){let Y=new Set;if("itemId"in Q&&typeof Q.itemId==="string")Y.add(Q.itemId);if("canonicalItemId"in Q&&typeof Q.canonicalItemId==="string")Y.add(Q.canonicalItemId);if("currentItemId"in Q&&typeof Q.currentItemId==="string")Y.add(Q.currentItemId);if("previousItemId"in Q&&typeof Q.previousItemId==="string")Y.add(Q.previousItemId);return Y}buildContentLoadedReplayEvents(Q){let Y=Q.getRuntimeState?.(),J=Y?.loadedRenderables;if(!Array.isArray(J)||J.length===0)return[];let G=typeof Y?.currentItemIndex==="number"&&Number.isFinite(Y.currentItemIndex)?Y.currentItemIndex:0,X=Date.now(),j=[];for(let Z of J){if(!Z)continue;let B=Z.itemId,W=typeof Z.canonicalItemId==="string"&&Z.canonicalItemId?Z.canonicalItemId:B;if(typeof B!=="string"||!B)continue;j.push({type:"content-loaded",contentKind:Z.contentKind??"unknown",itemId:B,canonicalItemId:W,currentItemIndex:G,timestamp:X})}return j}buildLoadingCompleteReplayEvent(Q){let Y=Q.getRuntimeState?.();if(Y?.loadingComplete!==!0)return null;let J=typeof Y.totalRegistered==="number"&&Number.isFinite(Y.totalRegistered)?Math.max(0,Y.totalRegistered):0,G=typeof Y.totalLoaded==="number"&&Number.isFinite(Y.totalLoaded)?Math.max(0,Y.totalLoaded):J;return{type:"section-loading-complete",totalRegistered:J,totalLoaded:G,currentItemIndex:Y.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||z2,itemIds:Q.itemIds,listener:Q.listener})}subscribeSectionLifecycleEvents(Q){return this.subscribeSectionEvents({eventTypes:Q.eventTypes||O2,listener:Q.listener})}onSectionControllerLifecycle(Q){return this.sectionControllerLifecycleListeners.add(Q),()=>{this.sectionControllerLifecycleListeners.delete(Q)}}async getOrCreateSectionController(Q){if(this.disposePromise!==null)throw new s;let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},J=this.getSectionControllerMapKey(Y);this.latestRequestedActiveCohortMapKey=J,this.suspendActiveCohortIfSuperseded(J);let G=await this.resolveExistingSectionController({mapKey:J,key:Y,input:Q.input,updateExisting:Q.updateExisting});if(G){if(this.disposePromise!==null)throw new s;return G}let X=this.sectionControllerDisposePromises.get(J);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new s;let j=this.sectionControllerInitEntries.get(J);if(j)return j.promise;let Z={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Q,key:Y,mapKey:J,token:Z}).catch((W)=>{throw this.handleSectionControllerInitError(W,Q),W}).finally(()=>{if(this.sectionControllerInitEntries.get(J)?.token===Z)this.sectionControllerInitEntries.delete(J)});return this.sectionControllerInitEntries.set(J,{key:Y,token:Z,promise:B}),B}async resolveExistingSectionController(Q){let Y=this.sectionControllers.get(Q.mapKey);if(!Y)return;if(this.sectionControllerKeys.set(Q.mapKey,Q.key),Q.updateExisting!==!1)await Y.updateInput?.(Q.input);if(this.sectionControllers.get(Q.mapKey)!==Y)return;return this.setActiveCohortIfLatestRequest(Q.mapKey),Y}createSectionControllerContext(Q){return{key:Q.key,coordinator:this,input:Q.input}}async initializeNewSectionController(Q){let Y=this.createSectionControllerContext({key:Q.key,input:Q.args.input}),J=await this.resolveSectionPersistence(Y);if(this.disposePromise!==null||Q.token.retired){if(this.sectionPersistenceStrategies.get(Q.mapKey)===J)this.sectionPersistenceStrategies.delete(Q.mapKey);throw this.createSectionControllerRetirementError()}let G={createDefaultController:Q.args.createDefaultController},X=await this.hooks.createSectionController?.(Y,G)??await G.createDefaultController(),j={mapKey:Q.mapKey,key:Q.key,controller:X,persistence:J,token:Q.token};try{return await this.retireUnpublishedSectionControllerIfNeeded(j),await X.configureSessionPersistence?.({strategy:J,context:Y}),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.initialize?.(Q.args.input),await this.retireUnpublishedSectionControllerIfNeeded(j),await X.hydrate?.(),await this.finalizeSectionControllerReady({...j,context:Y}),X}catch(Z){throw await this.cleanupUnpublishedSectionController(j),Z}}createSectionControllerRetirementError(){return this.disposePromise!==null?new s:new C9}async retireUnpublishedSectionControllerIfNeeded(Q){if(this.disposePromise===null&&!Q.token.retired)return;throw await this.cleanupUnpublishedSectionController(Q),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(Q){if(Q.token.candidateClaimed)return;Q.token.candidateClaimed=!0;try{await Q.controller.dispose?.()}catch(Y){this.handleError(Y,{phase:"section-controller-dispose",details:{sectionId:Q.key.sectionId,attemptId:Q.key.attemptId}})}finally{if(this.sectionPersistenceStrategies.get(Q.mapKey)===Q.persistence)this.sectionPersistenceStrategies.delete(Q.mapKey)}}retirePublishedSectionControllerIfNeeded(Q){if(this.disposePromise!==null&&!Q.token.retired)this.disposeSectionController({sectionId:Q.key.sectionId,attemptId:Q.key.attemptId});if(Q.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(Q){await this.retireUnpublishedSectionControllerIfNeeded(Q),this.sectionControllers.set(Q.mapKey,Q.controller),this.sectionControllerKeys.set(Q.mapKey,Q.key),Q.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(Q.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Q.key,controller:Q.controller}),await this.hooks.onSectionControllerReady?.(Q.context,Q.controller),this.retirePublishedSectionControllerIfNeeded(Q),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Q.key.assessmentId,sectionId:Q.key.sectionId,attemptId:Q.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(Q)}handleSectionControllerInitError(Q,Y){if(Q instanceof s||Q instanceof C9)return;this.handleError(Q,{phase:"section-controller-init",details:{sectionId:Y.sectionId,attemptId:Y.attemptId}})}disposeSectionController(Q){let Y={assessmentId:this.assessmentId,sectionId:Q.sectionId,attemptId:Q.attemptId},J=this.getSectionControllerMapKey(Y),G=this.sectionControllerInitEntries.get(J);if(G)G.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let K=this.sectionControllerDisposePromises.get(J);if(K)return K;if(!G)return Promise.resolve();let U=Promise.allSettled([G.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,U)}let j=this.sectionPersistenceStrategies.get(J);if(this.clearActiveCohortIfMatches(J),this.sectionControllers.get(J)===X)this.sectionControllers.delete(J),this.sectionControllerKeys.delete(J),this.sectionPersistenceStrategies.delete(J),this.emitSectionControllerLifecycle({type:"disposed",key:Y});let Z=this.createSectionControllerContext({key:Y,input:void 0}),B=this.disposeSectionControllerEntry({args:Q,key:Y,context:Z,controller:X,persistenceStrategy:j}),W=G?Promise.allSettled([G.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,W)}trackSectionControllerDisposal(Q,Y){this.sectionControllerDisposePromises.set(Q,Y);let J=()=>{if(this.sectionControllerDisposePromises.get(Q)===Y)this.sectionControllerDisposePromises.delete(Q)};return Y.then(J,J),Y}async disposeSectionControllerEntry(Q){try{await this.runSectionControllerDisposePipeline({key:Q.key,context:Q.context,controller:Q.controller,persistBeforeDispose:Q.args.persistBeforeDispose})}catch(Y){this.handleError(Y,{phase:"section-controller-dispose",details:{sectionId:Q.args.sectionId,attemptId:Q.args.attemptId}})}finally{await this.finalizeSectionControllerDispose({context:Q.context,persistenceStrategy:Q.persistenceStrategy,clearPersistence:Q.args.clearPersistence})}}async runSectionControllerDisposePipeline(Q){let Y=[];if(Q.persistBeforeDispose!==!1)try{await Q.controller.persist?.()}catch(J){Y.push(J)}try{await Q.controller.dispose?.()}catch(J){Y.push(J)}if(Y.length===1)throw Y[0];if(Y.length>1)throw AggregateError(Y,"Section controller persistence and disposal both failed.");await this.hooks.onSectionControllerDispose?.(Q.context,Q.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:Q.key.assessmentId,sectionId:Q.key.sectionId,attemptId:Q.key.attemptId})}async finalizeSectionControllerDispose(Q){if(Q.clearPersistence)await Q.persistenceStrategy?.clearSession?.(Q.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let Q=[],Y=async(G)=>{try{await G()}catch(X){Q.push(X)}};await this.waitForAdmittedInitialization();let J=new Map;for(let[G,X]of this.sectionControllerInitEntries)J.set(G,X.key);for(let[G,X]of this.sectionControllerKeys)J.set(G,X);for(let G of J.values())this.disposeSectionController({sectionId:G.sectionId,attemptId:G.attemptId});await Promise.allSettled(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let G of this.activeSubscriptions.values())await Y(()=>G.unsubscribeCurrent?.()),G.unsubscribeCurrent=null;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Y(()=>this.ttsService.stop()),await Y(()=>this.toolProviderRegistry.destroy()),await Y(()=>this.highlightCoordinator.destroy());for(let G of this.toolCoordinator.getRegisteredTools())await Y(()=>this.toolCoordinator.releaseTool(G));if(await Y(()=>this.catalogResolver.destroy()),await Y(()=>this.toolRequests.dispose()),await Y(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(Q.length===1)throw Q[0];if(Q.length>1)throw AggregateError(Q,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let Q=new Set;if(this.coordinatorReadyPromise)Q.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)Q.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)Q.add(this.ttsReconfigurePromise);for(let Y of this.providerInitPromises.values())Q.add(Y);await Promise.allSettled(Q)}async ensureTTSReady(Q){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(Q).then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let Q=this.ttsReconfigurePromise;while(Q)await Q,Q=this.ttsReconfigurePromise}async _initializeTTS(Q){if(this.ttsInitialized)return;let Y=this.resolveTTSToolConfig(Q),J=y8(Y),G=L9(J),X=f8(J);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:G}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:G}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:G}),this.toolProviderRegistry.has("tts"))try{let B=await(await this.ensureProviderReady("tts")).createInstance();await this.initializeTTSService(B,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:G,provider:"registry"}),console.log("[ToolkitCoordinator] TTS initialized via ToolProviderRegistry");return}catch(Z){if(Z instanceof s)throw Z;let B=Z instanceof Error?Z:Error(String(Z));await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:G,errorType:"TTSRegistryInitError",message:B.message,recovered:!0}),await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",providerId:"tts",operation:"tts-init",backend:G,fromProvider:"registry",toProvider:"browser",reason:B.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",B)}else if(G!=="browser")this.reportMissingTTSProvider(G);let j=new g7;try{await this.initializeTTSService(j,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:G,provider:"browser-fallback"})}catch(Z){if(Z instanceof s)throw Z;let B=Z instanceof Error?Z:Error(String(Z));throw this.handleError(B,{phase:"tts-init"}),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:B.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:G,errorType:"TTSInitError",message:B.message}),B}}resolveTTSToolConfig(Q){return Q||this.getTTSConfigFromProviders()||{}}async initializeTTSService(Q,Y){let J={...Y.providerOptions||{},__pieTelemetry:async(X,j)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...j||{}})}},G={...Y,providerOptions:J};await this.ttsService.initialize(Q,G),await this.ensureBrowserVoicesReady(Q),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async ensureBrowserVoicesReady(Q,Y=1200){if(Q.providerId!=="browser")return;if(typeof window>"u")return;if(!("speechSynthesis"in window))return;let J=window.speechSynthesis;if(J.getVoices().length>0)return;await new Promise((j)=>{let Z=!1,B=typeof J.addEventListener==="function"&&typeof J.removeEventListener==="function",W=!B&&"onvoiceschanged"in J,K=W?J.onvoiceschanged:null,U=!1,_=()=>{if(Z)return;if(Z=!0,window.clearTimeout(N),B)J.removeEventListener("voiceschanged",$);else if(U&&J.onvoiceschanged===$)J.onvoiceschanged=K;j()},$=(D)=>{if(!B&&typeof K==="function"&&D)K.call(J,D);_()},N=window.setTimeout(_,Y);if(B)J.addEventListener("voiceschanged",$,{once:!0});else if(W)J.onvoiceschanged=$,U=!0});let X=J.getVoices();await this.emitTelemetry("pie-toolkit-tts-browser-voices-ready",{voiceCount:X.length,timedOut:X.length===0})}getServiceBundle(){return{ttsService:this.ttsService,toolCoordinator:this.toolCoordinator,highlightCoordinator:this.highlightCoordinator,elementToolStateStore:this.elementToolStateStore,catalogResolver:this.catalogResolver,toolProviderRegistry:this.toolProviderRegistry}}async getToolProvider(Q){return this.ensureProviderReady(Q)}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{await this.ensureStateLoaded(),this.assertNotDisposed();let Q=this.getTTSConfigFromProviders();if(Q?.enabled!==!1)await this.ensureTTSReady(Q);if(this.assertNotDisposed(),!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return this.getInitStatus().coordinator}getInitStatus(){let Q={};for(let J of this.toolProviderRegistry.getProviderIds())Q[J]=this.toolProviderRegistry.isInitialized(J);let Y=this.getTTSConfigFromProviders();return{tts:this.ttsInitialized,stateLoaded:this.stateLoaded||!this.hooks.loadToolState,coordinator:(this.stateLoaded||!this.hooks.loadToolState)&&(this.ttsInitialized||Y?.enabled===!1),providers:Q}}getTTSConfigFromProviders(){return this.config.tools?.providers?.textToSpeech}assertCanonicalToolId(Q){if(typeof Q!=="string"||Q.trim().length===0)throw Error("Tool id must be a non-empty string.");if(Q==="tts")throw Error('Tool id "tts" is no longer supported. Use "textToSpeech".');if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(Q))throw Error(`Unknown tool id "${Q}".`)}installToolContextResolvers(Q){if(!Q)return;for(let[Y,J]of Object.entries(Q)){if(J==null)continue;if(this.assertCanonicalToolId(Y),typeof J!=="function")throw Error(`Invalid tool context resolver for "${Y}": expected a function.`);this.toolContextResolvers.set(Y,J)}}setToolContextResolvers(Q){this.toolContextResolvers.clear(),this.installToolContextResolvers(Q??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Q of this.toolContextResolverChangeListeners)try{Q()}catch(Y){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Y)}}isToolEnabled(Q){return this.assertCanonicalToolId(Q),this.config.tools?.providers?.[Q]?.enabled!==!1}getToolConfig(Q){return this.assertCanonicalToolId(Q),this.config.tools?.providers?.[Q]||null}updateToolConfig(Q,Y){this.assertCanonicalToolId(Q);let J=this.getToolConfig(Q)||{};if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});if(!this.config.tools.providers)this.config.tools.providers={};let G={...this.config.tools.providers||{},[Q]:M2(Q,J,Y)};this.config.tools=this.validateToolsConfig({...this.config.tools,providers:G},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}),this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Q}),this._applyToolConfigChange(Q,J)}updateToolPlacement(Q,Y){this.updateToolsPlacement({[Q]:[...Y]})}updateToolsPlacement(Q){if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});let Y=this.config.tools?.placement??{section:[],item:[],passage:[]},J={section:[...Q.section??Y.section??[]],item:[...Q.item??Y.item??[]],passage:[...Q.passage??Y.passage??[]]},G=this.validateToolsConfig({...this.config.tools,placement:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});G.placement=J,this.config.tools=G,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(Q){return this.policyEngine.decide(Q)}decideFeaturePolicy(Q){let Y=this.policyEngine.decideFeature(Q),J=this.config.assessmentOptional!==!0||this.pnpEnforcementOverride==="on";if(!Y.assessmentBound&&J&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Q}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return Y}onPolicyChange(Q){return this.policyEngine.onPolicyChange(Q)}onCatalogsChange(Q){return this.catalogResolver.onCatalogsChange(Q)}updateAssessment(Q){this.boundAssessment=Q,this.policyEngine.updateInputs({assessment:Q,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}updateCurrentItemRef(Q){this.boundCurrentItemRef=Q,this.policyEngine.updateInputs({currentItemRef:Q,pnpEnforcement:this.resolveEffectivePnpEnforcement()})}setPnpEnforcement(Q){this.pnpEnforcementOverride=Q,this.policyEngine.updateInputs({pnpEnforcement:this.resolveEffectivePnpEnforcement()})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(Q){return this.policyEngine.registerPolicySource(Q)}registerToolContextResolver(Q,Y){if(this.assertCanonicalToolId(Q),typeof Y!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);return this.toolContextResolvers.set(Q,Y),this.notifyToolContextResolverChange(),()=>{if(this.toolContextResolvers.get(Q)!==Y)return;this.toolContextResolvers.delete(Q),this.notifyToolContextResolverChange()}}hasToolContextResolver(Q){return this.assertCanonicalToolId(Q),this.toolContextResolvers.has(Q)}resolveToolContext(Q){this.assertCanonicalToolId(Q.toolId);let Y=this.toolContextResolvers.get(Q.toolId);if(!Y)return null;let J;try{J=Y(Q)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${Q.toolId}" threw:`,X),{toolId:Q.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!J)return{toolId:Q.toolId,visible:!0,params:{}};let G=J.params&&typeof J.params==="object"&&!Array.isArray(J.params)?J.params:{};return{toolId:Q.toolId,visible:J.visible!==!1,params:G,reason:typeof J.reason==="string"?J.reason:void 0}}onToolContextResolverChange(Q){return this.toolContextResolverChangeListeners.add(Q),()=>{this.toolContextResolverChangeListeners.delete(Q)}}registerToolRequestTarget(Q){return this.toolRequests.registerTarget(Q)}requestTool(Q){return this.assertCanonicalToolId(Q.toolId),this.toolRequests.request(Q)}canRequestTool(Q,Y){try{this.assertCanonicalToolId(Q)}catch{return!1}return this.toolRequests.canRequest(Q,Y)}onToolRequestTargetsChange(Q){return this.toolRequests.onTargetsChange(Q)}resolveEffectivePnpEnforcement(){if(this.pnpEnforcementOverride!==null)return this.pnpEnforcementOverride;return d7({assessment:this.boundAssessment,currentItemRef:this.boundCurrentItemRef})}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Q,Y){if(this.disposePromise!==null)return;switch(Q){case"textToSpeech":this.scheduleTTSReconfigure();break;case"answerEliminator":break;default:this._registerChangedToolProvider(Q,Y)}}_registerChangedToolProvider(Q,Y){let J=this.getProviderDescriptorTools().find((Z)=>Z.toolId===Q);if(!J)return;this.registerProviderFromTool(J);let G=(Z)=>{try{return b9(J,Z)}catch{return null}},X=G(Y),j=G(this.getToolConfig(Q)||void 0);if(!X||X===j||!this.toolProviderRegistry.has(X))return;this.toolProviderRegistry.unregister(X).catch((Z)=>{console.warn(`[ToolkitCoordinator] Failed to unregister provider "${X}":`,Z)})}scheduleTTSReconfigure(){let Q=this.ttsInitPromise,Y=Q?Q.catch(()=>{}).then(()=>this._reconfigureTTSProvider()):this._reconfigureTTSProvider();this.ttsReconfigurePromise=Y,Y.finally(()=>{if(this.ttsReconfigurePromise===Y)this.ttsReconfigurePromise=void 0}),Y.then(async()=>{if(this.disposePromise!==null)return;let J=this.getTTSConfigFromProviders();if(!this.lazyInit&&J?.enabled!==!1)await this.ensureTTSReady(J)})}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsInitPromise=void 0;try{this.ttsService.stop()}catch{}if(this.toolProviderRegistry.has("tts"))await this.toolProviderRegistry.unregister("tts");if(this.disposePromise!==null)return;let Q=this.getProviderDescriptorTools().find((Y)=>Y.toolId==="textToSpeech");if(!Q)return;await this.registerProviderFromTool(Q)}}var P2=()=>{};function m8(Q){let{ttsService:Y,listenerId:J,silence:G}=Q;if(typeof Y?.onStateChange!=="function")return P2;let X=(j)=>{if(j!==w.PLAYING&&j!==w.LOADING)return;G()};return Y.onStateChange(J,X),()=>{try{Y.offStateChange?.(J,X)}catch{}}}function u8(Q){try{if(Q?.isPlaying?.())Q.pause?.()}catch{}}import{timedMediaProjectionSignature as Q4}from"@pie-players/pie-players-shared/timed-media";var p8="pie-register",g8="pie-unregister",c8="pie-item-session-changed";var d8="pie-content-loaded",l8="pie-item-player-error",i8="pie-formative-action",s8="pie-media-time-source";var L2={bubbles:!0,composed:!0,cancelable:!1};function w2(Q,Y,J={}){return new CustomEvent(Q,{detail:Y,...L2,...J})}function y9(Q,Y,J,G={}){return Q.dispatchEvent(w2(Y,J,G))}function x7(){return{phase:"idle",cohort:null,controllerResolved:!1,readinessSignals:{sectionReady:!1,interactionReady:!1,allLoadingComplete:!1,runtimeError:!1},effectiveRuntime:null,effectiveToolsConfig:null,loadingCompleteEmitted:!1,lastFrameworkError:null,itemCount:0,loadedCount:0}}function f9(Q,Y){if(Q===Y)return!0;if(!Q||!Y)return!1;return Q.sectionId===Y.sectionId&&Q.attemptId===Y.attemptId}function R2(Q){if(Q.runtimeError)return"error";if(Q.allLoadingComplete)return"ready";if(Q.interactionReady)return"interaction-ready";if(Q.sectionReady)return"loading";return"bootstrapping"}function n8(Q){let Y=Q.signals.sectionReady&&Q.signals.allLoadingComplete,J=Q.mode==="strict"?Y:Q.signals.interactionReady;return{phase:R2({...Q.signals,allLoadingComplete:Y,interactionReady:J}),interactionReady:J,allLoadingComplete:Y,reason:Q.reason}}function r8(Q){switch(Q){case"idle":return null;case"booting-section":return"composed";case"engine-ready":return"engine-ready";case"interactive":return"interactive";case"disposed":return"disposed"}}function z1(Q,Y,J,G="entered"){let X=r8(Y);if(!X)return;Q.push({kind:"stage-change",stage:X,status:G,cohort:J})}function o8(Q){let Y={...x7(),phase:"booting-section",cohort:Q.cohort,effectiveRuntime:Q.effectiveRuntime,effectiveToolsConfig:Q.effectiveToolsConfig,itemCount:Q.itemCount},J=[];return z1(J,"booting-section",Q.cohort),{state:Y,outputs:J}}function E2(Q,Y){if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};let J=n8({mode:Y.mode,signals:Y.signals}),G=[],X=Q.phase,j=Q.loadingCompleteEmitted;if(X==="engine-ready"&&J.interactionReady)X="interactive",z1(G,X,Q.cohort);if(J.allLoadingComplete&&Q.cohort&&!j)j=!0,G.push({kind:"loading-complete",cohort:Q.cohort,itemCount:Y.itemCount,loadedCount:Y.loadedCount});return{state:{...Q,phase:X,readinessSignals:Y.signals,loadedCount:Y.loadedCount,itemCount:Y.itemCount,loadingCompleteEmitted:j},outputs:G}}function l7(Q,Y){switch(Y.kind){case"initialize":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(Q.phase!=="idle"){if(f9(Q.cohort,Y.cohort))return l7(Q,{kind:"update-runtime",effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig});return l7(Q,{kind:"cohort-change",cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount})}return o8({state:Q,cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount})}case"update-runtime":{if(Q.phase==="idle"||Q.phase==="disposed")return{state:Q,outputs:[]};return{state:{...Q,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig},outputs:[]}}case"cohort-change":{if(Q.phase==="disposed")return{state:Q,outputs:[]};if(f9(Q.cohort,Y.cohort))return l7(Q,{kind:"update-runtime",effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig});let J=[];if(Q.phase!=="idle")J.push({kind:"stage-change",stage:"disposed",status:"entered",cohort:Q.cohort});let G=o8({state:Q,cohort:Y.cohort,effectiveRuntime:Y.effectiveRuntime,effectiveToolsConfig:Y.effectiveToolsConfig,itemCount:Y.itemCount});return{state:G.state,outputs:[...J,...G.outputs]}}case"section-controller-resolved":{if(Q.phase!=="booting-section")return{state:{...Q,controllerResolved:!0},outputs:[]};let J=[];return z1(J,"engine-ready",Q.cohort),{state:{...Q,phase:"engine-ready",controllerResolved:!0},outputs:J}}case"update-readiness-signals":return E2(Q,{signals:Y.signals,mode:Y.mode,loadedCount:Y.loadedCount,itemCount:Y.itemCount});case"framework-error":return{state:{...Q,lastFrameworkError:Y.error,readinessSignals:{...Q.readinessSignals,runtimeError:Y.error.recoverable===!0?Q.readinessSignals.runtimeError:!0}},outputs:[{kind:"framework-error",error:Y.error}]};case"dispose":{if(Q.phase==="disposed")return{state:Q,outputs:[]};let J=[];if(Q.phase!=="idle")z1(J,"disposed",Q.cohort);return{state:{...Q,phase:"disposed"},outputs:J}}default:{let J=Y;return{state:Q,outputs:[]}}}}class x9{state=x7();listeners=new Set;getState(){return this.state}dispatch(Q){let Y=l7(this.state,Q);if(this.state=Y.state,Y.outputs.length>0)this.fanOut(Y.outputs);return Y.outputs}subscribe(Q){this.listeners.add(Q);let Y=!0;return()=>{if(!Y)return;Y=!1,this.listeners.delete(Q)}}disposeListeners(){this.listeners.clear()}fanOut(Q){let Y=Array.from(this.listeners),J=Object.freeze(Q.slice());for(let G of Y)try{G(J)}catch(X){console.warn("[SectionEngineCore] listener failed:",X)}}}function a8(Q){let{coordinator:Y,dispatchCoreInput:J}=Q,G=0,X=null,j=null,Z=!1,B=Y.subscribeFrameworkErrors((_)=>{try{J({kind:"framework-error",error:_})}catch($){console.warn("[CoordinatorBridge] framework-error dispatch failed:",$)}});function W(){if(!j)return;try{j()}catch(_){console.warn("[CoordinatorBridge] controller unsubscribe failed:",_)}j=null}async function K(_){if(Z)return;G+=1;let $=G;X=_.cohort;let N=await Y.getOrCreateSectionController({sectionId:_.cohort.sectionId,attemptId:_.cohort.attemptId||void 0,input:{section:_.section,sectionId:_.cohort.sectionId,assessmentId:_.assessmentId,view:_.view},updateExisting:!0,createDefaultController:_.createDefaultController});if($!==G||Z)return;W(),_.onControllerResolved?.(N);let D=N.getCompositionModel;if(_.onCompositionChanged?.(D?.()),typeof N.subscribe==="function")j=N.subscribe((O)=>{if($!==G||Z)return;_.onCompositionChanged?.(D?.())});J({kind:"section-controller-resolved"})}async function U(){if(Z)return;Z=!0,G+=1,W();try{B()}catch($){console.warn("[CoordinatorBridge] framework-error unsubscribe failed:",$)}let _=X;if(X=null,_)try{await Y.disposeSectionController({sectionId:_.sectionId,attemptId:_.attemptId||void 0})}catch($){console.warn("[CoordinatorBridge] section-controller dispose failed:",$)}}return{resolveSectionController:K,dispose:U}}function t8(Q){let{runtimeId:Y,sourceCe:J}=Q,G=Q.host,X=Q.now??(()=>new Date().toISOString());function j(U){let _={stage:U.stage,status:U.status,runtimeId:Y,sectionId:U.cohort?.sectionId,attemptId:U.cohort?.attemptId?U.cohort.attemptId:void 0,timestamp:X(),sourceCe:J};G.dispatchEvent(new CustomEvent("pie-stage-change",{detail:_}))}function Z(U){let _={runtimeId:Y,sectionId:U.cohort.sectionId,attemptId:U.cohort.attemptId?U.cohort.attemptId:void 0,itemCount:U.itemCount,loadedCount:U.loadedCount,timestamp:X(),sourceCe:J};G.dispatchEvent(new CustomEvent("pie-loading-complete",{detail:_}))}function B(U){G.dispatchEvent(new CustomEvent("framework-error",{detail:U.error}))}function W(U){switch(U.kind){case"stage-change":j(U);return;case"loading-complete":Z(U);return;case"framework-error":B(U);return;default:{let _=U;return}}}function K(U){G=U}return{dispatch:W,setHost:K}}function e8(Q){let{bus:Y}=Q;function J(G){switch(G.kind){case"framework-error":Y.reportFrameworkError(G.error);return;case"stage-change":case"loading-complete":return;default:{let X=G;return}}}return{dispatch:J}}function Q6(Q={}){let Y=Q.hook;function J(X){if(!Y)return;try{Y(X)}catch(j){console.warn("[InstrumentationBridge] hook failed:",j)}}function G(X){Y=X}return{dispatch:J,setHook:G}}function Y6(){let Q=new Set;function Y(j){if(j.length===0)return;let Z=Array.from(Q),B=Object.freeze(j.slice());for(let W of Z)try{W(B)}catch(K){console.warn("[SubscriberFanout] listener failed:",K)}}function J(j){Q.add(j);let Z=!0;return()=>{if(!Z)return;Z=!1,Q.delete(j)}}function G(){Q.clear()}function X(){return Q.size}return{emit:Y,subscribe:J,dispose:G,getListenerCount:X}}class k9{core;domEventBridge;frameworkErrorBridge;instrumentationBridge;subscriberFanout;coordinatorBridge;unsubscribeCore;disposed=!1;constructor(Q){this.core=Q.core??new x9,this.domEventBridge=t8({host:Q.host,runtimeId:Q.runtimeId,sourceCe:Q.sourceCe,now:Q.now}),this.frameworkErrorBridge=e8({bus:Q.frameworkErrorBus}),this.instrumentationBridge=Q6({hook:Q.instrumentationHook}),this.subscriberFanout=Y6(),this.coordinatorBridge=Q.coordinator?a8({coordinator:Q.coordinator,dispatchCoreInput:(Y)=>this.dispatchInput(Y)}):null,this.unsubscribeCore=this.core.subscribe((Y)=>{this.routeOutputs(Y)})}getState(){return this.core.getState()}dispatchInput(Q){if(this.disposed)return[];return this.core.dispatch(Q)}subscribe(Q){return this.subscriberFanout.subscribe(Q)}setHost(Q){this.domEventBridge.setHost(Q)}setInstrumentationHook(Q){this.instrumentationBridge.setHook(Q)}resolveSectionController(Q){if(!this.coordinatorBridge)throw Error("[SectionEngineAdapter] resolveSectionController called without a coordinator.");return this.coordinatorBridge.resolveSectionController(Q)}async dispose(){if(this.disposed)return;if(this.disposed=!0,this.core.dispatch({kind:"dispose"}),this.unsubscribeCore(),this.subscriberFanout.dispose(),this.coordinatorBridge)await this.coordinatorBridge.dispose()}routeOutputs(Q){for(let Y of Q)this.routeOne(Y);this.subscriberFanout.emit(Q)}routeOne(Q){switch(Q.kind){case"stage-change":case"loading-complete":this.domEventBridge.dispatch(Q);break;case"framework-error":this.domEventBridge.dispatch(Q),this.frameworkErrorBridge.dispatch(Q);break;default:{let Y=Q;return}}this.instrumentationBridge.dispatch(Q)}}var b2={mode:"gather",role:"student"};function O1(Q,Y){return Q!==void 0?Q:Y}function S2(Q){let Y=Q.runtime??{};if(Y.onFrameworkError!==void 0)return Y.onFrameworkError;return Q.onFrameworkError}function C2(Q){let Y=Q.runtime?.tools||{},J=Y.placement||{};return{...Y,placement:{...J}}}function T2(Q){let Y=Q.runtime||{},J=Y.player?{...Y.player}:null;return{...Y,assessmentId:O1(Y.assessmentId,Q.assessmentId),playerType:Y.playerType??"iife",player:J,lazyInit:Y.lazyInit??!0,accessibility:Y.accessibility??null,coordinator:Y.coordinator??null,createSectionController:Y.createSectionController,isolation:Y.isolation??"inherit",env:Y.env??b2,toolConfigStrictness:O1(Y.toolConfigStrictness,Q.toolConfigStrictness)??"error",onFrameworkError:S2({runtime:Q.runtime,onFrameworkError:Q.onFrameworkError}),onStageChange:O1(Y.onStageChange,Q.onStageChange),onLoadingComplete:O1(Y.onLoadingComplete,Q.onLoadingComplete),tools:Q.effectiveToolsConfig}}function J6(Q,Y){let J=Q.assessmentId??"section-demo-direct",G=C2({runtime:Q.runtime}),X=T2({assessmentId:J,runtime:Q.runtime,effectiveToolsConfig:G,toolConfigStrictness:Q.toolConfigStrictness,onFrameworkError:Q.onFrameworkError,onStageChange:Q.onStageChange,onLoadingComplete:Q.onLoadingComplete}),j=Y.resolvePlayerRuntime({effectiveRuntime:X,playerType:String(X.playerType??"iife"),env:X.env??null});return{effectiveToolsConfig:G,effectiveRuntime:X,playerRuntime:j}}import{createPieLogger as f2,isGlobalDebugEnabled as x2}from"@pie-players/pie-players-shared";function y2(Q,Y){if(Q===Y)return 0;let J=Q.compareDocumentPosition(Y);if(J&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(J&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class I9{shellsByElement=new Map;register(Q){let Y=this.shellsByElement.get(Q.element),J={...Q,sortKey:Date.now()};if(Y&&Y.kind===J.kind&&Y.itemId===J.itemId&&Y.canonicalItemId===J.canonicalItemId)return!1;return this.shellsByElement.set(Q.element,J),!0}unregister(Q){return this.shellsByElement.delete(Q)}getOrderedShells(Q){let Y=Array.from(this.shellsByElement.values()).filter((J)=>!Q||J.kind===Q);return Y.sort((J,G)=>y2(J.element,G.element)),Y}getCanonicalIdMap(){let Q={};for(let Y of this.getOrderedShells("item")){if(!Y.itemId)continue;Q[Y.itemId]=Y.canonicalItemId||Y.itemId}return Q}clear(){this.shellsByElement.clear()}}function P1(Q="runtime"){return`${Q}-${Math.random().toString(16).slice(2)}-${Date.now()}`}var k2=f2("section-runtime-engine",()=>x2());class v9{registry=new I9;runtimeId=P1("section-engine");adapter=null;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;loadedRenderableKeys=new Set;attachHost(Q){if(this.adapter){if(this.adapter.setHost(Q.host),Q.instrumentationHook!==void 0)this.adapter.setInstrumentationHook(Q.instrumentationHook);return}this.adapter=new k9({host:Q.host,runtimeId:this.runtimeId,sourceCe:Q.sourceCe,frameworkErrorBus:Q.frameworkErrorBus,coordinator:Q.coordinator,instrumentationHook:Q.instrumentationHook,now:Q.now})}dispatchInput(Q){return this.adapter?.dispatchInput(Q)??[]}subscribe(Q){return this.adapter?.subscribe(Q)??I2}getState(){return this.adapter?.getState()??x7()}getEffectiveRuntime(Q,Y){return J6(Q,Y).effectiveRuntime}setInstrumentationHook(Q){this.adapter?.setInstrumentationHook(Q)}getRuntimeId(){return this.runtimeId}async initialize(Q){this.activeInitToken+=1;let Y=this.activeInitToken;this.coordinator=Q.coordinator,this.sectionId=Q.sectionId,this.attemptId=Q.attemptId;let J=await Q.coordinator.getOrCreateSectionController({sectionId:Q.sectionId,attemptId:Q.attemptId,input:{section:Q.section,sectionId:Q.sectionId,assessmentId:Q.assessmentId,view:Q.view},updateExisting:!0,createDefaultController:Q.createDefaultController});if(Y!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=J,this.replayRegisteredShellsIntoController(J),Q.onCompositionChanged?.(J.getCompositionModel?.()),this.unsubscribeController=J.subscribe?.((G)=>{try{Q.onControllerEvent?.(G)}catch(X){k2.warn("onControllerEvent handler threw",X)}Q.onCompositionChanged?.(J.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Q){if(!Q.handleContentRegistered)return;let Y=this.registry.getOrderedShells();if(Y.length===0)return;for(let G of Y){let X=G.canonicalItemId||G.itemId;Q.handleContentRegistered({itemId:G.itemId,canonicalItemId:X,contentKind:G.contentKind||G.kind})}let J=Date.now();for(let G of Y){let X=G.canonicalItemId||G.itemId,j=this.getLoadedKey(X,G.contentKind);if(this.loadedRenderableKeys.has(j))Q.handleContentLoaded?.({itemId:G.itemId,canonicalItemId:X,contentKind:G.contentKind||G.kind,timestamp:J})}}getLoadedKey(Q,Y){return`${Y??""}:${Q}`}register(Q){return this.registry.register(Q)}unregister(Q){return this.registry.unregister(Q)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(Q){return this.registry.getCanonicalIdMap()[Q]||this.controller?.getCanonicalItemId?.(Q)||Q}handleContentRegistered(Q){this.controller?.handleContentRegistered?.({itemId:Q.itemId,canonicalItemId:Q.canonicalItemId||Q.itemId,contentKind:Q.contentKind||Q.kind})}handleContentUnregistered(Q){let Y=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.delete(this.getLoadedKey(Y,Q.contentKind)),this.controller?.handleContentUnregistered?.({itemId:Q.itemId,canonicalItemId:Y,contentKind:Q.contentKind||Q.kind})}handleContentLoaded(Q){let Y=Q.canonicalItemId||Q.itemId;this.loadedRenderableKeys.add(this.getLoadedKey(Y,Q.contentKind)),this.controller?.handleContentLoaded?.(Q)}handleItemPlayerError(Q){this.controller?.handleItemPlayerError?.(Q)}reportSectionError(Q){this.controller?.reportSectionError?.(Q)}updateItemSession(Q,Y){let J=this.getCanonicalItemId(Q);return this.controller?.updateItemSession?.(J,Y)??null}navigateToItem(Q){return this.controller?.navigateToItem?.(Q)??null}handleFormativeAction(Q){if(!Q?.itemId)return;let Y=this.getCanonicalItemId(Q.itemId);if(Q.action==="retry"){this.controller?.retryFormativeItem?.({itemId:Y});return}this.controller?.recordFormativeTry?.({itemId:Y,outcomes:Q.outcomes})}handleMediaTimeSource(Q){if(Q?.action==="detach"){this.controller?.detachMediaTimeSource?.({origin:Q.origin??"host"});return}if(!Q?.source)return;this.controller?.attachMediaTimeSource?.(Q.source,{origin:Q.origin??"host",renderableId:Q.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});if(this.registry.clear(),this.loadedRenderableKeys.clear(),this.controller=null,this.coordinator=null,this.adapter){let Q=this.adapter;this.adapter=null,await Q.dispose()}}}var I2=()=>{};import{connectContextWithRetry as v2,createContext as h2}from"@pie-players/pie-context";var m2=h2(Symbol.for("pie.sectionRuntimeEngineHostContext"));function G6(Q,Y){return v2(Q,m2,Y)}var u2=(Q)=>{console.error("[pie-assessment-toolkit] onStageChange handler threw",Q)};function X6(Q,Y){if(Q.isSuppressed())return!1;Q.dispatchDomEvent(Y);let J=Q.getOnStageChange();if(J)try{J(Y)}catch(G){(Q.logHandlerError??u2)(G)}return!0}function i7(Q,Y){if(typeof Q==="function")return Q;if(Q===null)return null;return typeof Y==="function"?Y:null}function Z6(Q={}){let Y=Q.frameDeadlineMs??100,J=!1,G=null,X=null,j=null,Z=null,B=null;function W(){if(J=!1,X!==null)Z?.(X),X=null;if(j!==null)B?.(j),j=null;Z=null,B=null}function K($){if(!J)return;if($==="frame")X=null;if($==="timer")j=null;let N=G;G=null,W(),N?.()}function U($){if(G=$,J)return;J=!0;let N=globalThis,D=i7(Q.requestFrame,N.requestAnimationFrame);Z=i7(Q.cancelFrame,N.cancelAnimationFrame);let O=i7(Q.setTimer,N.setTimeout);if(B=i7(Q.clearTimer,N.clearTimeout),D){let F=D(()=>K("frame"));if(!J)return;if(X=F,O){let L=O(()=>K("timer"),Y);if(J)j=L}return}let P=i7(Q.queueMicrotaskFn,N.queueMicrotask);if(P){P(()=>K("microtask"));return}if(O){let F=O(()=>K("timer"),0);if(J)j=F;return}K("microtask")}function _(){if(!J)return;G=null,W()}return{schedule:U,cancel:_,isPending:()=>J}}function j6(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function B6(Q){Q.lastSessionEventSignatureByItemId.clear(),Q.lastMetadataSignatureByItemId.clear()}function q6(Q){let{state:Y,itemId:J,payload:G}=Q;if(g2(G)){let Z=c2(G);if(Y.lastMetadataSignatureByItemId.get(J)===Z)return!1;Y.lastMetadataSignatureByItemId.set(J,Z)}let X=p2(G);if(Y.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Y.lastSessionEventSignatureByItemId.set(J,X),!0}function p2(Q){let Y={...Q};delete Y.timestamp,delete Y.sourceRuntimeId;try{return JSON.stringify(Y)}catch{return String(Y.itemId||"")}}function g2(Q){return Q.intent==="metadata-only"}function c2(Q){try{return JSON.stringify({itemId:Q.itemId,canonicalItemId:Q.canonicalItemId,intent:Q.intent,complete:Q.complete??null,component:Q.component??null})}catch{return String(Q.itemId||"")}}var d2=(Q,Y)=>{if(customElements.get(Q))return;try{customElements.define(Q,Y)}catch(J){if(!(J instanceof DOMException&&J.name==="NotSupportedError"||J&&typeof J==="object"&&J.name==="NotSupportedError")||!customElements.get(Q))throw J}},Y4=p9('<div class="pie-assessment-toolkit-error svelte-15pthty" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-15pthty"> </div> <div class="pie-assessment-toolkit-error-message svelte-15pthty"> </div> <pre class="pie-assessment-toolkit-error-details svelte-15pthty"> </pre></div>'),J4=p9('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),G4={hash:"svelte-15pthty",code:`.pie-assessment-toolkit-anchor.svelte-15pthty {display:none;}.pie-assessment-toolkit-error.svelte-15pthty {margin:0.75rem;padding:0.75rem 1rem;border-radius:0.5rem;border:1px solid
|
|
224
|
-
color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 40%, transparent);background:color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 12%, transparent);color:var(--pie-incorrect, #7f1d1d);font-size:0.9rem;}.pie-assessment-toolkit-error-title.svelte-15pthty {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-15pthty {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-15pthty {margin:0;white-space:pre-wrap;word-break:break-word;}`};function w6(Q,Y){V6(Y,!0),N6(Q,G4);let J=P1("toolkit"),G=new v9,X=m(null),j=new u7,Z={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},W=f(Y,"assessmentId",7,""),K=f(Y,"section",7,null),U=f(Y,"sectionId",7,""),_=f(Y,"attemptId",7,""),$=f(Y,"env",23,()=>({})),N=f(Y,"ndsIcons",7,!1),D=f(Y,"locale",7,""),O=f(Y,"lazyInit",7,!0),P=f(Y,"toolConfigStrictness",7,"error"),F=f(Y,"tools",23,()=>({})),L=f(Y,"toolContextResolvers",7,null),C=f(Y,"enabledTools",7,""),v=f(Y,"toolRegistry",7,null),k=f(Y,"accessibility",23,()=>({})),p=f(Y,"player",7,null),R=f(Y,"playerType",7,""),g=f(Y,"coordinator",7,null),B7=f(Y,"createSectionController",7,null),q7=f(Y,"onFrameworkError",7,null),W7=f(Y,"errorRenderer",7,null),w7=f(Y,"onStageChange",7,null),s7=f(Y,"assessment",7,null),n7=f(Y,"currentItemRef",7,null),r7=f(Y,"pnpEnforcement",7,null),K7=f(Y,"isolation",7,"inherit"),k7=m(null),d=m(null),G7=m(null),g9=null,I7=null,v7=null,o7=null,h7=null,a7=null,t7=m(0),b1=m(null),o=m(null),S1=m("Unable to initialize assessment toolkit."),C1=m(h9([])),c9="",T1="",d9=null,y1=!1,l9=!1,i9=m(""),s9=null,n9=Z6(),U7=[],e7=new Map,f1=new WeakMap,r9=j6(),n=n2({sourceCe:"pie-assessment-toolkit",sourceCeShape:"toolkit",runtimeId:J,sectionId:h(()=>U()||void 0),attemptId:h(()=>_()||void 0),emit:(q)=>{X6({isSuppressed:()=>A(X)!==null,dispatchDomEvent:(V)=>V7("pie-stage-change",V),getOnStageChange:()=>w7()},q)}}),o9=m(h9(h(()=>`${U()}|${_()}`))),Q1=m(!1),t=m(!1),x1=m(!1),k1=m(!1);function R6(){if(!A(k7))return null;let q=A(k7).getRootNode();if(q&&"host"in q)return q.host;return A(k7).parentElement}let x=c(()=>R6());function V7(q,V){if(!A(x)){U7=[...U7,{name:q,detail:V}];return}y9(A(x),q,V)}b(()=>{if(!A(x))return;if(U7.length===0)return;let q=U7;U7=[],queueMicrotask(()=>{let V=A(x);if(!V){U7=[...q,...U7];return}for(let M of q)y9(V,M.name,M.detail)})});function E6(q){if(!W7())return{title:"Unable to initialize assessment toolkit.",details:q.details.length>0?q.details:[q.message]};try{let V=W7()(q)||{};return{title:typeof V.title==="string"&&V.title.trim().length>0?V.title:"Unable to initialize assessment toolkit.",details:Array.isArray(V.details)&&V.details.length>0?V.details.map((M)=>String(M)):q.details.length>0?q.details:[q.message]}}catch(V){let M=V instanceof Error&&V.message.trim().length>0?V.message:String(V||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...q.details,`Error renderer failed: ${M}`]}}}function R7(q){let V=g1({kind:q.kind,source:q.source,error:q.error,recoverable:q.recoverable});return j.reportFrameworkError(V),V}function b6(q){if(q?.type==="timed-media-policy-degraded"){let M=q.degradations||[];j.reportFrameworkError(B1({kind:"timed-media",severity:"warning",source:"pie-assessment-toolkit",message:"A timed-media playback policy degraded to advisory: the media time source does not report the capability it needs.",details:M.map((z)=>z?.message).filter((z)=>typeof z==="string"),recoverable:!0}));return}if(q?.type!=="timed-media-invalid")return;let V=q.errors||[];j.reportFrameworkError(B1({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:V.map((M)=>M?.message).filter((M)=>typeof M==="string"),recoverable:!1}))}function S6(q){if(q?.type!=="timed-media-audio-started")return;if(!A(S))return;u8(A(S).getServiceBundle().ttsService)}function C6(q){return q==="coordinator-init"||q==="runtime-init"||q==="tool-config"}function a9(q){if(!q7())return;try{q7()(q),c9=`${q.kind}|${q.source}|${q.message}`}catch(V){console.error(`[pie-framework:${q.kind}:${q.source}] framework error hook failed`,V)}}let t9=new WeakSet;b(()=>{let q=j.subscribeFrameworkErrors((V)=>{if(console.error(K0(V),V.cause),C6(V.kind)&&!t9.has(V)){let M=E6(V);E(o,V,!0),E(S1,M.title,!0),E(C1,M.details,!0)}V7("framework-error",V),a9(V)});return()=>{q()}}),b(()=>{let q=g();if(!q||A(S)!==q)return;if(typeof q.subscribeFrameworkErrors!=="function")return;return h(()=>q.subscribeFrameworkErrors((V)=>{t9.add(V),j.reportFrameworkError(V)}))}),b(()=>{let q=g(),V=v();if(!q||A(S)!==q)return;if(typeof q.adoptToolRegistry!=="function")return;h(()=>q.adoptToolRegistry(V))}),b(()=>{if(!A(o))return;let q=`${A(o).kind}|${A(o).source}|${A(o).message}`;if(c9===q)return;a9(A(o))});function T6(q){let V=5381;for(let M=0;M<q.length;M+=1)V=(V<<5)+V^q.charCodeAt(M);return(V>>>0).toString(36)}function r(q){return q&&typeof q==="object"?q:{}}function y6(q){let V=r(q.section),M=typeof V.identifier==="string"?V.identifier:"",z=typeof q.sectionId==="string"?q.sectionId:"";return M||z}function f6(q){return typeof q.currentItemIndex==="number"?q.currentItemIndex:-1}function x6(q){return(Array.isArray(q.renderables)?q.renderables:[]).map((M,z)=>{let H=r(M),I=r(H.entity),Q7=typeof I.id==="string"&&I.id||`renderable-${z}`,j1=r(I.config),p1=typeof I.version==="string"&&I.version||(typeof I.version==="number"?String(I.version):"")||(typeof j1.version==="string"?j1.version:"");return{id:Q7,version:p1}})}function k6(q){let V=r(q.itemSessionsByItemId);return Object.keys(V).sort((M,z)=>M.localeCompare(z)).map((M)=>{let z=r(V[M]),H=typeof z.id==="string"?z.id:"",I=Array.isArray(z.data)?z.data:[],Q7="";try{Q7=T6(JSON.stringify(I))}catch{Q7=String(I.length)}return{itemId:M,sessionId:H,payloadSignature:Q7}})}function I6(q){let V=r(r(q.formative).states);return Object.entries(V).map(([M,z])=>{let H=r(z),I=r(H.lastOutcome).correctness??"";return`${M}:${H.tryCount??0}:${H.revealed===!0?1:0}:${String(I)}:${String(H.revealOverride??"")}`}).sort().join("|")}function v6(q){let V=q.timedMedia;return Q4(V)}function h6(q){let V=r(q),M=x6(V).map((H)=>`${H.id}:${H.version}`).join("|"),z=k6(V).map((H)=>`${H.itemId}:${H.sessionId}:${H.payloadSignature}`).join("|");return{sectionId:y6(V),currentItemIndex:f6(V),renderableSignature:M,itemSessionSignature:z,formativeSignature:I6(V),timedMediaSignature:v6(V)}}function m6(q){let V=h6(q);return`${V.sectionId}|${V.currentItemIndex}|${V.renderableSignature}|${V.itemSessionSignature}|${V.formativeSignature}|${V.timedMediaSignature}`}function e9(q){return q==="iife"||q==="esm"||q==="preloaded"||q==="custom"}function u6(q,V){let M=q?.type,z=e9(M)?M:e9(V)?V:q?.tagName?"custom":"iife",H=q?.tagName?.trim();if(z==="custom"&&!H)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:z,tagName:H||B[z],version:q?.version,source:q?.source,loaderConfig:q?.loaderConfig,loaderOptions:q?.loaderOptions,isDefault:!q&&!V}}function Q0(q){let V=q||{},M=typeof V.mode==="string"&&V.mode.trim()?V.mode.trim():Z.mode,z=typeof V.role==="string"&&V.role.trim()?V.role.trim():Z.role;return{mode:M,role:z}}function p6(q){let V=Q0(q);if(V.mode==="author")return"author";if(V.role==="instructor")return"scorer";return"candidate"}async function g6(){if(B7())return B7()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function I1(){let q=F()||{},V=L6(C());if(V.length===0)return q;let M=q.placement||{},z=Array.isArray(M.section)?M.section:null;if(z&&z.length>0)return q;return{...q,placement:{...M,section:V}}}function c6(){return A0(I1(),{strictness:P(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:v()}).config}function d6(){let q="",V="";try{q=JSON.stringify(I1())}catch{q="[unserializable-tools]"}try{V=JSON.stringify(Object.entries(L()??{}).map(([M,z])=>[M,typeof z]))}catch{V="[unserializable-resolvers]"}return[W()||"",String(P()||"error"),q,V].join("|")}function Y0(q){return q==="on"||q==="off"?q:null}function l6(q,V){let M=Y0(q);if(M)return M;if(V&&typeof V==="object"){let H=V.pnpEnforcement;return Y0(typeof H==="string"?H:null)}return null}function i6(q){let V=W()||K()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new T9({assessmentId:V,lazyInit:O(),toolConfigStrictness:P(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:q,toolRegistry:v(),toolContextResolvers:L(),accessibility:k(),frameworkErrorBus:j})}function J0(q){try{return JSON.stringify(q??null)}catch{return"[unserializable]"}}function G0(){return{signatures:{assessmentId:W()||"",toolConfigStrictness:String(P()||"error"),lazyInit:String(O()),tools:J0({...I1(),pnpEnforcement:void 0}),accessibility:J0(k())},toolRegistry:v()}}function s6(){let q=d9;if(!q)return[];let V=G0(),M=Object.keys(V.signatures).filter((z)=>V.signatures[z]!==q.signatures[z]);if(V.toolRegistry!==q.toolRegistry)M.push("toolRegistry");return M}function n6(q){if(l9)return;l9=!0,console.warn(`[pie-assessment-toolkit] ${q.join(", ")} changed after a section initialized with the coordinator this toolkit built, and that coordinator keeps the values it was built with. Set these inputs no later than the section, pass a coordinator of your own, or update this one from toolkit-ready with updateToolConfig(...) or updateToolsPlacement(...). Reported once per toolkit.`)}function Y1(){let q=A(d);if(!q)return Promise.resolve();return E(d,null),q.dispose()}function J1(q){R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}let S=c(()=>{if(K7()!=="force"&&A(G7)?.coordinator)return A(G7).coordinator;return g()||A(d)}),r6=c(()=>K()!=null);b(()=>{A(x),g(),K7(),A(G7),L(),A(r6),F(),C(),W(),P(),O(),k(),v(),h(()=>{if(!A(x))return;if(g()){if(A(d))Y1().catch(J1);I7=null;return}if(K7()!=="force"&&A(G7)?.coordinator){if(A(d))Y1().catch(J1);I7=null;return}if(A(d)){let q=s6();if(q.length>0&&y1)n6(q);else if(q.length>0&&K())Y1().catch(J1)}if(A(d)&&I7!==L()){try{A(d).setToolContextResolvers(L()),I7=L()}catch(q){R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:q})}return}if(!A(d)){let q=d6();if(T1===q)return;try{let V=c6();E(d,i6(V),!0),d9=G0(),y1=!1,I7=L(),T1="",E(o,null),E(S1,"Unable to initialize assessment toolkit."),E(C1,[],!0)}catch(V){E(d,null),T1=q,R7({kind:"coordinator-init",source:"pie-assessment-toolkit",error:V})}}})});let G1=t2(),v1=m(0);b(()=>G1.subscribe(()=>{E(v1,A(v1)+1)})),b(()=>{let q=typeof D()==="string"?D().trim():"";h(()=>{Promise.resolve(G1.setLocale(q||e2)).catch((V)=>{R7({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:V instanceof Error?V:Error(String(V))})})})});let X7=c(()=>W()||A(S)?.assessmentId||""),e=c(()=>U()||K()?.identifier||`section-${A(X7)||"default"}`),h1=c(()=>Q0($())),o6=c(()=>p6(A(h1))),E7=c(()=>u6(p(),R())),m7=c(()=>r2({player:A(E7),component:"pie-assessment-toolkit"})),X1=c(()=>{if(!A(S))return null;let q=A(S).getServiceBundle();return{toolkitCoordinator:A(S),toolCoordinator:A(S).toolCoordinator,ttsService:q.ttsService,highlightCoordinator:q.highlightCoordinator,catalogResolver:q.catalogResolver,elementToolStateStore:q.elementToolStateStore,assessmentId:A(X7),sectionId:A(e),itemPlayer:A(E7),ndsIcons:N()===!0,locale:(A(v1),G1.getLocale()),i18n:G1,reportSessionChanged:(V,M)=>{let z=G.updateItemSession(V,M);j0({itemId:V,result:z,fallbackSession:M})},reportSectionError:(V)=>{G.reportSectionError({source:"section-runtime",error:V,timestamp:Date.now()})}}}),Z1=c(()=>{if(!A(S))return null;return{runtimeId:J,coordinator:A(S)}});function a6(q){let V=m6(q);if(V===A(i9))return;E(i9,V,!0),E(t7,A(t7)+1),E(b1,q,!0),V7("composition-changed",{composition:A(b1),version:A(t7)})}function m1(q){s9=q??G.getCompositionModel(),n9.schedule(()=>{a6(s9)})}function u1(q){if(!q)return;let V=f1.get(q);if(!V)return;for(let M of V)M();f1.delete(q)}function X0(){for(let q of e7.values())u1(q.element)}function Z0(q){if(u1(q.element),!A(S))return;let V=A(S).getServiceBundle().catalogResolver;f1.set(q.element,[V.registerOwner({owner:{kind:q.kind,itemId:q.itemId,canonicalItemId:q.canonicalItemId,assessmentId:A(X7),sectionId:A(e)},entity:q.item})])}function t6(){X0();for(let q of e7.values())Z0(q)}function j0(q){let M={...q.result?.eventDetail||q.fallbackSession,itemId:q.itemId,canonicalItemId:q.canonicalItemId||q.itemId,sourceRuntimeId:J};if(!q6({state:r9,itemId:q.itemId,payload:M}))return;V7("session-changed",M)}function e6(q){if(!(q instanceof HTMLElement))return!1;return i2(q,u9)?.runtimeId===J}function A7(q){return q.detail??null}function Q3(q,V){for(let M of V)q.addEventListener(M.name,M.handler);return()=>{for(let M of V)q.removeEventListener(M.name,M.handler)}}b(()=>{if(!A(x))return;if(K7()==="force"){E(G7,null);return}return P6(A(x),(q)=>{if(q.runtimeId===J)return;E(G7,q,!0)})}),b(()=>{let q=A(x);return h(()=>{if(!q){E(X,null);return}let V=G6(q,(M)=>{if(M.engine===A(X))return;E(X,M.engine,!0)});return()=>{V(),E(X,null)}})}),b(()=>{let q=A(S);if(!q)return;return h(()=>m8({ttsService:q.getServiceBundle().ttsService,listenerId:`timed-media-audio-handoff:${J}`,silence:()=>G.requestMediaPauseForCompetingAudio()}))}),b(()=>{let q=K7()!=="force"&&A(G7)?A(G7).runtimeId:null,V=q?"inherited":"owned";if(V!==g9)g9=V,V7(V==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:J,parentRuntimeId:q})}),b(()=>{let q=A(e),V=_()||"";B6(r9)});let Y3=c(()=>A(Z1)!==null),J3=c(()=>A(X1)!==null);b(()=>{if(!A(x)||!A(Y3))return;let q=h(()=>A(Z1));if(!q)return;return h7=new W6(A(x),{context:u9,initialValue:q}),h7.connect(),a7=new K6(A(x)),a7.attach(),()=>{a7?.detach(),a7=null,h7?.disconnect(),h7=null}}),b(()=>{if(!A(Z1))return;h7?.setValue(A(Z1))}),b(()=>{if(!A(x))return;A(x).setAttribute("data-item-player-type",A(E7).type),A(x).setAttribute("data-item-player-tag",A(E7).tagName),A(x).setAttribute("data-env-mode",String(A(h1)?.mode||"")),A(x).setAttribute("data-env-role",String(A(h1)?.role||""))}),b(()=>{if(!A(x)||!A(J3))return;let q=h(()=>A(X1));if(!q)return;return v7=new W6(A(x),{context:O6,initialValue:q}),v7.connect(),o7=new K6(A(x)),o7.attach(),()=>{o7?.detach(),o7=null,v7?.disconnect(),v7=null}}),b(()=>{if(A(X1))v7?.setValue(A(X1))}),b(()=>{return A(S),A(X7),A(e),t6(),()=>{X0()}}),b(()=>{if(!A(x))return;return s2({host:A(x),instrumentationProvider:A(m7),component:"pie-assessment-toolkit",eventMap:o2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:A(X7),sectionId:A(e),attemptId:_()||void 0}})}),b(()=>{s7(),n7(),r7(),F();let q=A(S);if(!q)return;if(q!==A(d))return;h(()=>{q.setPnpEnforcement(l6(r7(),F())),q.updateAssessment(s7()),q.updateCurrentItemRef(n7())})}),b(()=>{if(!A(S))return;return A(S).subscribeTelemetry(({eventName:q,payload:V})=>{if(!a2(A(m7)))return;if(!A(m7).isReady())return;let M=q,z=new Date().toISOString(),H={...V||{},instrumentationLayer:"toolkit",assessmentId:A(X7),sectionId:A(e),attemptId:_()||void 0,component:"pie-assessment-toolkit",sourceEventName:q,timestamp:z};A(m7).trackEvent(M,H);let I=V&&typeof V.errorType==="string"?V.errorType:void 0;if(!q.endsWith("-error")&&!I)return;let Q7=V&&typeof V.message==="string"?V.message:`Toolkit telemetry error: ${q}`;A(m7).trackError(Error(Q7),{component:"pie-assessment-toolkit",errorType:I||"ToolkitTelemetryError",...H})})}),b(()=>{if(!K()||!A(S))return;let q=!1;if(A(S)===h(()=>A(d)))y1=!0;return G.initialize({coordinator:A(S),section:K(),sectionId:A(e),assessmentId:A(X7),attemptId:_()||void 0,view:A(o6),createDefaultController:g6,onCompositionChanged:(V)=>{if(q)return;m1(V)},onControllerEvent:(V)=>{if(q)return;S6(V),b6(V)}}).then(()=>{if(q)return;V7("toolkit-ready",{runtimeId:J,assessmentId:A(X7),sectionId:A(e),itemPlayer:A(E7),coordinator:A(S)}),V7("section-ready",{sectionId:A(e)}),h(()=>{E(k1,!0)})}).catch((V)=>{if(q)return;h(()=>{if(!A(t))E(t,!0),n.enter("engine-ready","skipped");n.enter("interactive","failed")}),G.reportSectionError({source:"section-runtime",error:V,timestamp:Date.now()}),R7({kind:"runtime-init",source:"pie-assessment-toolkit",error:V})}),()=>{q=!0}}),b(()=>{if(!A(x))return;let q=A(x),V=(z)=>{if(!e6(z.target))return!1;return z.stopPropagation(),!0};return Q3(q,[{name:p8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.element||!H?.itemId)return;let I=G.register(H);if(e7.set(H.element,H),Z0(H),G.handleContentRegistered(H),I)m1()}},{name:g8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;let I=H?.element?G.unregister(H.element):!1;if(u1(H.element),H.element)e7.delete(H.element);if(G.handleContentUnregistered(H),I)m1()}},{name:c8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;let I=G.updateItemSession(H.itemId,H.session);j0({itemId:H.itemId,canonicalItemId:G.getCanonicalItemId(H.itemId),result:I,fallbackSession:H.session})}},{name:d8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;G.handleContentLoaded({itemId:H.itemId,canonicalItemId:H.canonicalItemId,contentKind:H.contentKind,detail:H.detail,timestamp:Date.now()})}},{name:l8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;G.handleItemPlayerError({itemId:H.itemId,canonicalItemId:H.canonicalItemId,contentKind:H.contentKind,error:H.error,timestamp:Date.now()})}},{name:i8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.itemId)return;if(H.action!=="check"&&H.action!=="retry")return;G.handleFormativeAction({itemId:H.canonicalItemId||H.itemId,action:H.action,outcomes:H.outcomes})}},{name:s8,handler:(z)=>{if(!V(z))return;let H=A7(z);if(!H?.renderableId)return;if(H.action!=="attach"&&H.action!=="detach")return;G.handleMediaTimeSource({renderableId:H.renderableId,action:H.action,source:H.source,origin:H.origin})}}])});async function G3(){if(!A(S))throw Error("Coordinator not initialized");await A(S).waitUntilReady()}function X3(){if(!A(S))throw Error("Coordinator not initialized");return A(S).getServiceBundle()}function Z3(q){if(!A(S))throw Error("Coordinator not initialized");A(S).setHooks(q)}function j3(q){return G.navigateToItem(q)}function B3(){return G.getCompositionModel()}function q3(){return A(E7)}async function W3(){await G.persist()}async function K3(){await G.hydrate()}b(()=>{return()=>{h(()=>{if(n.getCurrent()!==null)n.enter("disposed")})}}),b(()=>{let q=`${U()}|${_()}`;h(()=>{if(q===A(o9))return;if(n.getCurrent()!==null)n.enter("disposed");n.reset({sectionId:U()||void 0,attemptId:_()||void 0}),E(o9,q),E(Q1,!1),E(t,!1),E(x1,!1),E(k1,!1)})}),b(()=>{let q=A(t)&&A(k1);h(()=>{if(!q)return;if(A(x1))return;E(x1,!0),n.enter("interactive")})}),b(()=>{let q=A(t7)>0||A(b1)!==null;h(()=>{if(!A(Q1)&&q)E(Q1,!0),n.enter("composed")})}),b(()=>{if(!A(S))return;if(!A(Q1))return;if(A(t))return;let q=A(S),V=!1;return q.waitUntilReady().then(()=>{if(V)return;h(()=>{if(A(t))return;E(t,!0),n.enter("engine-ready")})}).catch(()=>{if(V)return;h(()=>{if(A(t))return;E(t,!0),n.enter("engine-ready","failed")})}),()=>{V=!0}}),b(()=>{return()=>{n9.cancel(),G.dispose().catch((q)=>{R7({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:q,recoverable:!0})}).then(()=>Y1()).catch(J1).finally(()=>{j.dispose()})}});var U3={waitUntilReady:G3,getServiceBundle:X3,setHooks:Z3,navigateToItem:j3,getCompositionModel:B3,getItemPlayerConfig:q3,persist:W3,hydrate:K3,get assessmentId(){return W()},set assessmentId(q){W(q),y()},get section(){return K()},set section(q){K(q),y()},get sectionId(){return U()},set sectionId(q){U(q),y()},get attemptId(){return _()},set attemptId(q){_(q),y()},get env(){return $()},set env(q){$(q),y()},get ndsIcons(){return N()},set ndsIcons(q){N(q),y()},get locale(){return D()},set locale(q){D(q),y()},get lazyInit(){return O()},set lazyInit(q){O(q),y()},get toolConfigStrictness(){return P()},set toolConfigStrictness(q){P(q),y()},get tools(){return F()},set tools(q){F(q),y()},get toolContextResolvers(){return L()},set toolContextResolvers(q){L(q),y()},get enabledTools(){return C()},set enabledTools(q){C(q),y()},get toolRegistry(){return v()},set toolRegistry(q){v(q),y()},get accessibility(){return k()},set accessibility(q){k(q),y()},get player(){return p()},set player(q){p(q),y()},get playerType(){return R()},set playerType(q){R(q),y()},get coordinator(){return g()},set coordinator(q){g(q),y()},get createSectionController(){return B7()},set createSectionController(q){B7(q),y()},get onFrameworkError(){return q7()},set onFrameworkError(q){q7(q),y()},get errorRenderer(){return W7()},set errorRenderer(q){W7(q),y()},get onStageChange(){return w7()},set onStageChange(q){w7(q),y()},get assessment(){return s7()},set assessment(q){s7(q),y()},get currentItemRef(){return n7()},set currentItemRef(q){n7(q),y()},get pnpEnforcement(){return r7()},set pnpEnforcement(q){r7(q),y()},get isolation(){return K7()},set isolation(q){K7(q),y()}},B0=J4(),q0=m9(B0);M6(q0,(q)=>E(k7,q),()=>A(k7));var V3=w1(q0,2);{var A3=(q)=>{var V=Y4(),M=_6(V),z=L1(M,!0),H=w1(M,2),I=L1(H,!0),Q7=w1(H,2),j1=L1(Q7,!0);U6(V),$6((p1)=>{E1(z,A(S1)),E1(I,A(o).message),E1(j1,p1)},[()=>A(C1).join(`
|
|
225
|
-
`)]),
|
|
222
|
+
`;for(let G of X)Y+=`- ${G.rule}: ${G.reason}
|
|
223
|
+
`}return Y}function f3(Z){let{request:Q,tools:J,pnpPolicy:Y,customSources:X,contextId:G}=Z,j=new U8(G);j.addSource("host",{id:Q.scope.scopeId,name:`${Q.level}:${Q.scope.scopeId}`,config:{placement:J.placement,policy:J.policy}});let B=h9(J.placement[Q.level]),U=h9(J.policy.allowed),q=new Set(h9(J.policy.blocked)),K=[];for(let F of B)K.push(F),j.addDecision({precedence:0,rule:"placement-membership",featureId:F,action:"skip",sourceType:"host",reason:`Listed in tools.placement.${Q.level}`});if(K=K.filter((F)=>{if(J.providers?.[F]?.enabled===!1)return j.addDecision({precedence:0,rule:"provider-disabled",featureId:F,action:"block",sourceType:"host",reason:`tools.providers.${F}.enabled === false`,value:!1}),!1;return!0}),U.length>0){let F=new Set(U);K=K.filter((w)=>{if(!F.has(w))return j.addDecision({precedence:0,rule:"host-allowlist",featureId:w,action:"block",sourceType:"host",reason:"Not present in tools.policy.allowed",value:U}),!1;return!0})}K=K.filter((F)=>{if(q.has(F))return j.addDecision({precedence:0,rule:"host-blocked",featureId:F,action:"block",sourceType:"host",reason:"Listed in tools.policy.blocked",value:J.policy.blocked}),!1;return!0});let $=[],D=new Set(K),z=null;if(Y.enforcement==="on"&&Y.source&&(Y.assessment||Y.item)){if(z=Y.source.apply({assessment:Y.assessment,item:Y.item}),z.sources.assessment)j.addSource("assessment",z.sources.assessment);if(z.sources.student)j.addSource("student",z.sources.student);if(z.sources.item)j.addSource("item",z.sources.item);for(let F of z.decisions)j.addDecision({precedence:F.precedence,rule:F.rule,featureId:F.featureId,action:F.action,sourceType:F.sourceType,reason:F.reason,value:F.value});for(let[F,w]of z.unmappedSupportIds)$.push(V8(F,w,Q.level));for(let[F,w]of z.blockedOverrides)$.push(K8(F,w,Q.level));K=K.filter((F)=>{return!z.blockedToolIds.has(F)});for(let F of z.mandatedToolIds){if(!!D.has(F))continue;let b=z.perToolFlags.get(F)?.rule??"required-tool",S=d4(F,{placement:B,allowed:U,blocked:q,providers:J.providers}),h={rule:b,hostRule:S.hostRule,hostValue:S.hostValue};$.push({code:"tool-policy.requiredToolBlocked",level:Q.level,toolId:F,message:`Profile policy mandates "${F}" (${b}) but host policy removed it from level "${Q.level}" via ${S.hostRule}.`,details:h}),j.addDecision({precedence:0,rule:"required-tool-blocked",featureId:F,action:"advisory",sourceType:"host",reason:`Host removed required tool "${F}" via ${S.hostRule}`,value:h})}}for(let F=0;F<X.length;F++){let w=X[F],R=K.slice(),b=w.refine({request:Q,candidates:R}),S=new Set(b.refinedCandidates);for(let C of b.refinedCandidates)if(!R.includes(C))$.push({code:"tool-policy.placementMissing",level:Q.level,toolId:C,message:`Custom source "${w.id}" tried to add tool "${C}" that was not in candidates; ignored.`,details:{customSourceId:w.id}}),S.delete(C);K=R.filter((C)=>S.has(C));let h=new Set;if(b.decisions){for(let C of b.decisions)if(j.addDecision({precedence:C.precedence??100+F,rule:C.rule,featureId:C.featureId,action:C.action,sourceType:C.sourceType,reason:C.reason,value:C.value}),C.action==="block")h.add(C.featureId)}for(let C of R){if(S.has(C))continue;if(h.has(C))continue;j.addDecision({precedence:100+F,rule:"custom-source",featureId:C,action:"block",sourceType:"custom",reason:`Custom policy source "${w.id}" removed tool "${C}" from candidates without emitting a decision; auto-logged for trail completeness.`,value:{customSourceId:w.id}})}}for(let F of K)for(let w of Z.unappliedItems??[]){let R=["restrictedTools","requiredTools"].filter((S)=>w.settings[S]?.includes(F)===!0);if(R.length===0)continue;let b={itemId:w.id,settings:R,toolbarLevel:Q.scope.level};$.push({code:"tool-policy.itemSettingNotApplied",level:Q.level,toolId:F,message:`Item "${w.id}" names "${F}" in ${R.join(" and ")}, but "${F}" is on the ${Q.scope.level}-level toolbar, which item settings do not reach. Place "${F}" at item level to enforce the setting per item.`,details:b})}let M=new Set(K),O=K.map((F)=>{let w=z?.perToolFlags.get(F);return{toolId:F,required:w?.required??!1,alwaysAvailable:w?.alwaysAvailable??!1,settings:w?.settings}});return j.reconcileFinalStates(M),{visibleTools:O,diagnostics:$,provenance:j.build()}}function d4(Z,Q){if(!Q.placement.includes(Z))return{hostRule:"placement-missing",hostValue:Q.placement};if(Q.providers?.[Z]?.enabled===!1)return{hostRule:"provider-disabled",hostValue:!1};if(Q.allowed.length>0&&!Q.allowed.includes(Z))return{hostRule:"host-allowlist",hostValue:Q.allowed};if(Q.blocked.has(Z))return{hostRule:"host-blocked",hostValue:Array.from(Q.blocked)};return{hostRule:"placement-missing",hostValue:Q.placement}}var I3={"district-block":"settings.districtPolicy.blockedTools","test-admin-override":"settings.testAdministration.toolOverrides","item-restriction":"item settings.restrictedTools","pnp-prohibited":"personalNeedsProfile.prohibitedSupports","item-requirement":"item settings.requiredTools","district-requirement":"settings.districtPolicy.requiredTools","pnp-support":"personalNeedsProfile.supports"};function K8(Z,Q,J){return{code:"tool-policy.overrideBlocked",...J?{level:J}:{},toolId:Z,message:`settings.testAdministration.toolOverrides grants "${Z}", but ${I3[Q]} withdraws it and outranks a granting override.`,details:{rule:Q}}}function V8(Z,Q,J){let Y=Q.map((X)=>I3[X]).join(", ");return{code:"tool-policy.unknownSupportId",...J?{level:J}:{},toolId:Z,message:`No tool is registered under "${Z}", named in ${Y}, so it matches nothing. These lists name tools by tool id.`,details:{origins:[...Q]}}}var l4=(Z)=>`No assessment is bound, so no policy source could grant "${Z}"`;function q8(Z,Q,J,Y){return{featureId:Z,granted:!1,action:"block",rule:Q,precedence:0,sourceType:"host",reason:Q==="host-blocked"?"Listed in tools.policy.blocked":`Not listed in tools.policy.allowed (${J.join(", ")})`,required:!1,assessmentBound:Y.assessmentBound,diagnostics:[]}}function v3(Z,Q,J){let Y=Q.decisions[0],X=Array.from(Q.perToolFlags.values())[0],G=Y?.action==="enable",j=Y?.reason??`Feature "${Z}" not configured`;return{featureId:Z,granted:G,action:Y?.action??"skip",rule:Y?.rule??"pnp-support",precedence:Y?.precedence??8,sourceType:Y?.sourceType??"system",reason:J.assessmentBound||G?j:l4(Z),required:Boolean(X?.required),parameters:X?.settings,assessmentBound:J.assessmentBound,diagnostics:[...Array.from(Q.unmappedSupportIds,([B,U])=>V8(B,U)),...Array.from(Q.blockedOverrides,([B,U])=>K8(B,U))]}}function i4(Z){if(!Z)return!1;let Q=Z.personalNeedsProfile;if(Q){if(Array.isArray(Q.supports)&&Q.supports.length>0)return!0;if(Array.isArray(Q.prohibitedSupports)&&Q.prohibitedSupports.length>0)return!0}let J=Z.settings;if(J){let Y=J.districtPolicy;if(Y){if(Array.isArray(Y.blockedTools)&&Y.blockedTools.length>0)return!0;if(Array.isArray(Y.requiredTools)&&Y.requiredTools.length>0)return!0}let X=J.testAdministration?.toolOverrides;if(X&&typeof X==="object"&&Object.keys(X).length>0)return!0}return!1}function s4(Z){if(!Z)return!1;if(Array.isArray(Z.requiredTools)&&Z.requiredTools.length>0)return!0;if(Array.isArray(Z.restrictedTools)&&Z.restrictedTools.length>0)return!0;if(Z.toolParameters&&typeof Z.toolParameters==="object"&&Object.keys(Z.toolParameters).length>0)return!0;return!1}function h3(Z){if(i4(Z.assessment))return"on";if(s4(Z.itemSettings))return"on";return"off"}class p0{id="pnp";toolRegistry;constructor(Z){this.toolRegistry=Z}apply(Z){let{ctx:Q,result:J}=this.prepare(Z),{pnp:Y,districtPolicy:X,testAdmin:G,itemSettings:j}=Q,B=new Set;Y?.supports?.forEach((U)=>B.add(U)),Y?.prohibitedSupports?.forEach((U)=>B.add(U)),X?.blockedTools?.forEach((U)=>B.add(U)),X?.requiredTools?.forEach((U)=>B.add(U));for(let U of Object.keys(G?.toolOverrides??{}))B.add(U);j?.requiredTools?.forEach((U)=>B.add(U)),j?.restrictedTools?.forEach((U)=>B.add(U));for(let U of B)this.resolveSupport(U,Q,J);return J}resolveFeature(Z,Q){let{ctx:J,result:Y}=this.prepare(Q);return this.resolveSupport(Z,J,Y),Y}prepare(Z){let{assessment:Q,item:J}=Z,Y=Q?.personalNeedsProfile,X=Q?.settings,G=J?.settings,j={blockedToolIds:new Set,mandatedToolIds:new Set,perToolFlags:new Map,decisions:[],unmappedSupportIds:this.unmappedIds(Y,X,G),blockedOverrides:new Map,sources:{}};if(X?.districtPolicy||X?.testAdministration)j.sources.assessment={id:Q?.id||"unknown",name:Q?.name||Q?.id||"Assessment",config:X};if(Y)j.sources.student={id:"student",name:"Student PNP Profile",config:Y};if(J)j.sources.item={id:J.id,name:J.id,config:J.settings};return{ctx:{pnp:Y,districtPolicy:X?.districtPolicy,testAdmin:X?.testAdministration,itemSettings:G,toolConfigs:X?.toolConfigs},result:j}}resolveSupport(Z,Q,J){if(Q.districtPolicy?.blockedTools?.includes(Z)){J.blockedToolIds.add(Z),J.decisions.push({precedence:1,rule:"district-block",featureId:Z,action:"block",sourceType:"assessment",reason:`District policy blocks "${Z}" for all assessments`,value:Q.districtPolicy.blockedTools});return}let Y=Q.testAdmin?.toolOverrides?.[Z];if(Y===!1){J.blockedToolIds.add(Z),J.decisions.push({precedence:2,rule:"test-admin-override",featureId:Z,action:"block",sourceType:"assessment",reason:`Test administrator disabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(Q.itemSettings?.restrictedTools?.includes(Z)){if(J.blockedToolIds.add(Z),Y===!0)J.blockedOverrides.set(Z,"item-restriction");J.decisions.push({precedence:3,rule:"item-restriction",featureId:Z,action:"block",sourceType:"item",reason:`Item restricts "${Z}" (e.g., mental math question blocks calculator)`,value:Q.itemSettings.restrictedTools});return}if(Q.pnp?.prohibitedSupports?.includes(Z)){if(J.blockedToolIds.add(Z),Y===!0)J.blockedOverrides.set(Z,"pnp-prohibited");J.decisions.push({precedence:4,rule:"pnp-prohibited",featureId:Z,action:"block",sourceType:"student",reason:`Student PNP profile prohibits "${Z}"`,value:Q.pnp.prohibitedSupports});return}if(Y===!0){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Z,Q),rule:"test-admin-override"}),J.decisions.push({precedence:5,rule:"test-admin-override",featureId:Z,action:"enable",sourceType:"assessment",reason:`Test administrator enabled "${Z}" for this session`,value:Q.testAdmin?.toolOverrides});return}if(Q.itemSettings?.requiredTools?.includes(Z)){J.mandatedToolIds.add(Z),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Z,Q),rule:"item-requirement"}),J.decisions.push({precedence:6,rule:"item-requirement",featureId:Z,action:"enable",sourceType:"item",reason:`Item requires "${Z}" for this question`,value:Q.itemSettings.requiredTools});return}if(Q.districtPolicy?.requiredTools?.includes(Z)){J.mandatedToolIds.add(Z),J.perToolFlags.set(Z,{required:!0,alwaysAvailable:!1,settings:this.resolveToolSettings(Z,Q),rule:"district-requirement"}),J.decisions.push({precedence:7,rule:"district-requirement",featureId:Z,action:"enable",sourceType:"assessment",reason:`District policy requires "${Z}" for all assessments`,value:Q.districtPolicy.requiredTools});return}if(Q.pnp?.supports?.includes(Z)){J.perToolFlags.set(Z,{required:!1,alwaysAvailable:!0,settings:this.resolveToolSettings(Z,Q),rule:"pnp-support"}),J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"enable",sourceType:"student",reason:`Student PNP profile requests "${Z}"`,value:Q.pnp.supports});return}J.decisions.push({precedence:8,rule:"pnp-support",featureId:Z,action:"skip",sourceType:"system",reason:`Feature "${Z}" not configured at any level`,value:{supportId:Z}})}unmappedIds(Z,Q,J){let Y=new Map;if(this.toolRegistry.getAllTools().length===0)return Y;let X=[["district-block",Q?.districtPolicy?.blockedTools],["test-admin-override",Object.keys(Q?.testAdministration?.toolOverrides??{})],["item-restriction",J?.restrictedTools],["pnp-prohibited",Z?.prohibitedSupports],["item-requirement",J?.requiredTools],["district-requirement",Q?.districtPolicy?.requiredTools],["pnp-support",Z?.supports]];for(let[G,j]of X)for(let B of j??[]){if(this.toolRegistry.has(B))continue;let U=Y.get(B)??[];if(!U.includes(G))U.push(G);Y.set(B,U)}return Y}resolveToolSettings(Z,Q){return Q.itemSettings?.toolParameters?.[Z]??Q.toolConfigs?.[Z]}}var m3=c9({policy:{allowed:[],blocked:[]},placement:{section:[],item:[],passage:[]},providers:{}});class g0{toolRegistry;contextId;pnpPolicySource;customSources;listeners=new Set;tools;assessment;pnpEnforcementOverride;itemSettings=new Map;disposed=!1;constructor(Z){this.toolRegistry=Z.toolRegistry,this.contextId=Z.contextId??"tool-policy",this.pnpPolicySource=new p0(this.toolRegistry),this.customSources=Z.customSources?[...Z.customSources]:[];let Q=Z.inputs??{};this.tools=Q.tools??m3,this.assessment=Q.assessment??null,this.pnpEnforcementOverride=Q.pnpEnforcement??null}decide(Z){this.assertNotDisposed();let Q=Z.scope.scopeId?`${this.contextId}:${Z.level}:${Z.scope.scopeId}`:`${this.contextId}:${Z.level}`,J=Z.level==="item"?this.itemForScope(Z.scope):void 0,Y=Z.level!=="item"||Z.scope.level==="section"||Z.scope.level==="assessment";return f3({request:Z,tools:this.tools,pnpPolicy:{source:this.pnpPolicySource,assessment:this.assessment??void 0,item:J,enforcement:this.enforcementFor(J)},unappliedItems:Y?this.enforcedItems():void 0,customSources:this.customSources,contextId:Q})}grantsFeatureAnywhere(Z){if(this.decideFeature(Z).granted)return!0;for(let Q of this.itemSettings.keys())if(this.decideFeature(Z,{level:"item",scopeId:Q}).granted)return!0;return!1}registerItemSettings(Z,Q){this.assertNotDisposed();let J={settings:Q},Y=this.itemSettingsFor(Z),X=this.itemSettings.get(Z)??[];return X.push(J),this.itemSettings.set(Z,X),this.emitIfItemSettingsChanged(Z,Y),()=>{if(this.disposed)return;let G=this.itemSettings.get(Z),j=G?.indexOf(J)??-1;if(!G||j<0)return;let B=this.itemSettingsFor(Z);if(G.splice(j,1),G.length===0)this.itemSettings.delete(Z);this.emitIfItemSettingsChanged(Z,B)}}decideFeature(Z,Q){this.assertNotDisposed();let J=this.hostFeatureGate(Z);if(J)return J;return v3(Z,this.pnpPolicySource.resolveFeature(Z,{assessment:this.assessment??void 0,item:this.itemForScope(Q)}),{assessmentBound:this.assessment!==null})}hostFeatureGate(Z){let Q={assessmentBound:this.assessment!==null},J=h9(this.tools.policy.blocked);if(J.includes(Z))return q8(Z,"host-blocked",J,Q);let Y=h9(this.tools.policy.allowed);if(Y.length>0&&!Y.includes(Z))return q8(Z,"host-allowlist",Y,Q);return null}getVisibleToolIds(Z,Q){return this.decide({level:Z,scope:{level:Z,scopeId:Q}}).visibleTools.map((J)=>J.toolId)}updateInputs(Z){this.assertNotDisposed();let Q=!1,J=!1;if("tools"in Z){let Y=Z.tools??m3;if(!Object.is(this.tools,Y))this.tools=Y,Q=!0}if("assessment"in Z){let Y=Z.assessment??null;if(!t9(this.assessment,Y))Q=!0;this.assessment=Y}if("pnpEnforcement"in Z){let Y=Z.pnpEnforcement??null;if(this.pnpEnforcementOverride!==Y)this.pnpEnforcementOverride=Y,J=!0}if(Q||J)this.emit({reason:J&&!Q?"pnp-enforcement":"inputs",inputs:this.snapshotInputs()})}replaceToolRegistry(Z,Q){this.assertNotDisposed(),this.toolRegistry=Z,this.pnpPolicySource=new p0(Z),this.tools=Q,this.emit({reason:"inputs",inputs:this.snapshotInputs()})}registerPolicySource(Z){return this.assertNotDisposed(),this.customSources.push(Z),this.emit({reason:"policy-source-added",inputs:this.snapshotInputs()}),()=>{let Q=this.customSources.indexOf(Z);if(Q!==-1){if(this.customSources.splice(Q,1),!this.disposed)this.emit({reason:"policy-source-removed",inputs:this.snapshotInputs()})}}}onPolicyChange(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}getInputs(){return this.snapshotInputs()}dispose(){if(this.disposed)return;this.disposed=!0,this.emit({reason:"disposed",inputs:this.snapshotInputs()}),this.listeners.clear(),this.itemSettings.clear(),this.customSources.length=0}snapshotInputs(){return Object.freeze({tools:this.tools,assessment:this.assessment,pnpEnforcement:this.enforcementFor(),pnpEnforcementOverride:this.pnpEnforcementOverride})}enforcementFor(Z){return this.pnpEnforcementOverride??h3({assessment:this.assessment,itemSettings:Z?.settings})}itemSettingsFor(Z){return this.itemSettings.get(Z)?.at(-1)?.settings}emitIfItemSettingsChanged(Z,Q){if(t9(Q,this.itemSettingsFor(Z)))return;this.emit({reason:"item-settings",inputs:this.snapshotInputs()})}itemForScope(Z){if(Z?.level!=="item")return;let Q=Z.canonicalItemId||Z.itemId||Z.scopeId,J=Q?this.itemSettingsFor(Q):void 0;return J?{id:Q,settings:J}:void 0}enforcedItems(){let Z=[];for(let Q of this.itemSettings.keys()){let J=this.itemSettingsFor(Q);if(!J)continue;let Y={id:Q,settings:J};if(this.enforcementFor(Y)==="on")Z.push(Y)}return Z}emit(Z){for(let Q of Array.from(this.listeners))try{Q(Z)}catch{}}assertNotDisposed(){if(this.disposed)throw Error("ToolPolicyEngine has been disposed.")}}import{hasResponseField as n4,hasResponseValue as u3}from"@pie-players/pie-players-shared/pie";function e9(Z){return Boolean(Z)&&typeof Z==="object"&&!Array.isArray(Z)}function c0(Z){return e9(Z)&&e9(Z.session)?Z.session:Z}function r4(Z,Q){let J=e9(Z)?Z:{},Y=e9(Q)?Q:{},X=new Set([...Object.keys(J),...Object.keys(Y)]);for(let G of X)if(!t9(c0(J[G]),c0(Y[G])))return!1;return!0}function o4(Z,Q){for(let[J,Y]of Object.entries(Z)){if(Y===void 0)continue;if(J==="itemSessions"){if(!r4(Y,Q.itemSessions))return!1;continue}if(!t9(Y,Q[J]))return!1}return!0}function d0(Z,Q){if(!Z)return Q;let J=e9(Q.itemSessions)?{...Q.itemSessions}:{},Y=e9(Z.itemSessions)?Z.itemSessions:{};for(let[G,j]of Object.entries(Y)){if(!u3(c0(j)))continue;let B=c0(J[G]);if(u3(B)||n4(B))continue;J[G]=j}let X={...Q,itemSessions:J};return o4(X,Z)?null:X}class l extends Error{constructor(){super("ToolkitCoordinator has been disposed.");this.name="ToolkitCoordinatorDisposedError"}}class l0 extends Error{constructor(){super("Section controller acquisition was retired during initialization.");this.name="SectionControllerRetiredError"}}var p3=(Z)=>!!Z&&typeof Z==="object"&&!Array.isArray(Z),a4=(Z,Q,J)=>{let Y={...Q,...J};if(Z==="textToSpeech"&&p3(Q.mathSpeech)&&p3(J.mathSpeech))Y.mathSpeech={...Q.mathSpeech,...J.mathSpeech};return Y},t4=["item-selected","item-session-data-changed","item-session-meta-changed","item-complete-changed","content-loaded","item-player-error"],e4=["section-navigation-change","section-session-applied","section-loading-complete","section-items-complete-changed","section-error","timed-media-cue-changed","timed-media-policy-degraded","timed-media-invalid"];class A8{assessmentId;config;ttsService;toolCoordinator;highlightCoordinator;elementToolStateStore;catalogResolver;toolProviderRegistry;hooks;lazyInit;ttsInitialized=!1;ttsDegraded=!1;ttsInitPromise;ttsReconfigurePromise;stateLoaded=!1;stateLoadSettled=!1;stateLoadPromise;coordinatorReadyPromise;coordinatorReadyNotified=!1;providerInitPromises=new Map;degradedTools=new Map;toolModuleFailures=new Set;readyChangeListeners=new Set;eagerInit;toolRegistry;toolRegistrySupplied;toolRegistrySettled;toolRegistryAbsent=!1;toolContextResolvers=new Map;toolContextResolverChangeListeners=new Set;toolRequests=new W8;sectionControllers=new Map;sectionControllerKeys=new Map;sectionControllerInitEntries=new Map;sectionControllerDisposePromises=new Map;sectionPersistenceStrategies=new Map;sectionControllerLifecycleListeners=new Set;activeSubscriptions=new Map;activeCohortMapKey=null;latestRequestedActiveCohortMapKey=null;telemetryListeners=new Set;frameworkErrorBus;ownsFrameworkErrorBus;frameworkErrorHookUnsubscribe=null;disposePromise=null;policyEngine;pnpEnforcementOverride=null;warnedPolicyDiagnostics=new Set;reportedUnboundFeaturePolicy=!1;reportedMissingTTSProvider=!1;heldMissingTTSProviderBackend=null;reportedRegistryUnavailable=!1;resolveConfig(Z){let Q=D1(Z.toolConfigStrictness),J=Z.toolRegistry??new $8,Y=Z.deferToolConfigValidation===!0?c9(Z.tools):this.validateToolsConfig(Z.tools,{strictness:Q,source:"ToolkitCoordinator.init",toolRegistry:J});return{...Z,toolConfigStrictness:Q,toolRegistry:J,tools:{...Y,providers:{...{textToSpeech:{enabled:!0,backend:"browser"},annotationToolbar:{enabled:!0}},...Y.providers}},accessibility:{language:"en-US",...Z.accessibility??{},catalogs:Z.accessibility?.catalogs??[]}}}validateToolsConfig(Z,Q){let{config:J,diagnostics:Y}=F1(Z,Q.toolRegistry),X=this.reportedRegistryUnavailable||this.toolRegistryPending()?Y.filter((G)=>G.code!=="tools.registryUnavailable"):Y;if(z1(X,Q),Q.strictness!=="off"&&X.some((G)=>G.code==="tools.registryUnavailable"))this.reportedRegistryUnavailable=!0;return J}constructor(Z){if(!Z.assessmentId)throw Error("ToolkitCoordinator requires assessmentId in config");this.toolRegistrySupplied=Z.toolRegistry!=null,this.toolRegistrySettled=this.toolRegistrySupplied;let Q=this.resolveConfig(Z);if(this.assessmentId=Q.assessmentId,this.config=Q,this.toolRegistry=Q.toolRegistry??new $8,this.installToolContextResolvers(Q.toolContextResolvers),this.hooks={...Q.hooks},this.lazyInit=Z.lazyInit===!0,this.eagerInit=Z.eagerInit??!this.lazyInit,this.pnpEnforcementOverride=this.resolveConfiguredPnpEnforcement(),this.frameworkErrorBus=Z.frameworkErrorBus??new B0,this.ownsFrameworkErrorBus=!Z.frameworkErrorBus,this.subscribeFrameworkErrorHookAdapters(),this.toolCoordinator=new g3,this.highlightCoordinator=new $0,this.elementToolStateStore=new R1,this.catalogResolver=new w1(Q.accessibility?.catalogs||[],Q.accessibility?.language||"en-US"),this.toolProviderRegistry=new u0,this._registerToolProviders(),this.ttsService=new J8,this.ttsService.setHighlightCoordinator(this.highlightCoordinator),this.ttsService.setReadinessGate(()=>this.ensureTTSReady()),this.ttsService.setMathSpeechSource(()=>B8(G8(this.resolveTTSToolConfig())).providerOptions?.mathSpeech),this.setupStatePersistenceHooks(),this.policyEngine=new g0({toolRegistry:this.toolRegistry,contextId:`toolkit-coordinator:${this.assessmentId}`,inputs:{tools:this.config.tools,assessment:null,pnpEnforcement:this.pnpEnforcementOverride}}),this.policyEngine.onPolicyChange((J)=>{if(J.reason!=="disposed")this.reportNewlyGrantedFailures()}),this.eagerInit)this.waitUntilReady().catch((J)=>{if(J instanceof l)return;console.error("[ToolkitCoordinator] Failed eager initialization:",J),this.handleError(J,{phase:"coordinator-ready",recoverable:!1})})}assertNotDisposed(){if(this.disposePromise!==null)throw new l}subscribeFrameworkErrorHookAdapters(){this.frameworkErrorHookUnsubscribe=this.frameworkErrorBus.subscribeFrameworkErrors((Z)=>{let Q=this.hooks.onFrameworkError;if(!Q)return;try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] onFrameworkError hook failed:",J)}})}async emitTelemetry(Z,Q){try{await this.hooks.onTelemetry?.(Z,Q)}catch(Y){console.warn("[ToolkitCoordinator] telemetry hook failed:",Y)}let J=Q?{...Q}:void 0;for(let Y of this.telemetryListeners)try{Y({eventName:Z,payload:J?{...J}:void 0})}catch(X){console.warn("[ToolkitCoordinator] telemetry listener failed:",X)}}emitSectionControllerLifecycle(Z){for(let Q of this.sectionControllerLifecycleListeners)try{Q(Z)}catch(J){console.warn("[ToolkitCoordinator] section controller lifecycle listener failed:",J)}}handleError(Z,Q,J="runtime"){let Y=s8({error:Z,context:Q,recoverable:Q.recoverable,scope:J});this.frameworkErrorBus.reportFrameworkError(Y)}isToolGranted(Z){try{return this.policyEngine.grantsFeatureAnywhere(Z)}catch{return!1}}reportToolFailure(Z,Q,J,Y=!1){let X=Array.from(J),G=Y||!X.some((j)=>this.isToolGranted(j));if(G&&!Y)for(let j of X)this.degradedTools.set(j,{error:Z,context:Q});this.handleError(Z,{...Q,recoverable:G})}reportToolModuleFailure(Z,Q){if(this.toolRequests.notifyTargetsChange(),this.toolModuleFailures.has(Z))return;this.toolModuleFailures.add(Z);let J=Q instanceof Error&&Q.message.trim().length>0?Q.message:String(Q);this.reportToolFailure(Error(`Tool "${Z}" failed to load: ${J}`,{cause:Q}),{phase:"tool-module-load",details:{toolId:Z}},[Z])}reportNewlyGrantedFailures(){for(let[Z,Q]of this.degradedTools){if(!this.isToolGranted(Z))continue;this.degradedTools.delete(Z),this.handleError(Q.error,{...Q.context,recoverable:!1})}}onReadyChange(Z){return this.readyChangeListeners.add(Z),()=>{this.readyChangeListeners.delete(Z)}}notifyReadyChange(){for(let Z of this.readyChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] ready-change listener failed:",Q)}}subscribeFrameworkErrors(Z){return this.frameworkErrorBus.subscribeFrameworkErrors(Z)}reportFrameworkError(Z){this.frameworkErrorBus.reportFrameworkError(Z)}getSectionControllerMapKey(Z){return`${Z.assessmentId}::${Z.sectionId}::${Z.attemptId||""}`}createDefaultSectionPersistence(){let Z=(()=>{try{if(typeof window>"u")return null;return window.localStorage}catch{return null}})(),Q=(J)=>{let{assessmentId:Y,sectionId:X,attemptId:G}=J.key;if(!G)return null;return`pie:section-controller:v1:${Y}:${X}:${G}`};return{async loadSession(J){let Y=Q(J);if(!Z||!Y)return null;let X=Z.getItem(Y);if(!X)return null;try{return JSON.parse(X)}catch{return null}},async saveSession(J,Y){let X=Q(J);if(!Z||!X)return;Z.setItem(X,JSON.stringify(Y))},async clearSession(J){let Y=Q(J);if(!Z||!Y)return;Z.removeItem(Y)}}}async resolveSectionPersistence(Z){let Q=this.getSectionControllerMapKey(Z.key),J=this.sectionPersistenceStrategies.get(Q);if(J)return J;let Y={createDefaultPersistence:()=>this.createDefaultSectionPersistence()},X=await this.hooks.createSectionSessionPersistence?.(Z,Y)??await Y.createDefaultPersistence();return this.sectionPersistenceStrategies.set(Q,X),X}setupStatePersistenceHooks(){this.elementToolStateStore.setOnStateChange((Z)=>{if(!this.hooks.saveToolState)return;Promise.resolve(this.hooks.saveToolState(Z)).catch((Q)=>{this.handleError(Q,{phase:"state-save",recoverable:!0})})})}async ensureStateLoaded(){if(this.stateLoadSettled)return;if(this.stateLoadPromise)return this.stateLoadPromise;return this.stateLoadPromise=(async()=>{let Z=this.hooks.loadToolState;if(!Z)return;try{let Q=await Z();if(this.assertNotDisposed(),Q&&typeof Q==="object")this.elementToolStateStore.loadState(Q);this.stateLoaded=!0,this.stateLoadSettled=!0,await this.emitTelemetry("pie-toolkit-tool-state-loaded",{hasState:Boolean(Q)})}catch(Q){if(Q instanceof l)throw Q;this.stateLoadSettled=!0,this.handleError(Q,{phase:"state-load",recoverable:!0})}})().finally(()=>{this.stateLoadPromise=void 0,this.notifyReadyChange()}),this.stateLoadPromise}toolRegistryPending(){return!this.toolRegistrySettled&&!this.toolRegistryAbsent}reportMissingTTSProvider(Z){if(this.toolRegistryPending()){this.heldMissingTTSProviderBackend=Z;return}if(this.reportedMissingTTSProvider)return;this.reportedMissingTTSProvider=!0,console.warn(`[ToolkitCoordinator] Text-to-speech is configured for the "${Z}" backend but falls back to browser speech: no "textToSpeech" tool provider is registered. A coordinator registers tool providers only from its \`toolRegistry\`, or from its toolkit's when constructed without one, so supply one that carries the text-to-speech registration — for the packaged capability set, \`createPackagedToolRegistry()\` from "@pie-players/pie-default-tool-loaders". Reported once per coordinator.`)}adoptToolRegistry(Z){if(this.disposePromise!==null||this.toolRegistrySettled)return!1;if(!Z&&this.toolRegistryAbsent)return!1;let Q=this.heldMissingTTSProviderBackend;this.heldMissingTTSProviderBackend=null;let J=this.config.toolConfigStrictness??"error",Y="ToolkitCoordinator.adoptToolRegistry";if(!Z){if(this.toolRegistryAbsent=!0,this.validateToolsConfig(this.config.tools,{strictness:J,source:Y,toolRegistry:this.toolRegistry}),Q)this.reportMissingTTSProvider(Q);return!1}this.toolRegistrySettled=!0,this.toolRegistry=Z,this.config.toolRegistry=Z;try{this.config.tools=this.validateToolsConfig(this.config.tools,{strictness:J==="off"?"off":"warn",source:Y,toolRegistry:Z})}catch(G){console.warn("[ToolkitCoordinator] Tool config does not validate against the adopted tool registry:",G)}this.policyEngine.replaceToolRegistry(Z,this.config.tools);let X=this.ttsInitialized||this.ttsInitPromise!==void 0||this.ttsReconfigurePromise!==void 0;for(let G of this.getProviderDescriptorTools()){if(X&&G.toolId==="textToSpeech")continue;this.registerProviderFromTool(G)}if(X)this.scheduleTTSReconfigure();return!0}_registerToolProviders(){let Z=this.getProviderDescriptorTools();for(let Q of Z)this.registerProviderFromTool(Q)}getProviderDescriptorTools(){return this.toolRegistry.getAllTools().filter((Z)=>!!Z.provider)}async registerProviderFromTool(Z,Q=!1){let J=Z.provider;if(!J)return;let{toolId:Y}=Z,X;try{let G=this.getToolConfig(Y)||void 0;if(G?.enabled===!1){if(Q)this.toolProviderRegistry.unregister(Y);return}if(!Q&&this.toolProviderRegistry.has(Y))return;let j=J.createProvider(G),B=J.getInitConfig?.(G)??G?.provider?.init??{},U=this.addToolTelemetryReporter(Y,B),q=this.createToolTelemetryForwarder(Y),K=J.getAuthFetcher?.(G)??G?.provider?.runtime?.authFetcher;X={provider:j,config:U,lazy:J.lazy??!0,authFetcher:K,onTelemetry:q}}catch(G){this.reportProviderRegisterFailure(G,Y);return}await this.registerProvider(Y,X)}createToolTelemetryForwarder(Z){return async(Q,J)=>{await this.emitTelemetry(Q,{...J||{},toolId:Z})}}addToolTelemetryReporter(Z,Q){let J=Q&&typeof Q==="object"?{...Q}:{},Y=typeof J.onTelemetry==="function"?J.onTelemetry:null,X=this.createToolTelemetryForwarder(Z);return J.onTelemetry=async(G,j)=>{if(Y)await Y(G,j);await X(G,j)},J}async registerProvider(Z,Q){try{this.toolProviderRegistry.register(Z,Q);let J={providerName:Q.provider.providerName};await this.hooks.onProviderRegistered?.(Z,J),await this.emitTelemetry("pie-toolkit-provider-registered",{toolId:Z,providerName:Q.provider.providerName})}catch(J){this.reportProviderRegisterFailure(J,Z)}}reportProviderRegisterFailure(Z,Q){console.warn(`[ToolkitCoordinator] Failed to register the provider of tool "${Q}":`,Z),this.reportToolFailure(Z,{phase:"provider-register",toolId:Q},[Q])}async ensureProviderReady(Z){return this.initializeProvider(Z,!1)}async initializeProvider(Z,Q){this.assertNotDisposed();let J=this.providerInitPromises.get(Z);if(J)return J;let Y=(async()=>{try{let X=await this.toolProviderRegistry.getProvider(Z,!1);if(this.assertNotDisposed(),this.toolProviderRegistry.isInitialized(Z))return X;let G={providerName:X.providerName};return await this.hooks.onProviderInitStart?.(Z,G),this.assertNotDisposed(),await this.toolProviderRegistry.initialize(Z),this.assertNotDisposed(),X=await this.toolProviderRegistry.getProvider(Z,!1),await this.hooks.onProviderReady?.(Z,G),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-provider-ready",{toolId:Z}),this.assertNotDisposed(),X}catch(X){if(X instanceof l)throw X;let G=X instanceof Error?X:Error(String(X));throw this.reportToolFailure(G,{phase:"provider-init",toolId:Z},this.toolRegistry.get(Z)?.provider?[Z]:[],Q),G}})().finally(()=>{this.providerInitPromises.delete(Z)});return this.providerInitPromises.set(Z,Y),Y}setHooks(Z){if(Object.assign(this.hooks,Z),this.setupStatePersistenceHooks(),this.disposePromise===null&&Z.onCoordinatorReady&&this.isReady())Promise.resolve(Z.onCoordinatorReady(this)).catch((Q)=>{this.handleError(Q,{phase:"coordinator-ready",recoverable:!1})})}subscribeTelemetry(Z){return this.telemetryListeners.add(Z),()=>{this.telemetryListeners.delete(Z)}}getSectionController(Z){let Q={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId};return this.sectionControllers.get(this.getSectionControllerMapKey(Q))}subscribeSectionEvents(Z){if(this.activeCohortMapKey===null&&this.latestRequestedActiveCohortMapKey===null)throw Error("[ToolkitCoordinator] subscribeSectionEvents requires an active section cohort; call getOrCreateSectionController first.");let Q=this.activeSubscriptions.get(Z.listener);if(Q)Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null;let J={listener:Z.listener,eventTypes:Z.eventTypes,itemIds:Z.itemIds,unsubscribeCurrent:null};this.activeSubscriptions.set(Z.listener,J);let Y=this.activeCohortMapKey===null?void 0:this.sectionControllers.get(this.activeCohortMapKey);if(Y)this.bindSubscriptionToController(J,Y);let X=!1;return()=>{if(X)return;if(X=!0,J.unsubscribeCurrent?.(),J.unsubscribeCurrent=null,this.activeSubscriptions.get(Z.listener)===J)this.activeSubscriptions.delete(Z.listener)}}bindSubscriptionToController(Z,Q){Z.unsubscribeCurrent?.(),Z.unsubscribeCurrent=null;let J=Q.subscribe;if(typeof J!=="function")return;let Y=this.buildSectionEventPredicate(Z);Z.unsubscribeCurrent=J.call(Q,(j)=>{if(!Y(j))return;this.deliverSectionEventSafely(Z.listener,j)});let X=this.buildContentLoadedReplayEvents(Q);for(let j of X)if(Y(j))this.deliverSectionEventSafely(Z.listener,j);let G=this.buildLoadingCompleteReplayEvent(Q);if(G&&Y(G))this.deliverSectionEventSafely(Z.listener,G)}deliverSectionEventSafely(Z,Q){try{Z(Q)}catch(J){console.warn("[ToolkitCoordinator] section-event listener failed:",J)}}setActiveCohort(Z){if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=Z;let Q=this.sectionControllers.get(Z);if(!Q)return;for(let J of Array.from(this.activeSubscriptions.values()))this.bindSubscriptionToController(J,Q)}setActiveCohortIfLatestRequest(Z){if(this.latestRequestedActiveCohortMapKey!==Z)return;this.setActiveCohort(Z)}suspendActiveCohortIfSuperseded(Z){if(this.activeCohortMapKey===null)return;if(this.activeCohortMapKey===Z)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}clearActiveCohortIfMatches(Z){if(this.activeCohortMapKey!==Z)return;this.activeCohortMapKey=null;for(let Q of Array.from(this.activeSubscriptions.values()))Q.unsubscribeCurrent?.(),Q.unsubscribeCurrent=null}buildSectionEventPredicate(Z){let Q=Z.eventTypes?new Set(Z.eventTypes):null,J=Z.itemIds?new Set(Z.itemIds):null;return(Y)=>{if(Q||J){let X=Y?.type||null;if(Q&&(!X||!Q.has(X)))return!1;if(J){if(!Array.from(this.collectEventItemIds(Y)).some((j)=>J.has(j)))return!1}}return!0}}collectEventItemIds(Z){let Q=new Set;if("itemId"in Z&&typeof Z.itemId==="string")Q.add(Z.itemId);if("canonicalItemId"in Z&&typeof Z.canonicalItemId==="string")Q.add(Z.canonicalItemId);if("currentItemId"in Z&&typeof Z.currentItemId==="string")Q.add(Z.currentItemId);if("previousItemId"in Z&&typeof Z.previousItemId==="string")Q.add(Z.previousItemId);return Q}buildContentLoadedReplayEvents(Z){let Q=Z.getRuntimeState?.(),J=Q?.loadedRenderables;if(!Array.isArray(J)||J.length===0)return[];let Y=typeof Q?.currentItemIndex==="number"&&Number.isFinite(Q.currentItemIndex)?Q.currentItemIndex:0,X=Date.now(),G=[];for(let j of J){if(!j)continue;let B=j.itemId,U=typeof j.canonicalItemId==="string"&&j.canonicalItemId?j.canonicalItemId:B;if(typeof B!=="string"||!B)continue;G.push({type:"content-loaded",contentKind:j.contentKind??"unknown",itemId:B,canonicalItemId:U,currentItemIndex:Y,timestamp:X})}return G}buildLoadingCompleteReplayEvent(Z){let Q=Z.getRuntimeState?.();if(Q?.loadingComplete!==!0)return null;let J=typeof Q.totalRegistered==="number"&&Number.isFinite(Q.totalRegistered)?Math.max(0,Q.totalRegistered):0,Y=typeof Q.totalLoaded==="number"&&Number.isFinite(Q.totalLoaded)?Math.max(0,Q.totalLoaded):J;return{type:"section-loading-complete",totalRegistered:J,totalLoaded:Y,currentItemIndex:Q.currentItemIndex,timestamp:Date.now()}}subscribeItemEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||t4,itemIds:Z.itemIds,listener:Z.listener})}subscribeSectionLifecycleEvents(Z){return this.subscribeSectionEvents({eventTypes:Z.eventTypes||e4,listener:Z.listener})}onSectionControllerLifecycle(Z){return this.sectionControllerLifecycleListeners.add(Z),()=>{this.sectionControllerLifecycleListeners.delete(Z)}}async getOrCreateSectionController(Z){if(this.disposePromise!==null)throw new l;let Q={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId},J=this.getSectionControllerMapKey(Q);this.latestRequestedActiveCohortMapKey=J,this.suspendActiveCohortIfSuperseded(J);let Y;try{if(Y=await this.resolveExistingSectionController({mapKey:J,key:Q,input:Z.input,updateExisting:Z.updateExisting}),Y){if(this.disposePromise!==null)throw new l;if(Z.initialSession)await this.assignSessionToPublishedController(Y,Z.initialSession)}}catch(U){throw this.deliverSectionStartError(J,U),U}if(Y)return Y;let X=this.sectionControllerDisposePromises.get(J);if(X)await Promise.allSettled([X]);if(this.disposePromise!==null)throw new l;let G=this.sectionControllerInitEntries.get(J);if(G){if(!Z.initialSession)return G.promise;let U=await G.promise;return await this.assignSessionToPublishedController(U,Z.initialSession),U}let j={retired:!1,candidateClaimed:!1},B=this.initializeNewSectionController({args:Z,key:Q,mapKey:J,token:j}).catch((U)=>{throw this.handleSectionControllerInitError(U,Z),this.deliverSectionStartError(J,U),U}).finally(()=>{if(this.sectionControllerInitEntries.get(J)?.token===j)this.sectionControllerInitEntries.delete(J)});return this.sectionControllerInitEntries.set(J,{key:Q,token:j,promise:B}),B}async resolveExistingSectionController(Z){let Q=this.sectionControllers.get(Z.mapKey);if(!Q)return;if(this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.updateExisting!==!1)await Q.updateInput?.(Z.input);if(this.sectionControllers.get(Z.mapKey)!==Q)return;return this.setActiveCohortIfLatestRequest(Z.mapKey),Q}createSectionControllerContext(Z){return{key:Z.key,coordinator:this,input:Z.input}}async initializeNewSectionController(Z){let Q=this.createSectionControllerContext({key:Z.key,input:Z.args.input}),J=await this.resolveSectionPersistence(Q);if(this.disposePromise!==null||Z.token.retired){if(this.sectionPersistenceStrategies.get(Z.mapKey)===J)this.sectionPersistenceStrategies.delete(Z.mapKey);throw this.createSectionControllerRetirementError()}let Y={createDefaultController:Z.args.createDefaultController},X=await this.hooks.createSectionController?.(Q,Y)??await Y.createDefaultController(),G={mapKey:Z.mapKey,key:Z.key,controller:X,persistence:J,token:Z.token};try{await this.retireUnpublishedSectionControllerIfNeeded(G),await X.configureSessionPersistence?.({strategy:J,context:Q}),await this.retireUnpublishedSectionControllerIfNeeded(G),await X.initialize?.(Z.args.input),await this.retireUnpublishedSectionControllerIfNeeded(G);let j=Z.args.initialSession;if(j){if(!X.applySession)throw Error("Section controller cannot apply the session it was created with: it has no applySession.");await X.applySession(j,{mode:"replace"})}else await X.hydrate?.();return await this.finalizeSectionControllerReady({...G,context:Q}),X}catch(j){throw await this.cleanupUnpublishedSectionController(G),j}}async assignSessionToPublishedController(Z,Q){if(!Q)return;if(!Z.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");let J=d0(Z.getSession?.()??null,Q);if(!J)return;await Z.applySession(J,{mode:"replace"})}createSectionControllerRetirementError(){return this.disposePromise!==null?new l:new l0}async retireUnpublishedSectionControllerIfNeeded(Z){if(this.disposePromise===null&&!Z.token.retired)return;throw await this.cleanupUnpublishedSectionController(Z),this.createSectionControllerRetirementError()}async cleanupUnpublishedSectionController(Z){if(Z.token.candidateClaimed)return;Z.token.candidateClaimed=!0;try{await Z.controller.dispose?.()}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.key.sectionId,attemptId:Z.key.attemptId},recoverable:!0})}finally{if(this.sectionPersistenceStrategies.get(Z.mapKey)===Z.persistence)this.sectionPersistenceStrategies.delete(Z.mapKey)}}retirePublishedSectionControllerIfNeeded(Z){if(this.disposePromise!==null&&!Z.token.retired)this.disposeSectionController({sectionId:Z.key.sectionId,attemptId:Z.key.attemptId});if(Z.token.retired)throw this.createSectionControllerRetirementError()}async finalizeSectionControllerReady(Z){await this.retireUnpublishedSectionControllerIfNeeded(Z),this.sectionControllers.set(Z.mapKey,Z.controller),this.sectionControllerKeys.set(Z.mapKey,Z.key),Z.token.candidateClaimed=!0,this.setActiveCohortIfLatestRequest(Z.mapKey),this.emitSectionControllerLifecycle({type:"ready",key:Z.key,controller:Z.controller}),await this.hooks.onSectionControllerReady?.(Z.context,Z.controller),this.retirePublishedSectionControllerIfNeeded(Z),await this.emitTelemetry("pie-toolkit-section-controller-ready",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId}),this.retirePublishedSectionControllerIfNeeded(Z)}handleSectionControllerInitError(Z,Q){if(Z instanceof l||Z instanceof l0)return;this.handleError(Z,{phase:"section-controller-init",details:{sectionId:Q.sectionId,attemptId:Q.attemptId},recoverable:!1},"cohort")}deliverSectionStartError(Z,Q){if(Q instanceof l||Q instanceof l0||this.latestRequestedActiveCohortMapKey!==Z)return;let J={type:"section-error",source:"section-runtime",error:Q,currentItemIndex:0,timestamp:Date.now()};for(let Y of Array.from(this.activeSubscriptions.values()))if(this.buildSectionEventPredicate(Y)(J))this.deliverSectionEventSafely(Y.listener,J)}disposeSectionController(Z){let Q={assessmentId:this.assessmentId,sectionId:Z.sectionId,attemptId:Z.attemptId},J=this.getSectionControllerMapKey(Q),Y=this.sectionControllerInitEntries.get(J);if(Y)Y.token.retired=!0;let X=this.sectionControllers.get(J);if(!X){let q=this.sectionControllerDisposePromises.get(J);if(q)return q;if(!Y)return Promise.resolve();let K=Promise.allSettled([Y.promise]).then(()=>{return});return this.trackSectionControllerDisposal(J,K)}let G=this.sectionPersistenceStrategies.get(J);if(this.clearActiveCohortIfMatches(J),this.sectionControllers.get(J)===X)this.sectionControllers.delete(J),this.sectionControllerKeys.delete(J),this.sectionPersistenceStrategies.delete(J),this.emitSectionControllerLifecycle({type:"disposed",key:Q});let j=this.createSectionControllerContext({key:Q,input:void 0}),B=this.disposeSectionControllerEntry({args:Z,key:Q,context:j,controller:X,persistenceStrategy:G}),U=Y?Promise.allSettled([Y.promise]).then(()=>B):B;return this.trackSectionControllerDisposal(J,U)}trackSectionControllerDisposal(Z,Q){this.sectionControllerDisposePromises.set(Z,Q);let J=()=>{if(this.sectionControllerDisposePromises.get(Z)===Q)this.sectionControllerDisposePromises.delete(Z)};return Q.then(J,J),Q}async disposeSectionControllerEntry(Z){try{await this.runSectionControllerDisposePipeline({key:Z.key,context:Z.context,controller:Z.controller,persistBeforeDispose:Z.args.persistBeforeDispose})}catch(Q){this.handleError(Q,{phase:"section-controller-dispose",details:{sectionId:Z.args.sectionId,attemptId:Z.args.attemptId},recoverable:!0})}finally{await this.finalizeSectionControllerDispose({context:Z.context,persistenceStrategy:Z.persistenceStrategy,clearPersistence:Z.args.clearPersistence})}}async runSectionControllerDisposePipeline(Z){let Q=[];if(Z.persistBeforeDispose!==!1)try{await Z.controller.persist?.()}catch(J){Q.push(J)}try{await Z.controller.dispose?.()}catch(J){Q.push(J)}if(Q.length===1)throw Q[0];if(Q.length>1)throw AggregateError(Q,"Section controller persistence and disposal both failed.");await this.hooks.onSectionControllerDispose?.(Z.context,Z.controller),await this.emitTelemetry("pie-toolkit-section-controller-disposed",{assessmentId:Z.key.assessmentId,sectionId:Z.key.sectionId,attemptId:Z.key.attemptId})}async finalizeSectionControllerDispose(Z){if(Z.clearPersistence)await Z.persistenceStrategy?.clearSession?.(Z.context)}dispose(){if(this.disposePromise)return this.disposePromise;return this.disposePromise=Promise.resolve().then(()=>this.disposeOwnedResources()),this.disposePromise}async disposeOwnedResources(){let Z=[],Q=async(Y)=>{try{await Y()}catch(X){Z.push(X)}};await this.waitForAdmittedInitialization();let J=new Map;for(let[Y,X]of this.sectionControllerInitEntries)J.set(Y,X.key);for(let[Y,X]of this.sectionControllerKeys)J.set(Y,X);for(let Y of J.values())this.disposeSectionController({sectionId:Y.sectionId,attemptId:Y.attemptId});await Promise.allSettled(Array.from(this.sectionControllerDisposePromises.values())),this.sectionControllers.clear(),this.sectionControllerKeys.clear(),this.sectionControllerInitEntries.clear(),this.sectionPersistenceStrategies.clear();for(let Y of this.activeSubscriptions.values())await Q(()=>Y.unsubscribeCurrent?.()),Y.unsubscribeCurrent=null;this.activeSubscriptions.clear(),this.activeCohortMapKey=null,this.latestRequestedActiveCohortMapKey=null,await Q(()=>this.ttsService.dispose()),await Q(()=>this.toolProviderRegistry.destroy()),await Q(()=>this.highlightCoordinator.destroy());for(let Y of this.toolCoordinator.getRegisteredTools())await Q(()=>this.toolCoordinator.releaseTool(Y));if(await Q(()=>this.catalogResolver.destroy()),await Q(()=>this.toolRequests.dispose()),await Q(()=>this.policyEngine.dispose()),this.toolContextResolvers.clear(),this.toolContextResolverChangeListeners.clear(),this.sectionControllerLifecycleListeners.clear(),this.telemetryListeners.clear(),this.frameworkErrorHookUnsubscribe?.(),this.frameworkErrorHookUnsubscribe=null,this.ownsFrameworkErrorBus)this.frameworkErrorBus.dispose();if(Z.length===1)throw Z[0];if(Z.length>1)throw AggregateError(Z,"ToolkitCoordinator cleanup failed for multiple owned resources.")}async waitForAdmittedInitialization(){let Z=new Set;if(this.coordinatorReadyPromise)Z.add(this.coordinatorReadyPromise);if(this.ttsInitPromise)Z.add(this.ttsInitPromise);if(this.ttsReconfigurePromise)Z.add(this.ttsReconfigurePromise);for(let Q of this.providerInitPromises.values())Z.add(Q);await Promise.allSettled(Z)}async ensureTTSReady(Z){if(this.assertNotDisposed(),await this.waitForPendingTTSReconfigure(),this.assertNotDisposed(),this.ttsInitialized)return;if(this.ttsInitPromise)return this.ttsInitPromise;return this.ttsInitPromise=this._initializeTTS(Z).then(()=>this.assertNotDisposed()).finally(()=>{this.ttsInitPromise=void 0,this.notifyReadyChange()}),this.ttsInitPromise}async waitForPendingTTSReconfigure(){let Z=this.ttsReconfigurePromise;while(Z)await Z,Z=this.ttsReconfigurePromise}async _initializeTTS(Z){if(this.ttsInitialized)return;let Q=this.resolveTTSToolConfig(Z),J=G8(Q),Y=j8(J),X=B8(J);if(await this.hooks.onBeforeTTSInit?.({phase:"tts-init",details:{backend:Y}}),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-tts-init-start",{backend:Y}),await this.emitTelemetry("pie-tool-init-start",{toolId:"textToSpeech",operation:"tts-init",backend:Y}),this.toolProviderRegistry.has("textToSpeech"))try{let B=await(await this.initializeProvider("textToSpeech",!0)).createInstance();await this.initializeTTSService(B,X),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"registry"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:Y,provider:"registry"});return}catch(j){if(j instanceof l)throw j;let B=j instanceof Error?j:Error(String(j));await this.emitTelemetry("pie-tool-init-fallback",{toolId:"textToSpeech",operation:"tts-init",backend:Y,fromProvider:"registry",toProvider:"browser",reason:B.message}),console.warn("[ToolkitCoordinator] Failed to initialize TTS via registry, falling back to browser provider:",B)}else if(Y!=="browser")this.reportMissingTTSProvider(Y);let G=new X8;try{await this.initializeTTSService(G,Y==="browser"?X:y3(X)),await this.emitTelemetry("pie-toolkit-tts-init-success",{provider:"browser-fallback"}),await this.emitTelemetry("pie-tool-init-success",{toolId:"textToSpeech",operation:"tts-init",backend:Y,provider:"browser-fallback"})}catch(j){if(j instanceof l)throw j;let B=j instanceof Error?j:Error(String(j));throw this.reportToolFailure(B,{phase:"tts-init"},["textToSpeech"]),await this.emitTelemetry("pie-toolkit-tts-init-error",{message:B.message}),await this.emitTelemetry("pie-tool-init-error",{toolId:"textToSpeech",operation:"tts-init",backend:Y,errorType:"TTSInitError",message:B.message}),B}}resolveTTSToolConfig(Z){return Z||this.getTTSConfigFromProviders()||{}}async initializeTTSService(Z,Q){let J={...Q.providerOptions,__pieTelemetry:async(X,G)=>{await this.emitTelemetry(X,{toolId:"textToSpeech",...G||{}})}},Y={...Q,providerOptions:J};await this.ttsService.initialize(Z,Y),this.assertNotDisposed(),this.ttsService.setCatalogResolver(this.catalogResolver),this.ttsInitialized=!0,this.ttsDegraded=!1,this.degradedTools.delete("textToSpeech"),await this.hooks.onTTSReady?.(),this.assertNotDisposed()}async waitUntilReady(){if(this.assertNotDisposed(),this.isReady())return;if(this.coordinatorReadyPromise)return this.coordinatorReadyPromise;return this.coordinatorReadyPromise=(async()=>{if(await this.ensureStateLoaded(),this.assertNotDisposed(),this.ttsRequiredForReadiness())await this.startTTSForReadiness();if(this.assertNotDisposed(),!this.coordinatorReadyNotified)this.coordinatorReadyNotified=!0,await this.hooks.onCoordinatorReady?.(this),this.assertNotDisposed(),await this.emitTelemetry("pie-toolkit-coordinator-ready",{assessmentId:this.assessmentId})})().finally(()=>{this.coordinatorReadyPromise=void 0}),this.coordinatorReadyPromise}isReady(){return(this.stateLoadSettled||!this.hooks.loadToolState)&&(this.ttsInitialized||this.ttsDegraded||!this.ttsRequiredForReadiness())}ttsRequiredForReadiness(){if(this.getTTSConfigFromProviders()?.enabled===!1)return!1;return!this.lazyInit||this.isToolGranted("textToSpeech")}async startTTSForReadiness(){try{await this.ensureTTSReady(this.getTTSConfigFromProviders())}catch(Z){if(Z instanceof l)throw Z;if(this.isToolGranted("textToSpeech"))throw Z;this.ttsDegraded=!0,this.notifyReadyChange()}}getTTSConfigFromProviders(){return this.config.tools?.providers?.textToSpeech}assertCanonicalToolId(Z){if(typeof Z!=="string"||Z.trim().length===0)throw Error("Tool id must be a non-empty string.");if(this.toolRegistry.getAllToolIds().length===0)return;if(!this.toolRegistry.get(Z))throw Error(`Unknown tool id "${Z}".`)}installToolContextResolvers(Z){if(!Z)return;for(let[Q,J]of Object.entries(Z)){if(J==null)continue;if(this.assertCanonicalToolId(Q),typeof J!=="function")throw Error(`Invalid tool context resolver for "${Q}": expected a function.`);this.toolContextResolvers.set(Q,J)}}setToolContextResolvers(Z){this.toolContextResolvers.clear(),this.installToolContextResolvers(Z??void 0),this.notifyToolContextResolverChange()}notifyToolContextResolverChange(){for(let Z of this.toolContextResolverChangeListeners)try{Z()}catch(Q){console.warn("[ToolkitCoordinator] Tool context resolver listener threw:",Q)}}getToolConfig(Z){return this.assertCanonicalToolId(Z),this.config.tools?.providers?.[Z]||null}updateToolConfig(Z,Q){this.assertCanonicalToolId(Z);let J=this.getToolConfig(Z)||{};if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry});if(!this.config.tools.providers)this.config.tools.providers={};let Y={...this.config.tools.providers||{},[Z]:a4(Z,J,Q)};this.config.tools=this.validateToolsConfig({...this.config.tools,providers:Y},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolConfig",toolRegistry:this.toolRegistry}),this.policyEngine.updateInputs({tools:this.config.tools}),this.emitTelemetry("pie-toolkit-tool-config-updated",{toolId:Z}),this._applyToolConfigChange(Z)}updateToolsPlacement(Z){if(!this.config.tools)this.config.tools=this.validateToolsConfig(void 0,{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});let Q=this.config.tools?.placement??{section:[],item:[],passage:[]},J={section:[...Z.section??Q.section??[]],item:[...Z.item??Q.item??[]],passage:[...Z.passage??Q.passage??[]]},Y=this.validateToolsConfig({...this.config.tools,placement:J},{strictness:this.config.toolConfigStrictness??"error",source:"ToolkitCoordinator.updateToolsPlacement",toolRegistry:this.toolRegistry});Y.placement=J,this.config.tools=Y,this.policyEngine.updateInputs({tools:this.config.tools})}decideToolPolicy(Z){let Q=this.policyEngine.decide(Z);return this.warnPolicyDiagnostics(Q.diagnostics),Q}warnPolicyDiagnostics(Z){for(let Q of Z){let J=Q.code==="tool-policy.itemSettingNotApplied"?Q.details.itemId:"",Y=`${Q.code}\x00${Q.toolId}\x00${J}`;if(this.warnedPolicyDiagnostics.has(Y))continue;this.warnedPolicyDiagnostics.add(Y),console.warn(`[ToolkitCoordinator] ${Q.message}`)}}registerItemSettings(Z,Q){return this.policyEngine.registerItemSettings(Z,Q)}decideFeaturePolicy(Z,Q){let J=this.policyEngine.decideFeature(Z,Q);this.warnPolicyDiagnostics(J.diagnostics);let Y=this.config.assessmentOptional!==!0||this.pnpEnforcementOverride==="on";if(!J.assessmentBound&&Y&&!this.reportedUnboundFeaturePolicy)this.reportedUnboundFeaturePolicy=!0,console.warn(`[ToolkitCoordinator] Feature policy was asked about "${Z}" with no assessment bound, so every capability will be declined for want of a profile to read. Call updateAssessment(...) with the assessment (its personalNeedsProfile, settings.districtPolicy and settings.testAdministration are what policy reads) before relying on any accommodation. Reported once per coordinator.`);return J}onPolicyChange(Z){return this.policyEngine.onPolicyChange(Z)}onCatalogsChange(Z){return this.catalogResolver.onCatalogsChange(Z)}updateAssessment(Z){this.policyEngine.updateInputs({assessment:Z})}setPnpEnforcement(Z){this.pnpEnforcementOverride=Z,this.policyEngine.updateInputs({pnpEnforcement:Z})}getPolicyInputs(){return this.policyEngine.getInputs()}registerPolicySource(Z){return this.policyEngine.registerPolicySource(Z)}hasToolContextResolver(Z){return this.assertCanonicalToolId(Z),this.toolContextResolvers.has(Z)}resolveToolContext(Z){this.assertCanonicalToolId(Z.toolId);let Q=this.toolContextResolvers.get(Z.toolId);if(!Q)return null;let J;try{J=Q(Z)}catch(X){return console.error(`[ToolkitCoordinator] Tool context resolver for "${Z.toolId}" threw:`,X),{toolId:Z.toolId,visible:!1,params:{},reason:"Tool context resolver threw."}}if(!J)return{toolId:Z.toolId,visible:!0,params:{}};let Y=J.params&&typeof J.params==="object"&&!Array.isArray(J.params)?J.params:{};return{toolId:Z.toolId,visible:J.visible!==!1,params:Y,reason:typeof J.reason==="string"?J.reason:void 0}}onToolContextResolverChange(Z){return this.toolContextResolverChangeListeners.add(Z),()=>{this.toolContextResolverChangeListeners.delete(Z)}}getToolRegistry(){return this.toolRegistry}registerToolRequestTarget(Z){return this.toolRequests.registerTarget(Z)}requestTool(Z){return this.assertCanonicalToolId(Z.toolId),this.toolRequests.request(Z)}canRequestTool(Z,Q,J){try{this.assertCanonicalToolId(Z)}catch{return!1}return this.toolRequests.canRequest(Z,Q,J)}onToolRequestTargetsChange(Z){return this.toolRequests.onTargetsChange(Z)}resolveConfiguredPnpEnforcement(){return this.config.tools?.pnpEnforcement??null}_applyToolConfigChange(Z){if(this.disposePromise!==null)return;if(Z==="textToSpeech"){this.scheduleTTSReconfigure();return}this._registerChangedToolProvider(Z)}_registerChangedToolProvider(Z){let Q=this.getProviderDescriptorTools().find((J)=>J.toolId===Z);if(!Q)return;this.degradedTools.delete(Z),this.registerProviderFromTool(Q,!0)}scheduleTTSReconfigure(){let Z=this.ttsInitPromise,Q=Z?Z.catch(()=>{}).then(()=>this._reconfigureTTSProvider()):this._reconfigureTTSProvider();this.ttsReconfigurePromise=Q,Q.finally(()=>{if(this.ttsReconfigurePromise===Q)this.ttsReconfigurePromise=void 0}),Q.then(async()=>{if(this.disposePromise!==null)return;if(this.ttsRequiredForReadiness())await this.startTTSForReadiness()}).catch(()=>{})}async _reconfigureTTSProvider(){this.ttsInitialized=!1,this.ttsDegraded=!1,this.degradedTools.delete("textToSpeech"),this.ttsInitPromise=void 0,this.notifyReadyChange();try{this.ttsService.releaseProvider()}catch{}if(this.toolProviderRegistry.has("textToSpeech"))await this.toolProviderRegistry.unregister("textToSpeech");if(this.disposePromise!==null)return;let Z=this.getProviderDescriptorTools().find((Q)=>Q.toolId==="textToSpeech");if(!Z)return;await this.registerProviderFromTool(Z)}}var Z2=()=>{};function c3(Z){return Z===P.PLAYING||Z===P.LOADING}function d3(Z){let{ttsService:Q,silence:J}=Z;if(typeof Q?.onStateChange!=="function")return Z2;let Y=Q.onStateChange((X)=>{if(c3(X))J()});return()=>{try{Y()}catch{}}}function l3(Z){try{if(c3(Z?.getState?.()))Z?.pause?.()}catch{}}import{timedMediaProjectionSignature as N2}from"@pie-players/pie-players-shared/timed-media";function i3(Z,Q,J){let Y=Z.detail?.runtimeId;if(typeof Y==="string"&&Y!=="")return Y===Q;return J(Z.target)}function s3(Z,Q,J){let Y=[Z.catalogResolver.registerOwner({owner:{kind:Q.kind,itemId:Q.itemId,canonicalItemId:Q.canonicalItemId,assessmentId:J.assessmentId,sectionId:J.sectionId},entity:Q.item})];if(Q.kind==="item"&&Q.settings)Y.push(Z.registerItemSettings(Q.canonicalItemId||Q.itemId,Q.settings));return Y}var Q2=["a[href]","button","label","summary",...["button","checkbox","combobox","link","menuitem","menuitemcheckbox","menuitemradio","option","radio","switch","tab","treeitem"].map((Z)=>`[role="${Z}"]`)].join(", "),n3=new Set(["mi","mn","mtext"]),J2=(Z)=>n3.has(Z.localName)||Z.localName==="mrow"&&Z.children.length===1&&n3.has(Z.children[0].localName),Y2=(Z)=>Array.from(Z.getElementsByTagName("mfrac")).every((Q)=>Array.from(Q.children).every(J2))?"Fraction_Over":"Fraction_General",X2=(Z)=>!Z||Z.toLowerCase().split("-")[0]==="en";function r3(Z,Q={}){if(typeof MutationObserver>"u")return()=>{};let J=new Map,Y=!1,X=async(K,$,D)=>{let z=await o9([{type:"math",mathml:K,fallbackText:""}],{language:D,loadSre:Q.loadSre,mathSpeech:{...X2(D)?{style:Y2($)}:{},engineOptions:Q.getMathSpeech?.()?.engineOptions}});return z.usedMathSpeech?z.speechText:null},G=(K)=>{if(!E1(K,Q2))return;let $=E9(K,"math"),D=$&&r9($.outerHTML);if(!$||!D)return;let z=MZ(K,{contentLanguage:Q.getContentLanguage?.()}),M=`${z??""}\x00${D}`,O=J.get(M);if(!O)O=X(D,$,z),J.set(M,O);O.then((F)=>{if(Y||!F||!K.isConnected)return;if(K.getAttribute("aria-label")!==F)K.setAttribute("aria-label",F)})},j=new WeakSet,B=(K)=>{if(j.has(K))return;j.add(K),q.observe(K,{childList:!0,subtree:!0})},U=(K)=>{if(K.nodeType!==1)return;let $=K,D=E1($,"mjx-container");if(D){G(D);return}if($.shadowRoot)B($.shadowRoot);W0($,(z)=>{if(z.nodeType!==1)return"skip";let M=z;if(M.localName==="mjx-container")return G(M),"skip";if(M.shadowRoot)B(M.shadowRoot);return})},q=new MutationObserver((K)=>{for(let $ of K)for(let D of $.addedNodes)U(D)});return B(Z),U(Z),()=>{Y=!0,q.disconnect()}}import{createPieLogger as j2,isGlobalDebugEnabled as B2}from"@pie-players/pie-players-shared";function G2(Z,Q){if(Z===Q)return 0;let J=Z.compareDocumentPosition(Q);if(J&Node.DOCUMENT_POSITION_PRECEDING)return 1;if(J&Node.DOCUMENT_POSITION_FOLLOWING)return-1;return 0}class D8{shellsByElement=new Map;register(Z){let Q=this.shellsByElement.get(Z.element),J={...Z,sortKey:Date.now()};if(Q&&Q.kind===J.kind&&Q.itemId===J.itemId&&Q.canonicalItemId===J.canonicalItemId)return!1;return this.shellsByElement.set(Z.element,J),!0}unregister(Z){return this.shellsByElement.delete(Z)}getOrderedShells(Z){let Q=Array.from(this.shellsByElement.values()).filter((J)=>!Z||J.kind===Z);return Q.sort((J,Y)=>G2(J.element,Y.element)),Q}getCanonicalIdMap(){let Z={};for(let Q of this.getOrderedShells("item")){if(!Q.itemId)continue;Z[Q.itemId]=Q.canonicalItemId||Q.itemId}return Z}clear(){this.shellsByElement.clear()}}var o3=j2("section-controller-binding",()=>B2());function W2(Z){let Q=Z?.renderables;if(!Array.isArray(Q))return null;let J=new Set;for(let Y of Q){let X=Y?.entity?.id;if(typeof X==="string"&&X)J.add(X)}return J}class F8{registry=new D8;controller=null;coordinator=null;sectionId="";attemptId;unsubscribeController=null;activeInitToken=0;sectionRenderableIds=null;boundSections=new Map;loadedRenderableKeys=new Set;async initialize(Z){this.activeInitToken+=1;let Q=this.activeInitToken;this.coordinator=Z.coordinator,this.sectionId=Z.sectionId,this.attemptId=Z.attemptId,this.forgetUnregisteredLoads(Z.coordinator.getSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId}));let J;try{J=await Z.coordinator.getOrCreateSectionController({sectionId:Z.sectionId,attemptId:Z.attemptId,input:{section:Z.section,sectionId:Z.sectionId,assessmentId:Z.assessmentId,view:Z.view},updateExisting:!0,initialSession:Z.initialSession,createDefaultController:Z.createDefaultController})}catch(X){if(Q===this.activeInitToken)this.unsubscribeController?.(),this.unsubscribeController=null,this.controller=null;throw X}if(Q!==this.activeInitToken)return;this.unsubscribeController?.(),this.controller=J,this.sectionRenderableIds=W2(J.getCompositionModel?.());let Y=this.getSectionKey(Z.sectionId,Z.attemptId);this.boundSections.delete(Y),this.boundSections.set(Y,{sectionId:Z.sectionId,attemptId:Z.attemptId,renderableIds:this.sectionRenderableIds}),this.replayRegisteredShellsIntoController(J),Z.onCompositionChanged?.(J.getCompositionModel?.()),this.unsubscribeController=J.subscribe?.((X)=>{try{Z.onControllerEvent?.(X)}catch(G){o3.warn("onControllerEvent handler threw",G)}Z.onCompositionChanged?.(J.getCompositionModel?.())})||null}replayRegisteredShellsIntoController(Z){if(!Z.handleContentRegistered)return;let Q=this.registry.getOrderedShells().filter((Y)=>this.isSectionRenderable(Y));if(Q.length===0)return;for(let Y of Q){let X=Y.canonicalItemId||Y.itemId;Z.handleContentRegistered({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind})}let J=Date.now();for(let Y of Q){let X=Y.canonicalItemId||Y.itemId,G=this.getLoadedKey(X,Y.contentKind);if(this.loadedRenderableKeys.has(G))Z.handleContentLoaded?.({itemId:Y.itemId,canonicalItemId:X,contentKind:Y.contentKind||Y.kind,timestamp:J})}}getLoadedKey(Z,Q){return`${Q??""}:${Z}`}isSectionRenderable(Z){let Q=this.sectionRenderableIds;if(!Q)return!0;return Q.has(Z.itemId)||!!Z.canonicalItemId&&Q.has(Z.canonicalItemId)}getSectionKey(Z,Q){return`${Z}\x00${Q??""}`}controllerFor(Z){if(this.isSectionRenderable(Z))return this.controller;let Q=this.getSectionKey(this.sectionId,this.attemptId),J=[...this.boundSections.entries()].reverse();for(let[Y,X]of J){if(Y===Q||!X.renderableIds)continue;if(!X.renderableIds.has(Z.itemId)&&!(Z.canonicalItemId&&X.renderableIds.has(Z.canonicalItemId)))continue;let G=this.coordinator?.getSectionController({sectionId:X.sectionId,attemptId:X.attemptId});if(G)return G}return null}requireControllerFor(Z,Q){let J=this.controllerFor(Z);if(!J)o3.warn(`Dropped ${Q} for "${Z.itemId}": no section this toolkit bound renders it.`);return J}forgetUnregisteredLoads(Z){if(!Z||Z===this.controller)return;let Q=Z.getRuntimeState?.()?.loadedRenderables??[];if(Q.length===0)return;let J=new Set;for(let Y of this.registry.getOrderedShells())if(J.add(Y.itemId),Y.canonicalItemId)J.add(Y.canonicalItemId);for(let Y of Q){if(J.has(Y.canonicalItemId)||J.has(Y.itemId))continue;Z.handleContentUnregistered?.({itemId:Y.itemId,canonicalItemId:Y.canonicalItemId,contentKind:Y.contentKind})}}register(Z){return this.registry.register(Z)}unregister(Z){return this.registry.unregister(Z)}getCompositionModel(){return this.controller?.getCompositionModel?.()??null}getCanonicalItemId(Z){return this.registry.getCanonicalIdMap()[Z]||this.controller?.getCanonicalItemId?.(Z)||Z}handleContentRegistered(Z){if(!this.isSectionRenderable(Z))return;this.controller?.handleContentRegistered?.({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId||Z.itemId,contentKind:Z.contentKind||Z.kind})}handleContentUnregistered(Z){let Q=Z.canonicalItemId||Z.itemId,J=this.getLoadedKey(Q,Z.contentKind);if(this.registry.getOrderedShells().some((X)=>this.getLoadedKey(X.canonicalItemId||X.itemId,X.contentKind)===J))return;this.loadedRenderableKeys.delete(J),this.controllerFor(Z)?.handleContentUnregistered?.({itemId:Z.itemId,canonicalItemId:Q,contentKind:Z.contentKind||Z.kind})}handleContentLoaded(Z){let Q=Z.canonicalItemId||Z.itemId;if(this.loadedRenderableKeys.add(this.getLoadedKey(Q,Z.contentKind)),!this.isSectionRenderable(Z))return;this.controller?.handleContentLoaded?.(Z)}handleItemPlayerError(Z){this.requireControllerFor(Z,"an item player error")?.handleItemPlayerError?.(Z)}reportSectionError(Z){(Z.itemId?this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId},"a section error"):this.controller)?.reportSectionError?.(Z)}updateItemSession(Z,Q){let J=this.getCanonicalItemId(Z);return this.requireControllerFor({itemId:Z,canonicalItemId:J},"a session update")?.updateItemSession?.(J,Q)??null}navigateToItem(Z){return this.controller?.navigateToItem?.(Z)??null}handleFormativeAction(Z){if(!Z?.itemId)return;let Q=Z.canonicalItemId||this.getCanonicalItemId(Z.itemId),J=this.requireControllerFor({itemId:Z.itemId,canonicalItemId:Q},"a formative action");if(Z.action==="retry"){J?.retryFormativeItem?.({itemId:Q});return}J?.recordFormativeTry?.({itemId:Q,outcomes:Z.outcomes})}handleMediaTimeSource(Z){if(!Z?.renderableId)return;let Q=this.requireControllerFor({itemId:Z.renderableId,canonicalItemId:this.getCanonicalItemId(Z.renderableId)},"a media time source");if(Z.action==="detach"){Q?.detachMediaTimeSource?.({origin:Z.origin??"host"});return}if(!Z.source)return;Q?.attachMediaTimeSource?.(Z.source,{origin:Z.origin??"host",renderableId:Z.renderableId})}requestMediaPauseForCompetingAudio(){return this.controller?.pauseMediaForCompetingAudio?.()??!0}async persist(){await this.controller?.persist?.()}async hydrate(){await this.controller?.hydrate?.()}getRegistry(){return this.registry}async dispose(){if(this.activeInitToken+=1,this.unsubscribeController?.(),this.unsubscribeController=null,this.coordinator&&this.sectionId)await this.coordinator.disposeSectionController({sectionId:this.sectionId,attemptId:this.attemptId});this.registry.clear(),this.loadedRenderableKeys.clear(),this.boundSections.clear(),this.controller=null,this.sectionRenderableIds=null,this.coordinator=null}}function a3(Z){let Q=Z.section?.identifier;return Z.sectionId||(typeof Q==="string"?Q:"")||`section-${Z.assessmentId||"default"}`}function t3(Z,Q){return["pnpEnforcement","assessment"].filter((Y)=>Z?!Object.is(Z[Y],Q[Y]):Q[Y]!==null)}function Z5(Z){if(!Z)return;let Q=Symbol.for("pie.assessmentToolkit.unclaimedRegistrationWatch"),J=Z;if(J[Q])return;J[Q]=!0,Z.addEventListener(i0,(Y)=>{let X=Y.detail,G=typeof X?.itemId==="string"?X.itemId:"";e3(Z,"unclaimedRegistration",`[pie-assessment-toolkit] Item "${G}" registered, but no toolkit claimed the registration, so its accessibility catalogs are not filed and it does not count toward its section's loading. Render its shell or scope inside the <pie-assessment-toolkit> that answered it. Reported once per page.`)})}function D0(Z,Q){if(typeof Z==="function")return Z;if(Z===null)return null;return typeof Q==="function"?Q:null}function Q5(Z={}){let Q=Z.frameDeadlineMs??100,J=!1,Y=null,X=null,G=null,j=null,B=null;function U(){if(J=!1,X!==null)j?.(X),X=null;if(G!==null)B?.(G),G=null;j=null,B=null}function q(D){if(!J)return;if(D==="frame")X=null;if(D==="timer")G=null;let z=Y;Y=null,U(),z?.()}function K(D){if(Y=D,J)return;J=!0;let z=globalThis,M=D0(Z.requestFrame,z.requestAnimationFrame);j=D0(Z.cancelFrame,z.cancelAnimationFrame);let O=D0(Z.setTimer,z.setTimeout);if(B=D0(Z.clearTimer,z.clearTimeout),M){let w=M(()=>q("frame"));if(!J)return;if(X=w,O){let R=O(()=>q("timer"),Q);if(J)G=R}return}let F=D0(Z.queueMicrotaskFn,z.queueMicrotask);if(F){F(()=>q("microtask"));return}if(O){let w=O(()=>q("timer"),0);if(J)G=w;return}q("microtask")}function $(){if(!J)return;Y=null,U()}return{schedule:K,cancel:$,isPending:()=>J}}function J5(Z="runtime"){return`${Z}-${Math.random().toString(16).slice(2)}-${Date.now()}`}function Y5(){return{lastSessionEventSignatureByItemId:new Map,lastMetadataSignatureByItemId:new Map}}function X5(Z){Z.lastSessionEventSignatureByItemId.clear(),Z.lastMetadataSignatureByItemId.clear()}function G5(Z){let{state:Q,itemId:J,payload:Y}=Z;if(K2(Y)){let j=V2(Y);if(Q.lastMetadataSignatureByItemId.get(J)===j)return!1;Q.lastMetadataSignatureByItemId.set(J,j)}let X=U2(Y);if(Q.lastSessionEventSignatureByItemId.get(J)===X)return!1;return Q.lastSessionEventSignatureByItemId.set(J,X),!0}function U2(Z){let Q={...Z};delete Q.timestamp,delete Q.sourceRuntimeId;try{return JSON.stringify(Q)}catch{return String(Q.itemId||"")}}function K2(Z){return Z.intent==="metadata-only"}function V2(Z){try{return JSON.stringify({itemId:Z.itemId,canonicalItemId:Z.canonicalItemId,intent:Z.intent,complete:Z.complete??null,component:Z.component??null})}catch{return String(Z.itemId||"")}}var q2=(Z,Q)=>{if(customElements.get(Z))return;try{customElements.define(Z,Q)}catch(J){if(!(J instanceof DOMException&&J.name==="NotSupportedError"||J&&typeof J==="object"&&J.name==="NotSupportedError")||!customElements.get(Z))throw J}},w2=_8('<div class="pie-assessment-toolkit-error svelte-15pthty" role="alert" aria-live="assertive"><div class="pie-assessment-toolkit-error-title svelte-15pthty"> </div> <div class="pie-assessment-toolkit-error-message svelte-15pthty"> </div> <pre class="pie-assessment-toolkit-error-details svelte-15pthty"> </pre></div>'),P2=_8('<div class="pie-assessment-toolkit-anchor svelte-15pthty" aria-hidden="true"></div> <!>',1),R2={hash:"svelte-15pthty",code:`.pie-assessment-toolkit-anchor.svelte-15pthty {display:none;}.pie-assessment-toolkit-error.svelte-15pthty {margin:0.75rem;padding:0.75rem 1rem;border-radius:0.5rem;border:1px solid
|
|
224
|
+
color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 40%, transparent);background:color-mix(in srgb, var(--pie-incorrect-icon, #dc2626) 12%, transparent);color:var(--pie-incorrect, #7f1d1d);font-size:0.9rem;}.pie-assessment-toolkit-error-title.svelte-15pthty {font-weight:600;margin-bottom:0.25rem;}.pie-assessment-toolkit-error-message.svelte-15pthty {margin-bottom:0.5rem;}.pie-assessment-toolkit-error-details.svelte-15pthty {margin:0;white-space:pre-wrap;word-break:break-word;}`};function b5(Z,Q){U5(Q,!0),z5(Z,R2);let J=H2("pie-assessment-toolkit",()=>_2()),Y=J5("toolkit"),X=new F8,G=new B0,j={mode:"gather",role:"student"},B={iife:"pie-item-player",esm:"pie-item-player",preloaded:"pie-item-player",custom:""},U=k(Q,"assessmentId",7,""),q=k(Q,"section",7,null),K=k(Q,"sectionId",7,""),$=k(Q,"attemptId",7,""),D=k(Q,"env",23,()=>({})),z=k(Q,"ndsIcons",7,!1),M=k(Q,"locale",7,""),O=k(Q,"contentLanguage",7,""),F=k(Q,"lazyInit",7,!1),w=k(Q,"toolConfigStrictness",7,"error"),R=k(Q,"tools",23,()=>({})),b=k(Q,"toolContextResolvers",7,null),S=k(Q,"enabledTools",7,""),h=k(Q,"toolRegistry",7,null),C=k(Q,"accessibility",23,()=>({})),U9=k(Q,"player",7,null),K9=k(Q,"playerType",7,""),u=k(Q,"coordinator",7,null),Q9=k(Q,"createSectionController",7,null),H9=k(Q,"onFrameworkError",7,null),_9=k(Q,"errorRenderer",7,null),M9=k(Q,"assessment",7,null),V9=k(Q,"isolation",7,"inherit"),L9=k(Q,"session",7,null),Z0=n(null),p=n(null),J9=n(null),M8=null,L8=null,Q0=!1,m9=null,u9=null,p9=null,F0=n(0),t0=n(null),Y9=n(null),e0=n("Unable to initialize assessment toolkit."),Z1=n(V5([])),O8="",Q1="",J0=null,Y0=null,z0=null,N8=null,J1=null,w8=null,H0=null,P8=!1,R8=null,E8=!1,C8=n(""),Y1=null,_0=Q5(),O9=[],M0=new Map,X1=new WeakMap,L0=new Map,b8=Y5(),X0=n(!1);function S5(){if(!A(Z0))return null;let W=A(Z0).getRootNode();if(W&&"host"in W)return W.host;return A(Z0).parentElement}let f=s(()=>S5());function N9(W,V){if(!A(f)){O9=[...O9,{name:W,detail:V}];return}H8(A(f),W,V)}T(()=>{if(!A(f))return;if(O9.length===0)return;let W=O9;O9=[],queueMicrotask(()=>{let V=A(f);if(!V){O9=[...W,...O9];return}for(let H of W)H8(V,H.name,H.detail)})});function T5(W){if(!_9())return{title:"Unable to initialize assessment toolkit.",details:W.details.length>0?W.details:[W.message]};try{let V=_9()(W)||{};return{title:typeof V.title==="string"&&V.title.trim().length>0?V.title:"Unable to initialize assessment toolkit.",details:Array.isArray(V.details)&&V.details.length>0?V.details.map((H)=>String(H)):W.details.length>0?W.details:[W.message]}}catch(V){let H=V instanceof Error&&V.message.trim().length>0?V.message:String(V||"Unknown renderer error");return{title:"Unable to initialize assessment toolkit.",details:[...W.details,`Error renderer failed: ${H}`]}}}function w9(W){let V=A1({kind:W.kind,source:W.source,error:W.error,recoverable:W.recoverable,scope:W.scope});return G.reportFrameworkError(V),V}function y5(W){if(W?.type==="timed-media-policy-degraded"){let H=W.degradations||[];G.reportFrameworkError(E0({kind:"timed-media",severity:"warning",source:"pie-assessment-toolkit",message:"A timed-media playback policy degraded to advisory: the media time source does not report the capability it needs.",details:H.map((N)=>N?.message).filter((N)=>typeof N==="string"),recoverable:!0,scope:"cohort"}));return}if(W?.type!=="timed-media-invalid")return;let V=W.errors||[];G.reportFrameworkError(E0({kind:"timed-media",severity:"error",source:"pie-assessment-toolkit",message:'This section declares sectionType: "timed-media" but its timedMedia data is not deliverable; the section renders without cue behavior.',details:V.map((H)=>H?.message).filter((H)=>typeof H==="string"),recoverable:!1,scope:"cohort"}))}function x5(W){if(W?.type!=="timed-media-audio-started")return;if(!A(E))return;l3(A(E).ttsService)}function k5(W){return W==="coordinator-init"||W==="runtime-init"||W==="tool-config"}function G0(W){return`${W.kind}|${W.source}|${W.message}`}function S8(W){if(!H9())return;try{H9()(W),O8=G0(W)}catch(V){console.error(`[pie-framework:${W.kind}:${W.source}] framework error hook failed`,V)}}let T8=new WeakSet,y8=new WeakMap;function f5(W){if(typeof W!=="object"||W===null)return null;return y8.get(W)??null}function x8(W){let V=T5(W);v(Y9,W,!0),v(e0,V.title,!0),v(Z1,V.details,!0)}function k8(){v(Y9,null),v(e0,"Unable to initialize assessment toolkit."),v(Z1,[],!0)}T(()=>{let W=G.subscribeFrameworkErrors((V)=>{if(console.error(n8(V),V.cause),typeof V.cause==="object"&&V.cause!==null)y8.set(V.cause,V);if(k5(V.kind)&&!T8.has(V))x8(V);N9("framework-error",V),S8(V)});return()=>{W()}}),T(()=>{let W=u();if(!W||A(E)!==W)return;if(typeof W.subscribeFrameworkErrors!=="function")return;return I(()=>W.subscribeFrameworkErrors((V)=>{T8.add(V),G.reportFrameworkError(V)}))}),T(()=>{let W=A(E),V=h();if(!W||A(w0))return;if(typeof W.adoptToolRegistry!=="function")return;I(()=>{let H=W===A(p);if(H&&!V)return;if(W.adoptToolRegistry(V)&&H&&J0)J0={...J0,toolRegistry:V}})}),T(()=>{if(!A(Y9))return;if(O8===G0(A(Y9)))return;S8(A(Y9))});function I5(W){let V=5381;for(let H=0;H<W.length;H+=1)V=(V<<5)+V^W.charCodeAt(H);return(V>>>0).toString(36)}function r(W){return W&&typeof W==="object"?W:{}}function v5(W){let V=r(W.section),H=typeof V.identifier==="string"?V.identifier:"",N=typeof W.sectionId==="string"?W.sectionId:"";return H||N}function h5(W){return typeof W.currentItemIndex==="number"?W.currentItemIndex:-1}function m5(W){return(Array.isArray(W.renderables)?W.renderables:[]).map((H,N)=>{let L=r(H),_=r(L.entity),g=typeof _.id==="string"&&_.id||`renderable-${N}`,R0=r(_.config),$1=typeof _.version==="string"&&_.version||(typeof _.version==="number"?String(_.version):"")||(typeof R0.version==="string"?R0.version:"");return{id:g,version:$1}})}function u5(W){let V=r(W.itemSessionsByItemId);return Object.keys(V).sort((H,N)=>H.localeCompare(N)).map((H)=>{let N=r(V[H]),L=typeof N.id==="string"?N.id:"",_=Array.isArray(N.data)?N.data:[],g="";try{g=I5(JSON.stringify(_))}catch{g=String(_.length)}return{itemId:H,sessionId:L,payloadSignature:g}})}function p5(W){let V=r(r(W.formative).states);return Object.entries(V).map(([H,N])=>{let L=r(N),_=r(L.lastOutcome).correctness??"";return`${H}:${L.tryCount??0}:${L.revealed===!0?1:0}:${String(_)}:${String(L.revealOverride??"")}`}).sort().join("|")}function g5(W){let V=W.timedMedia;return N2(V)}function c5(W){let V=r(W),H=m5(V).map((L)=>`${L.id}:${L.version}`).join("|"),N=u5(V).map((L)=>`${L.itemId}:${L.sessionId}:${L.payloadSignature}`).join("|");return{sectionId:v5(V),currentItemIndex:h5(V),renderableSignature:H,itemSessionSignature:N,formativeSignature:p5(V),timedMediaSignature:g5(V)}}function d5(W){let V=c5(W);return`${V.sectionId}|${V.currentItemIndex}|${V.renderableSignature}|${V.itemSessionSignature}|${V.formativeSignature}|${V.timedMediaSignature}`}function f8(W){return W==="iife"||W==="esm"||W==="preloaded"||W==="custom"}function l5(W,V){let H=W?.type,N=f8(H)?H:f8(V)?V:W?.tagName?"custom":"iife",L=W?.tagName?.trim();if(N==="custom"&&!L)return{type:"iife",tagName:B.iife,version:void 0,source:void 0,isDefault:!0};return{type:N,tagName:L||B[N],version:W?.version,source:W?.source,loaderConfig:W?.loaderConfig,loaderOptions:W?.loaderOptions,isDefault:!W&&!V}}function I8(W){let V=W||{},H=typeof V.mode==="string"&&V.mode.trim()?V.mode.trim():j.mode,N=typeof V.role==="string"&&V.role.trim()?V.role.trim():j.role;return{mode:H,role:N}}function i5(W){let V=I8(W);if(V.mode==="author")return"author";if(V.role==="instructor")return"scorer";return"candidate"}function s5(W,V){return W.sectionId===V.sectionId&&W.attemptId===V.attemptId}function v8(){if(!L9()||L9()===N8)return;N8=L9(),z0={value:L9(),cohort:{sectionId:A(a),attemptId:$()||void 0}}}function h8(W,V){v8();let H=z0;if(!H)return null;if(!s5(H.cohort,W)){if(V)z0=null;return null}return z0=null,H.value}function m8(){let W=J1,V=A(E);if(!W||!V)return;let H=h8(W,!1);if(!H)return;let N=V.getSectionController(W);if(!N)return;let L=d0(N.getSession?.()??null,H);if(!L)return;Promise.resolve().then(()=>{if(!N.applySession)throw Error("Section controller cannot apply the assigned session: it has no applySession.");return N.applySession(L,{mode:"replace"})}).catch((_)=>{w9({kind:"unknown",source:"pie-assessment-toolkit",error:_,recoverable:!0})})}async function n5(){if(Q9())return Q9()();throw Error("pie-assessment-toolkit requires createSectionController when no coordinator hook provides one")}function G1(){let W=R()||{},V=O5(S());if(V.length===0)return W;let H=W.placement||{},N=Array.isArray(H.section)?H.section:null;if(N&&N.length>0)return W;return{...W,placement:{...H,section:V}}}function r5(){return o8(G1(),{strictness:w(),source:"pie-assessment-toolkit.bootstrap",toolRegistry:h()}).config}function o5(){let W="",V="";try{W=JSON.stringify(G1())}catch{W="[unserializable-tools]"}try{V=JSON.stringify(Object.entries(b()??{}).map(([H,N])=>[H,typeof N]))}catch{V="[unserializable-resolvers]"}return[U()||"",String(w()||"error"),W,V].join("|")}function a5(W){let V=W?.pnpEnforcement;return V==="on"||V==="off"?V:null}function t5(W){let V=U()||q()?.identifier||`assessment-${Math.random().toString(16).slice(2)}`;return new A8({assessmentId:V,lazyInit:F(),eagerInit:!1,toolConfigStrictness:w(),deferToolConfigValidation:!0,assessmentOptional:!0,tools:W,toolRegistry:h(),toolContextResolvers:b(),accessibility:C(),frameworkErrorBus:G})}function u8(W){try{return JSON.stringify(W??null)}catch{return"[unserializable]"}}function p8(){return{signatures:{assessmentId:U()||"",toolConfigStrictness:String(w()||"error"),lazyInit:String(F()),tools:u8({...G1(),pnpEnforcement:void 0}),accessibility:u8(C())},toolRegistry:h()}}function e5(){let W=J0;if(!W)return[];let V=p8(),H=Object.keys(V.signatures).filter((N)=>V.signatures[N]!==W.signatures[N]);if(W.toolRegistry&&V.toolRegistry!==W.toolRegistry)H.push("toolRegistry");return H}function Z6(W,V){if(P8)return;P8=!0,console.warn(`[pie-assessment-toolkit] ${W.join(", ")} changed after ${V} with the coordinator this toolkit built, and that coordinator keeps the values it was built with. Set these inputs no later than the section or the first item scope, pass a coordinator of your own, or update this one from runtime-ready with updateToolConfig(...) or updateToolsPlacement(...). Reported once per toolkit.`)}function Q6(W){if(E8)return;E8=!0,console.warn(`[pie-assessment-toolkit] The toolkit above this one (runtime "${W}") had no coordinator when this one connected, so this one built its own and keeps it: the two share no tool state, policy or read-aloud. Give the outer toolkit its coordinator before the inner one connects, or set isolation="force" on the inner one to keep them apart on purpose. Reported once per toolkit.`)}function O0(){let W=A(p);if(!W)return Promise.resolve();return v(p,null),W.dispose()}function N0(W){w9({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}let w0=s(()=>!u()&&V9()!=="force"&&A(J9)?.coordinator!=null),E=s(()=>{if(A(w0))return A(J9)?.coordinator;return u()||A(p)}),j1=s(()=>q()!=null);T(()=>{A(f),u(),V9(),A(J9),b(),A(j1),A(X0),R(),S(),U(),w(),F(),C(),h(),I(()=>{if(!A(f))return;if(u()){if(A(p))O0().catch(N0);m9=null;return}if(V9()!=="force"&&A(J9)?.coordinator){if(A(p))O0().catch(N0);m9=null;return}if(A(p)){let W=e5();if(W.length>0&&Y0)Z6(W,Y0);else if(W.length>0&&(q()||A(X0)))O0().catch(N0)}if(A(p)&&m9!==b()){try{A(p).setToolContextResolvers(b()),m9=b()}catch(W){w9({kind:"coordinator-init",source:"pie-assessment-toolkit",error:W})}return}if(!A(p)){if(V9()!=="force"&&!Q0){let V=B5(A(f),a0);if(V?.coordinator&&V.runtimeId!==Y){v(J9,V,!0),m9=null;return}}let W=o5();if(Q1===W)return;try{let V=r5();v(p,t5(V),!0),Q0=V9()!=="force",J0=p8(),Y0=null,m9=b(),Q1="",k8()}catch(V){v(p,null),Q1=W,w9({kind:"coordinator-init",source:"pie-assessment-toolkit",error:V})}}})}),T(()=>{if(!A(X0)||!A(E))return;let W=A(E);I(()=>{if(W===A(p))Y0??="an item registered"})});let P0=L2(),B1=n(0);T(()=>P0.subscribe(()=>{v(B1,A(B1)+1)})),T(()=>{let W=typeof M()==="string"?M().trim():"";I(()=>{Promise.resolve(P0.setLocale(W||O2)).catch((V)=>{w9({kind:"i18n-locale-load",source:"pie-assessment-toolkit",error:V instanceof Error?V:Error(String(V)),recoverable:!0})})})});let q9=s(()=>U()||A(E)?.assessmentId||""),a=s(()=>a3({sectionId:K(),section:q(),assessmentId:A(q9)})),W1=s(()=>I8(D())),J6=s(()=>i5(A(W1))),g9=s(()=>l5(U9(),K9())),j0=s(()=>D2({player:A(g9),component:"pie-assessment-toolkit"})),Y6=s(()=>{if(!A(E))return null;return{toolkitCoordinator:A(E),toolCoordinator:A(E).toolCoordinator,ttsService:A(E).ttsService,highlightCoordinator:A(E).highlightCoordinator,catalogResolver:A(E).catalogResolver,elementToolStateStore:A(E).elementToolStateStore,assessmentId:A(q9),sectionId:A(a),itemPlayer:A(g9),ndsIcons:z()===!0,locale:(A(B1),P0.getLocale()),i18n:P0,contentLanguage:O()?.trim()||void 0,reportSectionError:(W)=>{X.reportSectionError({source:"section-runtime",error:W,timestamp:Date.now()})}}}),X6=s(()=>{if(!A(E)||!A(f))return null;return{runtimeId:Y,coordinator:A(E),sectionBound:A(j1),eventTarget:A(f)}});function g8(W){if(W==null)return;let V=d5(W);if(V===A(C8))return;v(C8,V,!0),v(F0,A(F0)+1),v(t0,W,!0),N9("composition-changed",{composition:A(t0),version:A(F0)})}function U1(W){Y1=W??X.getCompositionModel(),_0.schedule(()=>{g8(Y1)})}function G6(){if(!_0.isPending())return;_0.cancel(),g8(Y1)}function K1(W){if(!W)return;let V=X1.get(W);if(!V)return;for(let H of V)H();X1.delete(W)}function c8(){for(let W of M0.values())K1(W.element)}function d8(W){if(K1(W.element),!A(E))return;X1.set(W.element,s3(A(E),W,{assessmentId:A(q9),sectionId:A(a)}))}function j6(){c8();for(let W of M0.values())d8(W)}function V1(W){if(!W)return;L0.get(W)?.(),L0.delete(W)}function B6(W){V1(W),L0.set(W,r3(W,{getMathSpeech:()=>A(E)?.ttsService.getMathSpeechOptions(),getContentLanguage:()=>O()}))}function W6(W){let H={...W.result?.eventDetail||W.fallbackSession,itemId:W.itemId,canonicalItemId:W.canonicalItemId||W.itemId,sourceRuntimeId:Y};if(!G5({state:b8,itemId:W.itemId,payload:H}))return;N9("session-changed",H)}function U6(W){if(!(W instanceof HTMLElement))return!1;return B5(W,a0)?.runtimeId===Y}function P9(W){return W.detail??null}function K6(W,V){for(let H of V)W.addEventListener(H.name,H.handler);return()=>{for(let H of V)W.removeEventListener(H.name,H.handler)}}T(()=>{let W=A(f),V=V9();return I(()=>{if(!W)return;if(V==="force")return v(J9,null),()=>{Q0=!1};let H=L5(W,(N)=>{if(N.runtimeId===Y)return;if(Q0){Q6(N.runtimeId);return}v(J9,N,!0)});return()=>{H(),v(J9,null),Q0=!1}})}),T(()=>{let W=A(E);if(!W)return;return I(()=>d3({ttsService:W.ttsService,silence:()=>X.requestMediaPauseForCompetingAudio()}))}),T(()=>{let W=A(w0)?A(J9)?.runtimeId??null:null,V=W?"inherited":"owned";if(V!==M8)M8=V,N9(V==="inherited"?"runtime-inherited":"runtime-owned",{runtimeId:Y,parentRuntimeId:W})}),T(()=>{let W=A(f);if(!W)return;I(()=>Z5(W.ownerDocument))}),T(()=>{let W=A(E);if(!W)return;let V=A(w0)?"inherited":"owned";I(()=>{if(W===L8)return;L8=W,N9("runtime-ready",{runtimeId:Y,coordinator:W,ownership:V})})}),T(()=>{let W=A(a),V=$()||"";X5(b8)}),T(()=>{if(!A(f))return;A(f).setAttribute("data-item-player-type",A(g9).type),A(f).setAttribute("data-item-player-tag",A(g9).tagName),A(f).setAttribute("data-env-mode",String(A(W1)?.mode||"")),A(f).setAttribute("data-env-role",String(A(W1)?.role||""))}),T(()=>{return A(E),A(q9),A(a),j6(),()=>{c8()}}),T(()=>{if(!A(f))return;return A2({host:A(f),instrumentationProvider:A(j0),component:"pie-assessment-toolkit",eventMap:F2,staticAttributes:{instrumentationLayer:"toolkit",assessmentId:A(q9),sectionId:A(a),attemptId:$()||void 0}})});let q1=null;T(()=>{M9(),R();let W=A(E);if(!W)return;if(W!==A(p))return;I(()=>{let V={pnpEnforcement:a5(R()),assessment:M9()??null},H=q1?.coordinator===W?q1.inputs:null;q1={coordinator:W,inputs:V};for(let N of t3(H,V))if(N==="pnpEnforcement")W.setPnpEnforcement(V.pnpEnforcement);else W.updateAssessment(V.assessment)})}),T(()=>{if(!A(E))return;return A(E).subscribeTelemetry(({eventName:W,payload:V})=>{if(!M2(A(j0)))return;if(!A(j0).isReady())return;let H=W,N=new Date().toISOString(),L={...V||{},instrumentationLayer:"toolkit",assessmentId:A(q9),sectionId:A(a),attemptId:$()||void 0,component:"pie-assessment-toolkit",sourceEventName:W,timestamp:N};A(j0).trackEvent(H,L);let _=V&&typeof V.errorType==="string"?V.errorType:void 0;if(!W.endsWith("-error")&&!_)return;let g=V&&typeof V.message==="string"?V.message:`Toolkit telemetry error: ${W}`;A(j0).trackError(Error(g),{component:"pie-assessment-toolkit",errorType:_||"ToolkitTelemetryError",...L})})}),T(()=>{if(!q()||!A(E))return;let W=!1;if(A(E)===I(()=>A(p)))Y0??="a section initialized";let V={sectionId:A(a),attemptId:$()||void 0},H=w8;if(w8=V,H&&(H.sectionId!==V.sectionId||H.attemptId!==V.attemptId))I(()=>z2(A(f),{reason:"teardown",logger:J}));J1=null;let N=I(()=>h8(V,!0));return X.initialize({coordinator:A(E),section:q(),sectionId:A(a),assessmentId:A(q9),attemptId:$()||void 0,view:A(J6),initialSession:N,createDefaultController:n5,onCompositionChanged:(L)=>{if(W)return;U1(L)},onControllerEvent:(L)=>{if(W)return;x5(L),y5(L)}}).then(()=>{if(W)return;J1=V;let L=I(()=>A(Y9));if(L&&G0(L)===H0)k8();H0=null,I(()=>m8()),I(()=>G6()),queueMicrotask(()=>{if(W)return;N9("toolkit-ready",{runtimeId:Y,assessmentId:A(q9),sectionId:A(a),itemPlayer:A(g9),coordinator:A(E)}),N9("section-ready",{sectionId:V.sectionId,attemptId:V.attemptId,controller:A(E).getSectionController(V)??null})})}).catch((L)=>{if(W)return;let _=I(()=>f5(L));if(_)I(()=>x8(_)),H0=G0(_);else H0=G0(w9({kind:"runtime-init",source:"pie-assessment-toolkit",error:L,scope:"cohort"}))}),()=>{W=!0}}),T(()=>{L9(),I(()=>{v8(),m8()})}),T(()=>{if(!A(f))return;let W=A(f),V=(L)=>{if(!i3(L,Y,U6))return!1;return L.stopPropagation(),!0},N=K6(W,[{name:i0,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.element||!_?.itemId)return;let g=X.register(_);if(M0.set(_.element,_),v(X0,!0),d8(_),B6(_.element),X.handleContentRegistered(_),g)U1()}},{name:N5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;let g=_?.element?X.unregister(_.element):!1;if(K1(_.element),V1(_.element),_.element)M0.delete(_.element);if(X.handleContentUnregistered(_),g)U1()}},{name:w5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;let g=X.updateItemSession(_.itemId,_.session);W6({itemId:_.itemId,canonicalItemId:X.getCanonicalItemId(_.itemId),result:g,fallbackSession:_.session})}},{name:P5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;X.handleContentLoaded({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,detail:_.detail,timestamp:Date.now()})}},{name:R5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;X.handleItemPlayerError({itemId:_.itemId,canonicalItemId:_.canonicalItemId,contentKind:_.contentKind,error:_.error,timestamp:Date.now()})}},{name:E5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.itemId)return;if(_.action!=="check"&&_.action!=="retry")return;X.handleFormativeAction({itemId:_.itemId,canonicalItemId:_.canonicalItemId,action:_.action,outcomes:_.outcomes})}},{name:C5,handler:(L)=>{if(!V(L))return;let _=P9(L);if(!_?.renderableId)return;if(_.action!=="attach"&&_.action!=="detach")return;X.handleMediaTimeSource({renderableId:_.renderableId,action:_.action,source:_.source,origin:_.origin})}}]);return()=>{N();for(let L of[...L0.keys()])V1(L)}}),T(()=>{if(!A(f))return;return()=>{p9?.disconnect(),p9=null,u9?.disconnect(),u9=null}}),T(()=>{let W=A(f),V=A(X6);if(!W||!V)return;I(()=>{if(p9){p9.setValue(V);return}p9=new j5(W,{context:a0,initialValue:V}),p9.connect()})}),T(()=>{let W=A(f),V=A(Y6);if(!W||!V)return;I(()=>{if(u9){u9.setValue(V);return}u9=new j5(W,{context:M5,initialValue:V}),u9.connect()})});async function V6(){if(!A(E))throw Error("Coordinator not initialized");await A(E).waitUntilReady()}function q6(W){if(!A(E))throw Error("Coordinator not initialized");A(E).setHooks(W)}function $6(W){return X.navigateToItem(W)}function A6(){return X.getCompositionModel()}function D6(){return A(g9)}async function F6(){await X.persist()}async function z6(){await X.hydrate()}T(()=>{let W=A(E);if(!W)return;let V=A(F0)>0||A(t0)!==null,H=!A(j1)&&A(X0);if(!V&&!H)return;I(()=>{if(W===R8)return;R8=W,W.waitUntilReady().catch(()=>{})})}),T(()=>{return()=>{_0.cancel(),X.dispose().catch((W)=>{w9({kind:"runtime-dispose",source:"pie-assessment-toolkit",error:W,recoverable:!0})}).then(()=>O0()).catch(N0).finally(()=>{G.dispose()})}});var H6={waitUntilReady:V6,setHooks:q6,navigateToItem:$6,getCompositionModel:A6,getItemPlayerConfig:D6,persist:F6,hydrate:z6,get assessmentId(){return U()},set assessmentId(W){U(W),x()},get section(){return q()},set section(W){q(W),x()},get sectionId(){return K()},set sectionId(W){K(W),x()},get attemptId(){return $()},set attemptId(W){$(W),x()},get env(){return D()},set env(W){D(W),x()},get ndsIcons(){return z()},set ndsIcons(W){z(W),x()},get locale(){return M()},set locale(W){M(W),x()},get contentLanguage(){return O()},set contentLanguage(W){O(W),x()},get lazyInit(){return F()},set lazyInit(W){F(W),x()},get toolConfigStrictness(){return w()},set toolConfigStrictness(W){w(W),x()},get tools(){return R()},set tools(W){R(W),x()},get toolContextResolvers(){return b()},set toolContextResolvers(W){b(W),x()},get enabledTools(){return S()},set enabledTools(W){S(W),x()},get toolRegistry(){return h()},set toolRegistry(W){h(W),x()},get accessibility(){return C()},set accessibility(W){C(W),x()},get player(){return U9()},set player(W){U9(W),x()},get playerType(){return K9()},set playerType(W){K9(W),x()},get coordinator(){return u()},set coordinator(W){u(W),x()},get createSectionController(){return Q9()},set createSectionController(W){Q9(W),x()},get onFrameworkError(){return H9()},set onFrameworkError(W){H9(W),x()},get errorRenderer(){return _9()},set errorRenderer(W){_9(W),x()},get assessment(){return M9()},set assessment(W){M9(W),x()},get isolation(){return V9()},set isolation(W){V9(W),x()},get session(){return L9()},set session(W){L9(W),x()}},l8=P2(),i8=z8(l8);H5(i8,(W)=>v(Z0,W),()=>A(Z0));var _6=n0(i8,2);{var M6=(W)=>{var V=w2(),H=q5(V),N=s0(H,!0),L=n0(H,2),_=s0(L,!0),g=n0(L,2),R0=s0(g,!0);W5(V),$5(($1)=>{o0(N,A(e0)),o0(_,A(Y9).message),o0(R0,$1)},[()=>A(Z1).join(`
|
|
225
|
+
`)]),r0(W,V)},L6=(W)=>{var V=A5(),H=z8(V);F5(H,Q,"default",{},null),r0(W,V)};D5(_6,(W)=>{if(A(Y9)&&!A(Y9).recoverable)W(M6);else W(L6,-1)})}return r0(Z,l8),K5(H6)}q2("pie-assessment-toolkit",_5(b5,{assessmentId:{attribute:"assessment-id",type:"String"},section:{attribute:"section",type:"Object"},sectionId:{attribute:"section-id",type:"String"},attemptId:{attribute:"attempt-id",type:"String"},env:{attribute:"env",type:"Object"},ndsIcons:{attribute:"nds-icons",type:"Boolean"},locale:{attribute:"locale",type:"String"},contentLanguage:{attribute:"content-language",type:"String"},lazyInit:{attribute:"lazy-init",type:"Boolean"},toolConfigStrictness:{attribute:"tool-config-strictness",type:"String"},tools:{attribute:"tools",type:"Object"},toolContextResolvers:{type:"Object"},enabledTools:{attribute:"enabled-tools",type:"String"},toolRegistry:{type:"Object"},accessibility:{type:"Object"},player:{attribute:"player",type:"Object"},playerType:{attribute:"player-type",type:"String"},coordinator:{type:"Object"},createSectionController:{type:"Object"},onFrameworkError:{type:"Object"},errorRenderer:{type:"Object"},assessment:{type:"Object"},isolation:{attribute:"isolation",type:"String"},session:{type:"Object"}},["default"],["waitUntilReady","setHooks","navigateToItem","getCompositionModel","getItemPlayerConfig","persist","hydrate"],{mode:"open"},$2));export{b5 as default};
|